mspdebug/util/powerbuf.h

147 lines
4.8 KiB
C

/* 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 <time.h>
#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