41 #include "contiki-lib.h"
49 struct powertrace_sniff_stats {
50 struct powertrace_sniff_stats *next;
51 uint32_t num_input, num_output;
52 uint32_t input_txtime, input_rxtime;
53 uint32_t output_txtime, output_rxtime;
58 uint32_t last_input_txtime, last_input_rxtime;
59 uint32_t last_output_txtime, last_output_rxtime;
65 #define MAX_NUM_STATS 16
67 MEMB(stats_memb,
struct powertrace_sniff_stats, MAX_NUM_STATS);
70 PROCESS(powertrace_process,
"Periodic power output");
73 powertrace_print(
char *str)
75 static uint32_t last_cpu, last_lpm, last_transmit, last_listen;
76 static uint32_t last_idle_transmit, last_idle_listen;
78 uint32_t cpu, lpm, transmit, listen;
79 uint32_t all_cpu, all_lpm, all_transmit, all_listen;
80 uint32_t idle_transmit, idle_listen;
81 uint32_t all_idle_transmit, all_idle_listen;
83 static uint32_t seqno;
85 uint32_t time, all_time, radio, all_radio;
87 struct powertrace_sniff_stats *s;
91 all_cpu = energest_type_time(ENERGEST_TYPE_CPU);
92 all_lpm = energest_type_time(ENERGEST_TYPE_LPM);
93 all_transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT);
94 all_listen = energest_type_time(ENERGEST_TYPE_LISTEN);
98 cpu = all_cpu - last_cpu;
99 lpm = all_lpm - last_lpm;
100 transmit = all_transmit - last_transmit;
101 listen = all_listen - last_listen;
105 last_cpu = energest_type_time(ENERGEST_TYPE_CPU);
106 last_lpm = energest_type_time(ENERGEST_TYPE_LPM);
107 last_transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT);
108 last_listen = energest_type_time(ENERGEST_TYPE_LISTEN);
112 radio = transmit + listen;
114 all_time = all_cpu + all_lpm;
115 all_radio = energest_type_time(ENERGEST_TYPE_LISTEN) +
116 energest_type_time(ENERGEST_TYPE_TRANSMIT);
118 printf(
"%s %lu P %d.%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu (radio %d.%02d%% / %d.%02d%% tx %d.%02d%% / %d.%02d%% listen %d.%02d%% / %d.%02d%%)\n",
121 all_cpu, all_lpm, all_transmit, all_listen, all_idle_transmit, all_idle_listen,
122 cpu, lpm, transmit, listen, idle_transmit, idle_listen,
123 (
int)((100L * (all_transmit + all_listen)) / all_time),
124 (
int)((10000L * (all_transmit + all_listen) / all_time) - (100L * (all_transmit + all_listen) / all_time) * 100),
125 (
int)((100L * (transmit + listen)) / time),
126 (
int)((10000L * (transmit + listen) / time) - (100L * (transmit + listen) / time) * 100),
127 (
int)((100L * all_transmit) / all_time),
128 (
int)((10000L * all_transmit) / all_time - (100L * all_transmit / all_time) * 100),
129 (
int)((100L * transmit) / time),
130 (
int)((10000L * transmit) / time - (100L * transmit / time) * 100),
131 (
int)((100L * all_listen) / all_time),
132 (
int)((10000L * all_listen) / all_time - (100L * all_listen / all_time) * 100),
133 (
int)((100L * listen) / time),
134 (
int)((10000L * listen) / time - (100L * listen / time) * 100));
139 printf(
"%s %lu SP %d.%d %lu %u %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu (channel %d radio %d.%02d%% / %d.%02d%%)\n",
142 s->num_input, s->input_txtime, s->input_rxtime,
143 s->input_txtime - s->last_input_txtime,
144 s->input_rxtime - s->last_input_rxtime,
145 s->num_output, s->output_txtime, s->output_rxtime,
146 s->output_txtime - s->last_output_txtime,
147 s->output_rxtime - s->last_output_rxtime,
149 (
int)((100L * (s->input_rxtime + s->input_txtime + s->output_rxtime + s->output_txtime)) / all_radio),
150 (
int)((10000L * (s->input_rxtime + s->input_txtime + s->output_rxtime + s->output_txtime)) / all_radio),
151 (
int)((100L * (s->input_rxtime + s->input_txtime +
152 s->output_rxtime + s->output_txtime -
153 (s->last_input_rxtime + s->last_input_txtime +
154 s->last_output_rxtime + s->last_output_txtime))) /
156 (
int)((10000L * (s->input_rxtime + s->input_txtime +
157 s->output_rxtime + s->output_txtime -
158 (s->last_input_rxtime + s->last_input_txtime +
159 s->last_output_rxtime + s->last_output_txtime))) /
162 printf(
"%s %lu SP %d.%d %lu %u %u %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu (proto %u(%u) radio %d.%02d%% / %d.%02d%%)\n",
164 s->proto, s->channel,
165 s->num_input, s->input_txtime, s->input_rxtime,
166 s->input_txtime - s->last_input_txtime,
167 s->input_rxtime - s->last_input_rxtime,
168 s->num_output, s->output_txtime, s->output_rxtime,
169 s->output_txtime - s->last_output_txtime,
170 s->output_rxtime - s->last_output_rxtime,
171 s->proto, s->channel,
172 (
int)((100L * (s->input_rxtime + s->input_txtime + s->output_rxtime + s->output_txtime)) / all_radio),
173 (
int)((10000L * (s->input_rxtime + s->input_txtime + s->output_rxtime + s->output_txtime)) / all_radio),
174 (
int)((100L * (s->input_rxtime + s->input_txtime +
175 s->output_rxtime + s->output_txtime -
176 (s->last_input_rxtime + s->last_input_txtime +
177 s->last_output_rxtime + s->last_output_txtime))) /
179 (
int)((10000L * (s->input_rxtime + s->input_txtime +
180 s->output_rxtime + s->output_txtime -
181 (s->last_input_rxtime + s->last_input_txtime +
182 s->last_output_rxtime + s->last_output_txtime))) /
185 s->last_input_txtime = s->input_txtime;
186 s->last_input_rxtime = s->input_rxtime;
187 s->last_output_txtime = s->output_txtime;
188 s->last_output_rxtime = s->output_rxtime;
196 static struct etimer periodic;
197 clock_time_t *period;
210 powertrace_print(
"");
217 powertrace_start(clock_time_t period)
223 powertrace_stop(
void)
229 add_stats(
struct powertrace_sniff_stats *s,
int input_or_output)
231 if(input_or_output == INPUT) {
233 s->input_txtime += packetbuf_attr(PACKETBUF_ATTR_TRANSMIT_TIME);
234 s->input_rxtime += packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME);
235 }
else if(input_or_output == OUTPUT) {
237 s->output_txtime += packetbuf_attr(PACKETBUF_ATTR_TRANSMIT_TIME);
238 s->output_rxtime += packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME);
243 add_packet_stats(
int input_or_output)
245 struct powertrace_sniff_stats *s;
251 if(s->channel == packetbuf_attr(PACKETBUF_ATTR_CHANNEL)
253 && s->proto == packetbuf_attr(PACKETBUF_ATTR_NETWORK_ID)
256 add_stats(s, input_or_output);
263 memset(s, 0,
sizeof(
struct powertrace_sniff_stats));
264 s->channel = packetbuf_attr(PACKETBUF_ATTR_CHANNEL);
266 s->proto = packetbuf_attr(PACKETBUF_ATTR_NETWORK_ID);
269 add_stats(s, input_or_output);
277 add_packet_stats(INPUT);
281 output_sniffer(
int mac_status)
283 add_packet_stats(OUTPUT);
288 sniffprint(
char *prefix,
int seqno)
290 const linkaddr_t *sender, *receiver, *esender, *ereceiver;
292 sender = packetbuf_addr(PACKETBUF_ADDR_SENDER);
293 receiver = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
294 esender = packetbuf_addr(PACKETBUF_ADDR_ESENDER);
295 ereceiver = packetbuf_addr(PACKETBUF_ADDR_ERECEIVER);
298 printf(
"%lu %s %d %u %d %d %d.%d %u %u\n",
302 packetbuf_attr(PACKETBUF_ATTR_CHANNEL),
303 packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE),
304 esender->u8[0], esender->u8[1],
305 packetbuf_attr(PACKETBUF_ATTR_TRANSMIT_TIME),
306 packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME));
310 input_printsniffer(
void)
312 static int seqno = 0;
313 sniffprint(
"I", seqno++);
315 if(packetbuf_attr(PACKETBUF_ATTR_CHANNEL) == 0) {
321 printf(
"%02x ", dataptr[0]);
323 printf(
"%02x ", dataptr[i]);
330 output_printsniffer(
int mac_status)
332 static int seqno = 0;
333 sniffprint(
"O", seqno++);
336 RIME_SNIFFER(printsniff, input_printsniffer, output_printsniffer);
339 powertrace_printsniff(powertrace_onoff_t onoff)
343 rime_sniffer_add(&printsniff);
346 rime_sniffer_remove(&printsniff);
352 RIME_SNIFFER(powersniff, input_sniffer, output_sniffer);
355 powertrace_sniff(powertrace_onoff_t onoff)
359 rime_sniffer_add(&powersniff);
362 rime_sniffer_remove(&powersniff);
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
#define PROCESS_WAIT_UNTIL(c)
Wait for a condition to occur.
linkaddr_t linkaddr_node_addr
The Rime address of the node.
Header file for the powertrace application
#define PROCESS_EXIT()
Exit the currently running process.
#define PROCESS_BEGIN()
Define the beginning of a process.
void * list_item_next(void *item)
Get the next item following this item.
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
#define NULL
The null pointer.
struct compower_activity compower_idle_activity
The default idle communication activity.
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
Header file for the Rime stack
Header file for the communication power accounting module
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_END()
Define the end of a process.
CCIF clock_time_t clock_time(void)
Get the current clock time.
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
void * list_head(list_t list)
Get a pointer to the first element of a list.
#define MEMB(name, structure, num)
Declare a memory block.
void list_add(list_t list, void *item)
Add an item at the end of a list.
#define PROCESS(name, strname)
Declare a process.
#define LIST(name)
Declare a linked list.
void etimer_reset(struct etimer *et)
Reset an event timer with the same interval as was previously set.
void process_start(struct process *p, process_data_t data)
Start a process.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
void process_exit(struct process *p)
Cause a process to exit.