Customize reports using Annotate

While ARM Streamline provides a large variety of target information, sometimes you require extra context to decipher exactly what the target is doing at certain instances. Streamline Annotate provides a facility for you to add this context to Streamline.

The Streamline Annotate feature works in a similar way to printf, but instead of console output, annotate statements populate the Log view and place framing overlays right in the Streamline Timeline view:

Figure 39. Annotate overlays

Annotate overlays

When the user space application writes to the dev/gator/annotate file, the gator driver marks the recorded annotate-driven output with a timestamp and integrates the recorded data into the Streamline sample and trace capture report.

The annotated text is marked with a thread identifier that keeps the data uncluttered and eliminates the necessity of user mutexes. Writing to the annotate file is handled by the standard C-library functions.

The application code accesses the virtual annotate file using the standard c-library functions: fopen, fwrite, and fprintf. To start using the annotate feature, do the following:

  1. Ensure gatord is running. gatord creates the /dev/gator/annotate file.

  2. Open /dev/gator/annotate with write permissions

  3. Write null-terminated strings to the file from any thread

  4. Optionally set the color of the annotation by sending the ASCII escape code followed by a 3-byte RGB value

  5. Disable buffering on the annotate file, or manually flush the file after each write

  6. Write an empty string to clear the annotation message for the thread

Unless you are running out of file handles, closing the annotate file on completion is optional.

The following code examples show how you can build an annotate.h header file and use the annotate function in the simple sum.c program.

Show/hideCode example: annotate.h

#ifndef ANNOTATE_h
#define ANNOTATE_h

#include <stdio.h>
extern FILE *gator_annotate;

/* You must put 'ANNOTATE_DEFINE;' one place in your program. */
#define ANNOTATE_DEFINE   FILE *gator_annotate

#define ANNOTATE_SETUP  do { \
	gator_annotate = fopen("/dev/gator/annotate", "wb"); \
	if (gator_annotate) setvbuf(gator_annotate, (char *)NULL, _IONBF, 0); }} while(0)

#define ANNOTATE(...)   do { if (gator_annotate) { \
	fprintf(gator_annotate, __VA_ARGS__); \
	fputc('\0', gator_annotate); }} while(0)

#define ANNOTATE_COLOR(color, ...) do { if (gator_annotate) { \
	fwrite((char*)&color, 1, sizeof(color), gator_annotate); \
	fprintf(gator_annotate, __VA_ARGS__); \
	fputc('\0', gator_annotate); }} while(0)

#define ANNOTATE_END() do { if (gator_annotate) { \
	fputc('\0', gator_annotate); }} while(0)

// ESC character, hex RGB (little endian)
static const int ANNOTATE_RED = 0x0000ff1b;
static const int  ANNOTATE_BLUE = 0xff00001b;
static const int  ANNOTATE_GREEN = 0x00ff001b;
static const int  ANNOTATE_PURPLE = 0xff00ff1b;
static const int  ANNOTATE_YELLOW = 0x00ffff1b;
static const int  ANNOTATE_CYAN = 0xffff001b;
static const int  ANNOTATE_WHITE = 0xffffff1b;
static const int  ANNOTATE_LTGRAY = 0xbbbbbb1b;
static const int  ANNOTATE_DKGRAY = 0x5555551b;
static const int  ANNOTATE_BLACK = 0x0000001b;

#endif // ANNOTATE_h

Show/hideCode example: sum.c

This simple sum.c program shows how annotate can be added to your code:

#include <stdlib.h>
#include "annotate.h"
// instantiated once per program
ANNOTATE_DEFINE;

// caution: unintended stack use may cause a segfault
unsigned long long sum_recursive(int x) {
  if (x <= 0) return x;
  return x + sum_recursive(x - 1);
}

unsigned long long sum_loop(int x) {
  unsigned long long sum = 0;
  while (x > 0) sum += x--;
  return sum;
}

unsigned long long sum_fast(int x) {
  if (x <= 0) return x;
  return (((unsigned long long)x+1) * (unsigned long long)x >> 1);
}

int main(int argc, char** argv) {
  // called once per program
  ANNOTATE_SETUP;
  if (argc != 2) {
    printf("usage: sum <num>\n");
    return 0;
  }

  int value = atoi(argv[1]);
  ANNOTATE("Sum of Numbers (%d)", value);
  unsigned long long sum = sum_loop(value);
  ANNOTATE_COLOR(ANNOTATE_PURPLE, "Sum of Numbers Recursive");
  unsigned long long sumr = sum_recursive(value);
  ANNOTATE("Sum of Numbers Fast");
  unsigned long long sumf = sum_fast(value);
  ANNOTATE(""); // End annotation

  printf("sum = %lld, sumr = %lld, sumf = %lld\n", sum, sumr, sumf);
  return 0;
}

Show/hideSee also

Copyright © 2010-2011 ARM. All rights reserved.ARM DUI 0482D
Non-ConfidentialID072211