Add power sample output.

This commit is contained in:
Daniel Beer 2012-10-24 09:37:46 +13:00
parent 43735da212
commit 277a795f01
4 changed files with 89 additions and 5 deletions

View File

@ -45,6 +45,15 @@ character. These sigil characters are:
! Error messages
\ Shell messages
Another feature of output processing in embedded mode is that when
colourized output is enabled (``opt color true``), colourization is
always implemented by including ANSI escape codes in the output, even on
Windows. Normally, colourized output on Windows is implemented by
changing console text attributes.
Shell messages
--------------
Shell messages are emitted only when in embedded mode. They provide
additional information to the front-end and consist of a type identifier
string immediately following the sigil, then optionally a space and
@ -58,11 +67,18 @@ arguments. Currently, the following shell messages may be emitted:
~ The command process has accepted a command and is now executing it.
Another feature of output processing in embedded mode is that when
colourized output is enabled (``opt color true``), colourization is
always implemented by including ANSI escape codes in the output, even on
Windows. Normally, colourized output on Windows is implemented by
changing console text attributes.
\power-sample-us <period>
~ Indicates that power profiling is enabled. The period argument is a
decimal number giving the sample period in microseconds.
\power-samples <data>
~ Power data captured from the running device. The data argument is a
Base64-encoded string. When decoded, it consists of a sequence of
32-bit little-endian unsigned integers. Integers with bit 31 set are
MAB values, and those without bit 31 set are current consumption
readings, in microamps.
Input processing and interruption
=================================

View File

@ -404,6 +404,7 @@ static void power_init(struct fet_device *dev)
printc("Power profiling enabled: bufsize = %d bytes, %d us/sample\n",
dev->proto.argv[1], dev->proto.argv[0]);
printc_shell("power-sample-us %d\n", dev->proto.argv[0]);
dev->base.power_buf = powerbuf_new(POWERBUF_DEFAULT_SAMPLES,
dev->proto.argv[0]);
@ -447,6 +448,23 @@ static int power_end(struct fet_device *dev)
return 0;
}
static void shell_power(const uint8_t *data, int len)
{
while (len > 0) {
int plen = 128;
char text[256];
if (plen > len)
plen = len;
base64_encode(data, plen, text, sizeof(text));
printc_shell("power-samples %s\n", text);
len -= plen;
data += plen;
}
}
static int power_poll(struct fet_device *dev)
{
address_t mab;
@ -467,6 +485,8 @@ static int power_poll(struct fet_device *dev)
return -1;
}
shell_power(dev->proto.data, dev->proto.datalen);
mab = powerbuf_last_mab(dev->base.power_buf);
for (i = 0; i + 3 < dev->proto.datalen; i += 4) {
uint32_t s = LE_LONG(dev->proto.data, i);

View File

@ -296,3 +296,41 @@ int delay_ms(unsigned int s)
return nanosleep(&ts, NULL);
}
#endif
int base64_encode(const uint8_t *src, int len, char *dst, int max_len)
{
static const char basis[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz0123456789+/";
int i = 0;
int k = 0;
while ((i < len) && (k + 4) < max_len) {
int a = src[i++];
dst[k++] = basis[a >> 2];
if (i < len) {
int b = src[i++];
dst[k++] = basis[((a & 3) << 4) | (b & 0xf0) >> 4];
if (i < len) {
int c = src[i++];
dst[k++] = basis[((b & 0xf) << 2) |
((c & 0xc0) >> 6)];
dst[k++] = basis[c & 0x3f];
} else {
dst[k++] = basis[(b & 0xf) << 2];
dst[k++] = '=';
}
} else {
dst[k++] = basis[(a & 3) << 4];
dst[k++] = '=';
dst[k++] = '=';
}
}
dst[k] = 0;
return i;
}

View File

@ -61,6 +61,16 @@ char *expand_tilde(const char *path);
int delay_s(unsigned int s);
int delay_ms(unsigned int s);
/* Base64 encode a block without breaking into lines. Returns the number
* of source bytes encoded. The output is nul-terminated.
*/
static inline int base64_encoded_size(int decoded_size)
{
return ((decoded_size + 2) / 3) * 4;
}
int base64_encode(const uint8_t *src, int len, char *dst, int max_len);
/* printf format for long long args */
#ifdef __MINGW32__
#define LLFMT "I64d"