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 ! Error messages
\ Shell 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 Shell messages are emitted only when in embedded mode. They provide
additional information to the front-end and consist of a type identifier additional information to the front-end and consist of a type identifier
string immediately following the sigil, then optionally a space and 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. ~ The command process has accepted a command and is now executing it.
Another feature of output processing in embedded mode is that when \power-sample-us <period>
colourized output is enabled (``opt color true``), colourization is
always implemented by including ANSI escape codes in the output, even on ~ Indicates that power profiling is enabled. The period argument is a
Windows. Normally, colourized output on Windows is implemented by decimal number giving the sample period in microseconds.
changing console text attributes.
\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 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", printc("Power profiling enabled: bufsize = %d bytes, %d us/sample\n",
dev->proto.argv[1], dev->proto.argv[0]); 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->base.power_buf = powerbuf_new(POWERBUF_DEFAULT_SAMPLES,
dev->proto.argv[0]); dev->proto.argv[0]);
@ -447,6 +448,23 @@ static int power_end(struct fet_device *dev)
return 0; 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) static int power_poll(struct fet_device *dev)
{ {
address_t mab; address_t mab;
@ -467,6 +485,8 @@ static int power_poll(struct fet_device *dev)
return -1; return -1;
} }
shell_power(dev->proto.data, dev->proto.datalen);
mab = powerbuf_last_mab(dev->base.power_buf); mab = powerbuf_last_mab(dev->base.power_buf);
for (i = 0; i + 3 < dev->proto.datalen; i += 4) { for (i = 0; i + 3 < dev->proto.datalen; i += 4) {
uint32_t s = LE_LONG(dev->proto.data, i); 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); return nanosleep(&ts, NULL);
} }
#endif #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_s(unsigned int s);
int delay_ms(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 */ /* printf format for long long args */
#ifdef __MINGW32__ #ifdef __MINGW32__
#define LLFMT "I64d" #define LLFMT "I64d"