* introduced energy profiling (yet in a very early state)

dev/timer
Oliver Hahm 13 years ago
parent cb1d4dd041
commit 4533726214

@ -45,19 +45,19 @@ and the mailinglist (subscription via web site)
#include "ltc4150_arch.h"
#include "gpioint.h"
void ltc4150_disable_int(void) {
void __attribute__((__no_instrument_function__)) ltc4150_disable_int(void) {
gpioint_set(0, BIT4, GPIOINT_DISABLE, NULL);
}
void ltc4150_enable_int(void) {
void __attribute__((__no_instrument_function__)) ltc4150_enable_int(void) {
gpioint_set(0, BIT4, GPIOINT_FALLING_EDGE, &ltc4150_interrupt);
}
void ltc4150_sync_blocking(void) {
void __attribute__((__no_instrument_function__)) ltc4150_sync_blocking(void) {
while(!(FIO0PIN & BIT4)) {};
}
void ltc4150_arch_init() {
void __attribute__((__no_instrument_function__)) ltc4150_arch_init() {
FIO0DIR |= BIT5;
FIO0SET = BIT5;
}

@ -30,6 +30,11 @@ SubDir TOP cpu arm_common ;
Module arm_common : common.s bootloader.c VIC.c atomic.s arm_cpu.c iap.c ;
UseModule arm_common ;
Module profiling : profiling.c ;
if $(PROFILING) {
UseModule profiling ;
}
Module hwtimer_cpu : hwtimer_cpu.c ;
Objects syscalls.c ;

@ -40,9 +40,14 @@ LINK = $(CC) ;
OPTIM = -Os ;
#OPTIM = -O0 -g ;
CCFLAGS += -std=gnu99 -Wall -mcpu=arm7tdmi-s -mfloat-abi=soft -mfpu=vfp ;
LINKFLAGS = -mcpu=arm7tdmi-s -static -lgcc -nostartfiles -T [ FPath $(TOP) cpu $(CPU) linkerscript.x ] ;
if $(PROFILING) = 1 {
CCFLAGS += -g -finstrument-functions ;
}
AS = $(TOOLCHAIN)as ;
ASFLAGS += -mcpu=arm7tdmi-s --defsym $(CPU)=1 -mfloat-abi=soft -mfpu=vfp ;

@ -0,0 +1,109 @@
#include <stdio.h>
#include <stdint.h>
#include <cpu.h>
#include <ltc4150.h>
#define MAX_TRACED_FUNCTIONS (32)
#define PROFILING_STACK_SIZE (16)
typedef struct {
uint32_t address;
uint32_t time;
uint32_t start_time;
double consumption;
double consumption_start;
uint16_t counter;
} profiling_info_t;
static profiling_info_t functions[MAX_TRACED_FUNCTIONS];
static uint8_t profiling_stack[PROFILING_STACK_SIZE];
static uint8_t profiling_sp = 0;
static uint8_t traced_functions = 0;
static uint8_t profiling = 0;
void __attribute__((__no_instrument_function__)) profiling_init(void) {
uint8_t i;
for (i = 0; i < MAX_TRACED_FUNCTIONS; i++) {
functions[i].address = 0;
functions[i].time = 0;
functions[i].consumption = 0;
functions[i].counter = 0;
}
for (i = 0; i < PROFILING_STACK_SIZE; i++) {
profiling_stack[i] = 0;
}
ltc4150_start();
profiling = 1;
}
static int16_t __attribute__((__no_instrument_function__)) get_function_index(uint32_t addr) {
uint8_t i;
for (i = 0; i < MAX_TRACED_FUNCTIONS; i++) {
if (functions[i].address == addr) {
return i;
}
}
return -1;
}
void __attribute__((__no_instrument_function__)) __cyg_profile_func_enter (void *func, void *caller) {
if (!profiling) {
return;
}
/*
uint8_t i;
int16_t idx = -1;
for (i = 0; i < MAX_TRACED_FUNCTIONS; i++) {
if (functions[i].address == (uint32_t) func) {
idx = i;
break;
}
}
*/
uint8_t idx = get_function_index((uint32_t) func);
if ((idx < 0) && (traced_functions < MAX_TRACED_FUNCTIONS)) {
idx = traced_functions++;
functions[idx].address = (uint32_t) func;
}
else if (idx < 0) {
return;
}
functions[idx].start_time = T0TC;
functions[idx].counter++;
functions[idx].consumption_start = ltc4150_get_total_mAh();
// functions[idx].consumption_start = ltc4150_get_intcount();
}
void __attribute__((__no_instrument_function__)) __cyg_profile_func_exit (void *func, void *caller) {
if (!profiling) {
return;
}
/*
uint8_t i;
int16_t idx = -1;
for (i = 0; i < MAX_TRACED_FUNCTIONS; i++) {
if (functions[i].address == (uint32_t) func) {
idx = i;
break;
}
}
*/
uint8_t idx = get_function_index((uint32_t) func);
if (idx >= 0) {
functions[idx].time += T0TC - functions[idx].start_time;
//functions[idx].consumption += ltc4150_get_intcount() - functions[idx].consumption_start;
functions[idx].consumption += ltc4150_get_total_mAh() - functions[idx].consumption_start;
}
}
void profiling_stats(void) {
uint8_t i;
for (i = 0; i < traced_functions; i++) {
// printf("Function @%04lX was running %u times for %lu ticks, consuming %li ltc-ticks\n", functions[i].address, functions[i].counter, functions[i].time, functions[i].consumption);
printf("Function @%04lX was running %u times for %lu ticks, consuming %lf mAh\n", functions[i].address, functions[i].counter, functions[i].time, functions[i].consumption);
}
puts("________________________________________________________");
}

@ -123,7 +123,7 @@ gpioint_set(int port, uint32_t bitmask, int flags, fp_irqcb callback)
return true; // success
}
/*---------------------------------------------------------------------------*/
static void test_irq(int port, unsigned long f_mask, unsigned long r_mask, struct irq_callback* pcb)
static void __attribute__ ((__no_instrument_function__)) test_irq(int port, unsigned long f_mask, unsigned long r_mask, struct irq_callback* pcb)
{
/* Test each bit of rising and falling masks, if set trigger interrupt
* on corresponding device */
@ -148,7 +148,7 @@ void GPIO_IRQHandler(void) __attribute__((interrupt("IRQ")));
* Invoked whenever an activated gpio interrupt is triggered by a rising
* or falling edge.
*/
void GPIO_IRQHandler(void) {
void __attribute__ ((__no_instrument_function__)) GPIO_IRQHandler(void) {
if( IO_INT_STAT & BIT0 ) { // interrupt(s) on PORT0 pending
unsigned long int_stat_f = IO0_INT_STAT_F; // save content
unsigned long int_stat_r = IO0_INT_STAT_R; // save content

@ -29,7 +29,7 @@ SubDir TOP drivers ;
Module sht11 : sht11.c : hwtimer ;
Module ltc4150 : ltc4150.c : board_ltc4150 ;
Module ltc4150 : ltc4150.c : board_ltc4150 hwtimer ;
SubInclude TOP drivers cc110x ;
SubInclude TOP drivers cc110x_ng ;

@ -11,5 +11,6 @@ double ltc4150_get_current_mA();
double ltc4150_get_total_mAh();
double ltc4150_get_avg_mA();
int ltc4150_get_interval();
long ltc4150_get_intcount(void);
#endif /* __LTC4150_H */

@ -46,11 +46,11 @@ static unsigned int last_int_time;
static unsigned int last_int_duration;
static unsigned int start_time;
static double int_to_coulomb(int ints) {
static double __attribute__((__no_instrument_function__)) int_to_coulomb(int ints) {
return ((double)ints) / (_GFH * _R_SENSE);
}
static double coulomb_to_mA(double coulomb){
static double __attribute__((__no_instrument_function__)) coulomb_to_mA(double coulomb){
return (coulomb * 1000) / 3600;
}
@ -62,7 +62,7 @@ double ltc4150_get_current_mA() {
return 1000000000/(ltc4150_get_last_int_duration_us()*(_GFH * _R_SENSE));
}
double ltc4150_get_total_mAh() {
double __attribute__((__no_instrument_function__)) ltc4150_get_total_mAh() {
return coulomb_to_mA(int_to_coulomb(int_count));
}
@ -74,7 +74,7 @@ int ltc4150_get_interval() {
return HWTIMER_TICKS_TO_US(last_int_time - start_time);
}
unsigned long ltc4150_get_intcount() {
unsigned long __attribute__((__no_instrument_function__)) ltc4150_get_intcount() {
return int_count;
}
@ -96,7 +96,7 @@ void ltc4150_stop() {
ltc4150_disable_int();
}
void ltc4150_interrupt()
void __attribute__((__no_instrument_function__)) ltc4150_interrupt()
{
uint32_t now = hwtimer_now();
if (now >= last_int_time) {

@ -52,6 +52,10 @@ void auto_init(void) {
#ifdef MODULE_LTC4150
DEBUG("Auto init ltc4150 module.\n");
ltc4150_init();
#endif
#ifdef MODULE_PROFILING
extern void profiling_init(void);
profiling_init();
#endif
main();
}

Loading…
Cancel
Save