| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- /*
- * Copyright STREAMIT BV, 2010.
- *
- * Project : SIR
- * Module : Log
- * File name $Workfile: Log.c $
- * Last Save $Date: 2003/08/16 15:01:19 $
- * $Revision: 0.1 $
- * Creation Date : 2003/08/16 15:01:19
- *
- * Description : Keeps track of log messages
- * As an initial implementation this module
- * outputs messages to the serial port and uses
- * no buffering. (As a result logging delays execution
- * as long as the serial write takes)
- * At a later stage this module will have a logging
- * queue. This will not have much impact on execution
- * time. It will output messages to either a serial port
- * or telnet client.
- *
- */
- /*--------------------------------------------------------------------------*/
- /* Include files */
- /*--------------------------------------------------------------------------*/
- #define LOG_MODULE LOG_LOG_MODULE
- #include <stdio.h>
- #include <string.h>
- #include <sys/thread.h>
- #include <sys/heap.h>
- #include <sys/device.h>
- #include <sys/osdebug.h>
- //#pragma text:appcode
- #include "uart0driver.h"
- //#include "settings.h"
- #include "log.h"
- /*--------------------------------------------------------------------------*/
- /* Constant definitions */
- /*--------------------------------------------------------------------------*/
- /*!\brief Max length of address */
- #define MAX_OFFSET_LEN 8
- /*!\brief Max byte values printed on a line */
- #define BYTES_PER_LINE 16
- /*!\brief Max number of characters hex dump takes: 2 digits plus trailing blank */
- #define HEX_DUMP_LEN (BYTES_PER_LINE*3)
- /*!\brief Number of characters hex dump + ascii take: 3 chars, 2 blanks, 1 char */
- #define DATA_DUMP_LEN (HEX_DUMP_LEN + 2 + BYTES_PER_LINE)
- /*!\brief Number of characters per line: address, 2 blanks, data dump */
- #define MAX_LINE_LEN (MAX_OFFSET_LEN + 2 + DATA_DUMP_LEN)
- #define LEVEL_MASK 0x07 // b0...b2
- #define NAME_MASK 0xF8 // b3..b7
- /*--------------------------------------------------------------------------*/
- /* Type declarations */
- /*--------------------------------------------------------------------------*/
- /*--------------------------------------------------------------------------*/
- /* Local variables */
- /*--------------------------------------------------------------------------*/
- /*!\brief The current log level */
- static TLogLevel g_tLevel;
- /*!\brief Stream to output the log data to */
- static FILE *g_tStream;
- /*--------------------------------------------------------------------------*/
- /* Global variables */
- /*--------------------------------------------------------------------------*/
- /*--------------------------------------------------------------------------*/
- /* Local functions */
- /*--------------------------------------------------------------------------*/
- /*!
- * \brief Return the prefix-level for the given log level.
- *
- * \param tLevel [in] The log level.
- *
- * \return Pointer to a string in program space.
- */
- static PGM_P LogPrefixLevel_P(TLogLevel tLevel)
- {
- switch (tLevel)
- {
- case LOG_EMERG_LEV :return(PSTR("\n#Emerg "));
- case LOG_ALERT_LEV :return(PSTR("\n#Alert "));
- case LOG_CRIT_LEV :return(PSTR("\n#Crit "));
- case LOG_ERR_LEV :return(PSTR("\n#Err "));
- case LOG_WARNING_LEV :return(PSTR("\n#Warn "));
- case LOG_NOTICE_LEV :return(PSTR("\n#Notic "));
- case LOG_INFO_LEV :return(PSTR("\n#Info "));
- case LOG_DEBUG_LEV :return(PSTR("\n#Debug "));
- default :return(PSTR("\n"));
- }
- }
- /*!
- * \brief Return the prefix-name for the given log module.
- *
- * \param tLevel [in] The log module.
- *
- * \return Pointer to a string in program space.
- */
- static PGM_P LogPrefixName_P(TLogLevel tLevel)
- {
- switch (tLevel)
- {
- case LOG_AUDIO_MODULE :return(PSTR("AU: "));
- case LOG_CHANNEL_MODULE :return(PSTR("CH: "));
- case LOG_COMAND_MODULE :return(PSTR("CM: "));
- case LOG_DISPLAY_MODULE :return(PSTR("DP: "));
- case LOG_FAT_MODULE :return(PSTR("FA: "));
- case LOG_FLASH_MODULE :return(PSTR("FL: "));
- case LOG_HTTP_MODULE :return(PSTR("HT: "));
- case LOG_INET_MODULE :return(PSTR("IN: "));
- case LOG_KEYBOARD_MODULE :return(PSTR("KB: "));
- case LOG_LED_MODULE :return(PSTR("LE: "));
- case LOG_LOG_MODULE :return(PSTR("LG: "));
- case LOG_MAIN_MODULE :return(PSTR("SY: "));
- case LOG_MENU_MODULE :return(PSTR("ME: "));
- case LOG_MMC_MODULE :return(PSTR("MM: "));
- case LOG_MMCDRV_MODULE :return(PSTR("MD: "));
- case LOG_NTP_MODULE :return(PSTR("NT: "));
- case LOG_PARSE_MODULE :return(PSTR("PA: "));
- case LOG_PLAYER_MODULE :return(PSTR("PL: "));
- case LOG_REMCON_MODULE :return(PSTR("RC: "));
- case LOG_RTC_MODULE :return(PSTR("RT: "));
- case LOG_SELFTEST_MODULE :return(PSTR("ST: "));
- case LOG_SESSION_MODULE :return(PSTR("SE: "));
- case LOG_SETTINGS_MODULE :return(PSTR("SG: "));
- case LOG_SPIDRV_MODULE :return(PSTR("SP: "));
- case LOG_STREAMER_MODULE :return(PSTR("SR: "));
- case LOG_UART0DRIVER_MODULE :return(PSTR("UA: "));
- case LOG_UPDATE_MODULE :return(PSTR("UD: "));
- case LOG_UTIL_MODULE :return(PSTR("UT: "));
- case LOG_VERSION_MODULE :return(PSTR("VE: "));
- case LOG_VS10XX_MODULE :return(PSTR("VS: "));
- case LOG_WATCHDOG_MODULE :return(PSTR("WD: "));
- default :return(PSTR("?? <DMK> "));
- }
- }
- /*--------------------------------------------------------------------------*/
- /* Global functions */
- /*--------------------------------------------------------------------------*/
- /*!
- * \brief Initialises this module
- *
- * \param -
- *
- * \return -
- */
- void LogInit(void)
- {
- /* Set default level */
- g_tLevel = LOG_DEBUG_LEV;
- LogOpen();
- }
- /*!
- * \brief Opens the module for use.
- *
- * \param -
- *
- * \return -
- */
- void LogOpen(void)
- {
- /* Associate our stream with a device */
- g_tStream = Uart0DriverGetStream();
- }
- /*!
- * \brief Closes the module.
- *
- * All interface functions from this module will result in void
- * operations.
- *
- * \param -
- *
- * \return -
- */
- void LogClose(void)
- {
- FILE *tPrevStream = g_tStream;
- /* Don't allow adding of new output. */
- g_tStream = NULL;
- /* Finish all current output. */
- fflush(tPrevStream);
- }
- /*!
- * \brief Log a message to the log medium using a fixed string.
- *
- * The fixed string must reside in program space. It is parsed
- * using the rules of (s)printf.
- *
- * \param tLevel priority level of the message.
- * \param szMsg format string of the message.
- * \param ... arguments to the format string.
- */
- void LogMsg_P(TLogLevel tLevel, PGM_P szMsg, ...)
- {
- va_list ap;
- if (g_tStream)
- {
- /* Log the string if the message is more important than the current level */
- if ((tLevel&LEVEL_MASK) <= g_tLevel)
- {
- fputs_P(LogPrefixLevel_P(tLevel&LEVEL_MASK), g_tStream);
- fputs_P(LogPrefixName_P(tLevel&NAME_MASK), g_tStream);
- va_start(ap, szMsg);
- vfprintf_P(g_tStream, szMsg, ap);
- va_end(ap);
- }
- }
- }
- void LogChar_P(const char bChar)
- {
- if (g_tStream)
- {
- fputc(bChar, g_tStream);
- }
- }
- /*!
- * \brief Set the priority level
- *
- * \param tNewLevel New priority level
- *
- * \return The previous priority level
- */
- TLogLevel LogSetLevel(TLogLevel tNewLevel)
- {
- TLogLevel tPrevLevel = g_tLevel;
- if (tNewLevel <= LOG_DEBUG_LEV)
- {
- g_tLevel = tNewLevel;
- }
- return(tPrevLevel);
- }
- /*!
- * \brief Print a block of memory
- *
- * Prints out 16 bytes of data per line
- * Every line starts with the address (offset),
- * the data in hex and that same data in ascii.
- *
- * \param tStream The stream to print to
- * \param cp The data
- * \param length The length of the data
- *
- * \return none
- */
- void HexDump(FILE *tStream, CONST u_char *cp, size_t length)
- {
- register unsigned int address, i, hex_pos, ascii_pos, l;
- unsigned int address_len;
- unsigned char c;
- char line[MAX_LINE_LEN + 1];
- static CONST char binhex[16] =
- {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
- };
- if (tStream != NULL)
- {
- /*
- * How many digits do we need for the address?
- * We use at least 4 digits or more as needed
- */
- if (((length - 1) & 0xF0000000) != 0)
- {
- address_len = 8;
- }
- else if (((length - 1) & 0x0F000000) != 0)
- {
- address_len = 7;
- }
- else if (((length - 1) & 0x00F00000) != 0)
- {
- address_len = 6;
- }
- else if (((length - 1) & 0x000F0000) != 0)
- {
- address_len = 5;
- }
- else
- {
- address_len = 4;
- }
- address = 0;
- i = 0;
- hex_pos = 0;
- ascii_pos = 0;
- while (i < length)
- {
- if ((i & 15) == 0)
- {
- /*
- * Start of a new line.
- */
- memset(line, ' ', sizeof(line));
- hex_pos = 0;
- ascii_pos = 0;
- l = address_len;
- do
- {
- l--;
- c = (address >> (l*4)) & 0xF;
- line[hex_pos++] = binhex[c];
- } while (l != 0);
- /* 2 spaces */
- hex_pos += 2;
- /*
- * Offset in line of ASCII dump.
- */
- ascii_pos = hex_pos + HEX_DUMP_LEN + 2;
- }
- c = *cp++;
- /* Dump the hex value */
- line[hex_pos++] = binhex[c >> 4];
- line[hex_pos++] = binhex[c & 0xF];
- hex_pos++;
- /* Print the ascii value */
- line[ascii_pos++] = (c >= ' ' && c < 127) ? c : '.';
- i++;
- if ((i & 15) == 0 || i == length)
- {
- /*
- * We'll be starting a new line, or
- * we're finished printing this buffer;
- * dump out the line we've constructed,
- * and advance the offset.
- */
- line[ascii_pos] = '\0';
- fputs(line, tStream);
- fputc('\n', tStream);
- address += BYTES_PER_LINE;
- }
- }
- }
- }
|