Previous: , Up: Libc   [Contents]


3.4.4 Useful debugging functions

There are always a few useful functions for debugging your project in progress. I typically implement a simple print() routine that runs standalone in liblgoss, with no newlib support. The I/O function outbyte() can also be used for low level debugging. Many times print will work when there are problems that cause printf() to cause an exception. putnum() is just to print out values in hex so they are easier to read.

/*
 * print -- do a raw print of a string
 */ 
int
print(ptr)
char *ptr;
{
  while (*ptr) {
    outbyte (*ptr++);
  }
}

/*
 * putnum -- print a 32 bit number in hex
 */
int
putnum (num)
unsigned int num;
{
  char  buffer[9];
  int   count;
  char  *bufptr = buffer;
  int   digit;
  
  for (count = 7 ; count >= 0 ; count--) {
    digit = (num >> (count * 4)) & 0xf;
    
    if (digit <= 9)
      *bufptr++ = (char) ('0' + digit);
    else
      *bufptr++ = (char) ('a' - 10 + digit);
  }

  *bufptr = (char) 0;
  print (buffer);
  return;
}

If there are LEDs on the board, they can also be put to use for debugging when the serial I/O code is being written. I usually implement a zylons() function, which strobes the LEDS (if there is more than one) in sequence, creating a rotating effect. This is convenient between I/O to see if the target is still alive. Another useful LED function is led_putnum(), which takes a digit and displays it as a bit pattern or number. These usually have to be written in assembler for each target board. Here are a number of C based routines that may be useful.

led_putnum() puts a number on a single digit segmented LED display. This LED is set by setting a bit mask to an address, where 1 turns the segment off, and 0 turns it on. There is also a little decimal point on the LED display, so it gets the leftmost bit. The other bits specify the segment location. The bits look like:

        [d.p | g | f | e | d | c | b | a ] is the byte.

The locations are set up as:

             a
           -----
        f |     | b
          |  g  |
           -----
          |     |
        e |     | c
           -----
             d

This takes a number that’s already been converted to a string, and prints it.

#define LED_ADDR	0xd00003

void
led_putnum ( num )
char num;
{
    static unsigned char *leds = (unsigned char *)LED_ADDR;
    static unsigned char num_bits [18] = {
      0xff,						/* clear all */
      0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, /* numbers 0-9 */
      0x98, 0x20, 0x3, 0x27, 0x21, 0x4, 0xe 		/* letters a-f */
    };

    if (num >= '0' && num <= '9')
      num = (num - '0') + 1;

    if (num >= 'a' && num <= 'f')
      num = (num - 'a') + 12;

    if (num == ' ')
      num = 0;

    *leds = num_bits[num];
}

/*
 * zylons -- draw a rotating pattern. NOTE: this function never returns.
 */
void
zylons()
{
  unsigned char *leds 	= (unsigned char *)LED_ADDR;
  unsigned char curled = 0xfe;

  while (1)
    {
      *leds = curled;
      curled = (curled >> 1) | (curled << 7);
      delay ( 200 );
    }
}

Previous: , Up: Libc   [Contents]