/* MSPDebug - debugging tool for MSP430 MCUs * Copyright (C) 2009-2012 Daniel Beer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef POWERBUF_H_ #define POWERBUF_H_ /* This header file describes a data structure for recording power * profiling data. * * Power profile data consists of zero or more discontiguous "sessions". * Within each session is a sequence of evenly spaced current samples * and the corresponding MAB values. */ #include #include "util.h" /* Per-session information header. */ struct powerbuf_session { /* Time that this session started. */ time_t wall_clock; /* Index of first sample in sample buffer corresponding to this * session. */ unsigned int start_index; /* Integral of current consumed over this session. */ unsigned long long total_ua; }; #define POWERBUF_MAX_SESSIONS 8 #define POWERBUF_DEFAULT_SAMPLES 131072 /* Power buffer data structure. The power buffer contains three circular * buffers, two of which are dynamically allocated. Helper functions are * provided for managing access. */ struct powerbuf { /* These parameters are set at the time of construction and * shouldn't be modified. */ unsigned int interval_us; unsigned int max_samples; /* Session circular buffer. New sessions are created by * overwriting the head and advancing it. Old sessions drop out * the end of the buffer. */ struct powerbuf_session sessions[POWERBUF_MAX_SESSIONS]; unsigned int session_head; unsigned int session_tail; /* Sample circular buffer. A single head/tail pair indicates the * extent of both the current and MAB samples, since they are * synchronous with respect to one another. * * Adding samples to the buffer causes old samples to fall out * the tail end. If enough samples are pushed, old sessions will * also drop out above. */ unsigned int *current_ua; address_t *mab; unsigned int current_head; unsigned int current_tail; /* Index by MAB. This is a flat array which points to indices * within current_ua/mab. The indices are sorted in order of * increasing MAB. * * Note that this array is invalidated by any modification to * the sample buffers. You need to call powerbuf_sort() before * accessing it. */ int sort_valid; unsigned int *sorted; }; typedef struct powerbuf *powerbuf_t; /* Allocate/destroy a power buffer. The number of samples is fixed and * can't change over the lifetime of the buffer. */ powerbuf_t powerbuf_new(unsigned int max_samples, unsigned int interval_us); void powerbuf_free(powerbuf_t pb); /* Clear all sessions and samples from the buffer. */ void powerbuf_clear(powerbuf_t pb); /* Begin a new session. This may cause an old session to drop out the * end of the buffer. If the current session is empty, it will be * overwritten. * * powerbuf_end_session() simply discards any empty session previously * created by powerbuf_begin_session(). */ void powerbuf_begin_session(powerbuf_t pb, time_t when); void powerbuf_end_session(powerbuf_t pb); /* This interface provides a convenient way of accessing the session * circular buffer. Rather than using direct indices, we present an * interface that mimics a flat array. Indices (rev_idx) start at 0, * with 0 being the index of the most recent session. */ unsigned int powerbuf_num_sessions(powerbuf_t pb); const struct powerbuf_session *powerbuf_session_info(powerbuf_t pb, unsigned int rev_idx, unsigned int *length); /* Push samples into the buffer. The number of elements in both the * current_ua and mab arrays is given by the parameter "count". */ void powerbuf_add_samples(powerbuf_t pb, unsigned int count, const unsigned int *current_ua, const address_t *mab); /* Retrieve the last known MAB for this session, or 0 if none exists. */ address_t powerbuf_last_mab(powerbuf_t pb); /* Prepare the sorted MAB index. */ void powerbuf_sort(powerbuf_t pb); /* Obtain charge consumption data by MAB over all sessions. This * automatically calls powerbuf_sort() if necessary. * * Returns the number of samples found on success. The sum of all * current samples is written to the sum_ua argument. */ int powerbuf_get_by_mab(powerbuf_t pb, address_t mab, unsigned long long *sum_ua); #endif