1
0
mirror of https://github.com/ARM-software/devlib.git synced 2025-09-01 17:41:54 +01:00

devlib initial commit.

This commit is contained in:
Sergei Trofimov
2015-10-09 09:30:04 +01:00
commit 4e6afe960b
64 changed files with 8938 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.arm.devlib.netstats"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
<service android:name="com.arm.devlib.netstats.TrafficMetricsService" android:exported="true" android:enabled="true">
<intent-filter>
<action android:name="com.arm.devlib.netstats.TrafficMetricsService" />
</intent-filter>
</service>
</application>
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
</manifest>

8
src/netstats/build.sh Executable file
View File

@@ -0,0 +1,8 @@
set -e
THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
pushd $THIS_DIR
ant release
jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android $THIS_DIR/bin/netstats-*.apk androiddebugkey
cp $THIS_DIR/bin/netstats-*.apk $THIS_DIR/../../devlib/instrument/netstats/netstats.apk
ant clean
popd

92
src/netstats/build.xml Normal file
View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="netstats" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

View File

@@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@@ -0,0 +1,14 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=Google Inc.:Google APIs (x86 System Image):19

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, NetStats"
/>
</LinearLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">NetStats</string>
</resources>

View File

@@ -0,0 +1,124 @@
package com.arm.devlib.netstats;
import java.lang.InterruptedException;
import java.lang.System;
import java.lang.Thread;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import android.app.Activity;
import android.app.IntentService;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.TrafficStats;
import android.os.Bundle;
import android.util.Log;
class TrafficPoller implements Runnable {
private String tag;
private int period;
private PackageManager pm;
private static String TAG = "TrafficMetrics";
private List<String> packageNames;
private Map<String, Map<String, Long>> previousValues;
public TrafficPoller(String tag, PackageManager pm, int period, List<String> packages) {
this.tag = tag;
this.pm = pm;
this.period = period;
this.packageNames = packages;
this.previousValues = new HashMap<String, Map<String, Long>>();
}
public void run() {
try {
while (true) {
Thread.sleep(this.period);
getPakagesInfo();
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
}
}
public void getPakagesInfo() {
List<ApplicationInfo> apps;
if (this.packageNames == null) {
apps = pm.getInstalledApplications(0);
for (ApplicationInfo app : apps) {
}
} else {
apps = new ArrayList<ApplicationInfo>();
for (String packageName : packageNames) {
try {
ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
apps.add(info);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
}
for (ApplicationInfo appInfo : apps) {
int uid = appInfo.uid;
String name = appInfo.packageName;
long time = System.currentTimeMillis();
long received = TrafficStats.getUidRxBytes(uid);
long sent = TrafficStats.getUidTxBytes(uid);
if (!this.previousValues.containsKey(name)) {
this.previousValues.put(name, new HashMap<String, Long>());
this.previousValues.get(name).put("sent", sent);
this.previousValues.get(name).put("received", received);
Log.i(this.tag, String.format("INITIAL \"%s\" TX: %d RX: %d",
name, sent, received));
} else {
long previosSent = this.previousValues.get(name).put("sent", sent);
long previosReceived = this.previousValues.get(name).put("received", received);
Log.i(this.tag, String.format("%d \"%s\" TX: %d RX: %d",
time, name,
sent - previosSent,
received - previosReceived));
}
}
}
}
public class TrafficMetricsService extends IntentService {
private static String TAG = "TrafficMetrics";
private Thread thread;
private static int defaultPollingPeriod = 5000;
public TrafficMetricsService() {
super("TrafficMetrics");
}
@Override
public void onHandleIntent(Intent intent) {
List<String> packages = null;
String runTag = intent.getStringExtra("tag");
if (runTag == null) {
runTag = TAG;
}
String packagesString = intent.getStringExtra("packages");
int pollingPeriod = intent.getIntExtra("period", this.defaultPollingPeriod);
if (packagesString != null) {
packages = new ArrayList<String>(Arrays.asList(packagesString.split(",")));
}
if (this.thread != null) {
Log.e(runTag, "Attemping to start when monitoring is already in progress.");
return;
}
this.thread = new Thread(new TrafficPoller(runTag, getPackageManager(), pollingPeriod, packages));
this.thread.start();
}
}

11
src/readenergy/Makefile Normal file
View File

@@ -0,0 +1,11 @@
# To build:
#
# CROSS_COMPILE=aarch64-linux-gnu- make
#
CROSS_COMPILE?=aarch64-linux-gnu-
CC=$(CROSS_COMPILE)gcc
CFLAGS='-Wl,-static -Wl,-lc'
readenergy: readenergy.c
$(CC) $(CFLAGS) readenergy.c -o readenergy
mv readenergy ../../devlib/bin/arm64/readenergy

345
src/readenergy/readenergy.c Normal file
View File

@@ -0,0 +1,345 @@
/* Copyright 2014-2015 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* readenergy.c
*
* Reads APB energy registers in Juno and outputs the measurements (converted to appropriate units).
*
*/
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
// The following values obtained from Juno TRM 2014/03/04 section 4.5
// Location of APB registers in memory
#define APB_BASE_MEMORY 0x1C010000
// APB energy counters start at offset 0xD0 from the base APB address.
#define BASE_INDEX 0xD0 / 4
// the one-past last APB counter
#define APB_SIZE 0x120
// Masks specifying the bits that contain the actual counter values
#define CMASK 0xFFF
#define VMASK 0xFFF
#define PMASK 0xFFFFFF
// Sclaing factor (divisor) or getting measured values from counters
#define SYS_ADC_CH0_PM1_SYS_SCALE 761
#define SYS_ADC_CH1_PM2_A57_SCALE 381
#define SYS_ADC_CH2_PM3_A53_SCALE 761
#define SYS_ADC_CH3_PM4_GPU_SCALE 381
#define SYS_ADC_CH4_VSYS_SCALE 1622
#define SYS_ADC_CH5_VA57_SCALE 1622
#define SYS_ADC_CH6_VA53_SCALE 1622
#define SYS_ADC_CH7_VGPU_SCALE 1622
#define SYS_POW_CH04_SYS_SCALE (SYS_ADC_CH0_PM1_SYS_SCALE * SYS_ADC_CH4_VSYS_SCALE)
#define SYS_POW_CH15_A57_SCALE (SYS_ADC_CH1_PM2_A57_SCALE * SYS_ADC_CH5_VA57_SCALE)
#define SYS_POW_CH26_A53_SCALE (SYS_ADC_CH2_PM3_A53_SCALE * SYS_ADC_CH6_VA53_SCALE)
#define SYS_POW_CH37_GPU_SCALE (SYS_ADC_CH3_PM4_GPU_SCALE * SYS_ADC_CH7_VGPU_SCALE)
#define SYS_ENM_CH0_SYS_SCALE 12348030000
#define SYS_ENM_CH1_A57_SCALE 6174020000
#define SYS_ENM_CH0_A53_SCALE 12348030000
#define SYS_ENM_CH0_GPU_SCALE 6174020000
// Original values prior to re-callibrations.
/*#define SYS_ADC_CH0_PM1_SYS_SCALE 819.2*/
/*#define SYS_ADC_CH1_PM2_A57_SCALE 409.6*/
/*#define SYS_ADC_CH2_PM3_A53_SCALE 819.2*/
/*#define SYS_ADC_CH3_PM4_GPU_SCALE 409.6*/
/*#define SYS_ADC_CH4_VSYS_SCALE 1638.4*/
/*#define SYS_ADC_CH5_VA57_SCALE 1638.4*/
/*#define SYS_ADC_CH6_VA53_SCALE 1638.4*/
/*#define SYS_ADC_CH7_VGPU_SCALE 1638.4*/
/*#define SYS_POW_CH04_SYS_SCALE (SYS_ADC_CH0_PM1_SYS_SCALE * SYS_ADC_CH4_VSYS_SCALE)*/
/*#define SYS_POW_CH15_A57_SCALE (SYS_ADC_CH1_PM2_A57_SCALE * SYS_ADC_CH5_VA57_SCALE)*/
/*#define SYS_POW_CH26_A53_SCALE (SYS_ADC_CH2_PM3_A53_SCALE * SYS_ADC_CH6_VA53_SCALE)*/
/*#define SYS_POW_CH37_GPU_SCALE (SYS_ADC_CH3_PM4_GPU_SCALE * SYS_ADC_CH7_VGPU_SCALE)*/
/*#define SYS_ENM_CH0_SYS_SCALE 13421772800.0*/
/*#define SYS_ENM_CH1_A57_SCALE 6710886400.0*/
/*#define SYS_ENM_CH0_A53_SCALE 13421772800.0*/
/*#define SYS_ENM_CH0_GPU_SCALE 6710886400.0*/
// Ignore individual errors but if see too many, abort.
#define ERROR_THRESHOLD 10
// Default counter poll period (in milliseconds).
#define DEFAULT_PERIOD 100
// A single reading from the energy meter. The values are the proper readings converted
// to appropriate units (e.g. Watts for power); they are *not* raw counter values.
struct reading
{
double sys_adc_ch0_pm1_sys;
double sys_adc_ch1_pm2_a57;
double sys_adc_ch2_pm3_a53;
double sys_adc_ch3_pm4_gpu;
double sys_adc_ch4_vsys;
double sys_adc_ch5_va57;
double sys_adc_ch6_va53;
double sys_adc_ch7_vgpu;
double sys_pow_ch04_sys;
double sys_pow_ch15_a57;
double sys_pow_ch26_a53;
double sys_pow_ch37_gpu;
double sys_enm_ch0_sys;
double sys_enm_ch1_a57;
double sys_enm_ch0_a53;
double sys_enm_ch0_gpu;
};
inline uint64_t join_64bit_register(uint32_t *buffer, int index)
{
uint64_t result = 0;
result |= buffer[index];
result |= (uint64_t)(buffer[index+1]) << 32;
return result;
}
int nsleep(const struct timespec *req, struct timespec *rem)
{
struct timespec temp_rem;
if (nanosleep(req, rem) == -1)
{
if (errno == EINTR)
{
nsleep(rem, &temp_rem);
}
else
{
return errno;
}
}
else
{
return 0;
}
}
void print_help()
{
fprintf(stderr, "Usage: readenergy [-t PERIOD] -o OUTFILE\n\n"
"Read Juno energy counters every PERIOD milliseconds, writing them\n"
"to OUTFILE in CSV format until SIGTERM is received.\n\n"
"Parameters:\n"
" PERIOD is the counter poll period in milliseconds.\n"
" (Defaults to 100 milliseconds.)\n"
" OUTFILE is the output file path\n");
}
// debugging only...
inline void dprint(char *msg)
{
fprintf(stderr, "%s\n", msg);
sync();
}
// -------------------------------------- config ----------------------------------------------------
struct config
{
struct timespec period;
char *output_file;
};
void config_init_period_from_millis(struct config *this, long millis)
{
this->period.tv_sec = (time_t)(millis / 1000);
this->period.tv_nsec = (millis % 1000) * 1000000;
}
void config_init(struct config *this, int argc, char *argv[])
{
this->output_file = NULL;
config_init_period_from_millis(this, DEFAULT_PERIOD);
int opt;
while ((opt = getopt(argc, argv, "ht:o:")) != -1)
{
switch(opt)
{
case 't':
config_init_period_from_millis(this, atol(optarg));
break;
case 'o':
this->output_file = optarg;
break;
case 'h':
print_help();
exit(EXIT_SUCCESS);
break;
default:
fprintf(stderr, "ERROR: Unexpected option %s\n\n", opt);
print_help();
exit(EXIT_FAILURE);
}
}
if (this->output_file == NULL)
{
fprintf(stderr, "ERROR: Mandatory -o option not specified.\n\n");
print_help();
exit(EXIT_FAILURE);
}
}
// -------------------------------------- /config ---------------------------------------------------
// -------------------------------------- emeter ----------------------------------------------------
struct emeter
{
int fd;
FILE *out;
void *mmap_base;
};
void emeter_init(struct emeter *this, char *outfile)
{
this->out = fopen(outfile, "w");
if (this->out == NULL)
{
fprintf(stderr, "ERROR: Could not open output file %s; got %s\n", outfile, strerror(errno));
exit(EXIT_FAILURE);
}
this->fd = open("/dev/mem", O_RDONLY);
if(this->fd < 0)
{
fprintf(stderr, "ERROR: Can't open /dev/mem; got %s\n", strerror(errno));
fclose(this->out);
exit(EXIT_FAILURE);
}
this->mmap_base = mmap(NULL, APB_SIZE, PROT_READ, MAP_SHARED, this->fd, APB_BASE_MEMORY);
if (this->mmap_base == MAP_FAILED)
{
fprintf(stderr, "ERROR: mmap failed; got %s\n", strerror(errno));
close(this->fd);
fclose(this->out);
exit(EXIT_FAILURE);
}
fprintf(this->out, "sys_curr,a57_curr,a53_curr,gpu_curr,"
"sys_volt,a57_volt,a53_volt,gpu_volt,"
"sys_pow,a57_pow,a53_pow,gpu_pow,"
"sys_cenr,a57_cenr,a53_cenr,gpu_cenr\n");
}
void emeter_read_measurements(struct emeter *this, struct reading *reading)
{
uint32_t *buffer = (uint32_t *)this->mmap_base;
reading->sys_adc_ch0_pm1_sys = (double)(CMASK & buffer[BASE_INDEX+0]) / SYS_ADC_CH0_PM1_SYS_SCALE;
reading->sys_adc_ch1_pm2_a57 = (double)(CMASK & buffer[BASE_INDEX+1]) / SYS_ADC_CH1_PM2_A57_SCALE;
reading->sys_adc_ch2_pm3_a53 = (double)(CMASK & buffer[BASE_INDEX+2]) / SYS_ADC_CH2_PM3_A53_SCALE;
reading->sys_adc_ch3_pm4_gpu = (double)(CMASK & buffer[BASE_INDEX+3]) / SYS_ADC_CH3_PM4_GPU_SCALE;
reading->sys_adc_ch4_vsys = (double)(VMASK & buffer[BASE_INDEX+4]) / SYS_ADC_CH4_VSYS_SCALE;
reading->sys_adc_ch5_va57 = (double)(VMASK & buffer[BASE_INDEX+5]) / SYS_ADC_CH5_VA57_SCALE;
reading->sys_adc_ch6_va53 = (double)(VMASK & buffer[BASE_INDEX+6]) / SYS_ADC_CH6_VA53_SCALE;
reading->sys_adc_ch7_vgpu = (double)(VMASK & buffer[BASE_INDEX+7]) / SYS_ADC_CH7_VGPU_SCALE;
reading->sys_pow_ch04_sys = (double)(PMASK & buffer[BASE_INDEX+8]) / SYS_POW_CH04_SYS_SCALE;
reading->sys_pow_ch15_a57 = (double)(PMASK & buffer[BASE_INDEX+9]) / SYS_POW_CH15_A57_SCALE;
reading->sys_pow_ch26_a53 = (double)(PMASK & buffer[BASE_INDEX+10]) / SYS_POW_CH26_A53_SCALE;
reading->sys_pow_ch37_gpu = (double)(PMASK & buffer[BASE_INDEX+11]) / SYS_POW_CH37_GPU_SCALE;
reading->sys_enm_ch0_sys = (double)join_64bit_register(buffer, BASE_INDEX+12) / SYS_ENM_CH0_SYS_SCALE;
reading->sys_enm_ch1_a57 = (double)join_64bit_register(buffer, BASE_INDEX+14) / SYS_ENM_CH1_A57_SCALE;
reading->sys_enm_ch0_a53 = (double)join_64bit_register(buffer, BASE_INDEX+16) / SYS_ENM_CH0_A53_SCALE;
reading->sys_enm_ch0_gpu = (double)join_64bit_register(buffer, BASE_INDEX+18) / SYS_ENM_CH0_GPU_SCALE;
}
void emeter_take_reading(struct emeter *this)
{
static struct reading reading;
int error_count = 0;
emeter_read_measurements(this, &reading);
int ret = fprintf(this->out, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",
reading.sys_adc_ch0_pm1_sys,
reading.sys_adc_ch1_pm2_a57,
reading.sys_adc_ch2_pm3_a53,
reading.sys_adc_ch3_pm4_gpu,
reading.sys_adc_ch4_vsys,
reading.sys_adc_ch5_va57,
reading.sys_adc_ch6_va53,
reading.sys_adc_ch7_vgpu,
reading.sys_pow_ch04_sys,
reading.sys_pow_ch15_a57,
reading.sys_pow_ch26_a53,
reading.sys_pow_ch37_gpu,
reading.sys_enm_ch0_sys,
reading.sys_enm_ch1_a57,
reading.sys_enm_ch0_a53,
reading.sys_enm_ch0_gpu);
if (ret < 0)
{
fprintf(stderr, "ERROR: while writing a meter reading: %s\n", strerror(errno));
if (++error_count > ERROR_THRESHOLD)
exit(EXIT_FAILURE);
}
}
void emeter_finalize(struct emeter *this)
{
if (munmap(this->mmap_base, APB_SIZE) == -1)
{
// Report the error but don't bother doing anything else, as we're not gonna do
// anything with emeter after this point anyway.
fprintf(stderr, "ERROR: munmap failed; got %s\n", strerror(errno));
}
close(this->fd);
fclose(this->out);
}
// -------------------------------------- /emeter ----------------------------------------------------
int done = 0;
void term_handler(int signum)
{
done = 1;
}
int main(int argc, char *argv[])
{
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = term_handler;
sigaction(SIGTERM, &action, NULL);
struct config config;
struct emeter emeter;
config_init(&config, argc, argv);
emeter_init(&emeter, config.output_file);
struct timespec remaining;
while (!done)
{
emeter_take_reading(&emeter);
nsleep(&config.period, &remaining);
}
emeter_finalize(&emeter);
return EXIT_SUCCESS;
}