⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logterm.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*-C-*- * * $Revision: 1.1 $ *   $Author: rivimey $ *     $Date: 1999/03/11 11:54:02 $ * * Copyright (c) 1997 Advanced RISC Machines Limited. * All Rights Reserved. * *   Project: ANGEL * *     Title: Debug interface via Serial writes to 16c552 serial port B. */#include <string.h>#if DEBUG == 1 && (!defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0)#include "channels.h"#include "devconf.h"#include "platform.h"#include "logging.h"#include "logging/logterm.h"#include "serlock.h"#include "serring.h"#include "debug.h"#include "support.h"#include "disass.h"#define SAVEBUFSIZE     2048    /* max #words in save buffer -- min 6 words/message */#define MAXARGS         32      /* max number of distinct args on cmd line */#define CMDBUFSIZE      128     /* max number of characters on command line */#define OUTPUTBUFSIZE   64      /* number of buffered characters from message before flush */#ifndef UNUSED#define UNUSED(x)       (0 ? (x) = (x) : 0)#endifstatic unsigned long msgsavebuf[SAVEBUFSIZE];static struct LogSaveBuffer savebuf;static char log_commandbuf[CMDBUFSIZE];static int log_cursor = 0;static WarnLevel logterm_level;static char  logterm_buf[OUTPUTBUFSIZE];static char *logterm_pos;static char *logterm_end;static int log_tracing = TRUE;static int log_deferredprompt = FALSE;static int log_buflock = FALSE;static int log_cmdlock = FALSE;/* static void setupsave(void); */void log_emitch(char ch);void log_emitstr(char *str);static void log_output(int enable);static void log_processchar(char ch, unsigned int empty_stack);static int log_dump(int argc, char **argv);static int log_echo(int argc, char **argv);static int log_ver(int argc, char **argv);static int log_help(int argc, char **argv);static int log_trace(int argc, char **argv);static int log_go(int argc, char **argv);static int log_restart(int argc, char **argv);int log_pause(int argc, char **argv);static int log_stat(int argc, char **argv);static int log_task(int argc, char **argv);static int log_level(int argc, char **argv);#ifdef HAVE_DISASSstatic int log_list(int argc, char **argv);#endifstatic int log_format(int argc, char **argv);static struct {    char *str;    int (*pfn)(int argc, char **argv);    char *desc, *helpstr;} log_cmds[] ={   /* These must be kept in sorted order by name */    { "dump",  log_dump,  "Dump\n",                          "syntax: dump <start addr> [ <end addr> | +<len> ]\n"    },    { "echo",  log_echo,  "Echo\n",                          "syntax: echo <words>\n"    },    { "format",log_format,"Show / set the per-line format string\n",                          "syntax: format [<new string>]\n"    },    { "go",    log_go,    "Undo pause; reenable ints\n",                          "syntax: go\n"    },    { "help",  log_help,  "Command help\n",                          "syntax: help [command]\n"    },    { "level", log_level,   "Set the minimum log level displayed.\n",                            "syntax: level [info|warn|err]\n"    },#ifdef HAVE_DISASS    { "list",  log_list,    "Disassemble instructions from memory.\n",                            "syntax: list addr1 [addr2 | +len]\n"    },#endif    { "pause", log_pause, "Pause Angel; disable ints\n",                          "syntax: pause\n"    },    { "restart", log_restart,"Reboot Angel, optionally specifying restart addr.\n",                            "syntax: reboot [address]\n"    },    { "stat",  log_stat,  "Display internal statistics info\n",                          "syntax: stat [packagename]\n"                            "  packages: serpkt\n"    },    { "task",  log_task,    "Display internal task details\n",                            "syntax: task          - general scheduler details\n"                            "        task list     - list all known task contexts\n"                            "        task log <n>  - display <n> entries in task event log\n"                            "        task rb <name> - print global regblock <name> from:\n"                            "                        Intr,Desrd,SWI,Abort,Undef,Yield,Fatal,\n"                            "        task tq <n>   - display task queue entry <n>\n"    },    { "trace", log_trace, "Enable/disable tracing or display trace buffer\n",                          "syntax: trace           -- display current settings\n"                          "        trace <n>       -- show <n> lines of buffer\n"                          "        trace <n>       -- show <n> lines of buffer\n"                          "        trace on | off  -- enable/disable run-time trace\n"    },    { "ver",   log_ver,   "Display Angel version info\n",                          "syntax: ver\n"    },};static const int log_ncmds = sizeof(log_cmds)/sizeof(log_cmds[0]);/* * NT's HyperTerminal needs CRLF, not just LF! */#define LOGTERM_ADD_CR_TO_LF 1#pragma no_check_stack#include "banner.h"#define LOGONMESSAGE "\n\n" ANGEL_BANNER "Type 'help' for more info.\n\n"#define PROMPT       "% "/* * macros to control Interrupt Enable Register in various sensible ways */#ifdef DEBUG_WITHINTERRUPTS#define st16c552_EnableTxInterrupt(u)  (IER_set((u), TxReadyInt))#define st16c552_DisableTxInterrupt(u) (IER_clr((u), TxReadyInt))#define st16c552_EnableRxInterrupt(u)  (IER_set((u), RxReadyInt))#define st16c552_DisableRxInterrupt(u) (IER_clr((u), RxReadyInt))#endif/* * prefix for lines not at start of message -- see stuff in putchar too */#define PREFIXLEN   6/* * prototypes *//* *  Function: stoi *   Purpose: string to integer conversion; like atoi but doesn't pull in *            the rest of the c library! * *  Pre-conditions: none. * *    Params: *       Input: s - pointer to (base-10) number in ASCII * *       Output: e - pointer to last character converted *               *   Returns: number converted */static int stoi(char *s, char **e){    int i, sign = 0, base = 10;    while(*s == ' ')        s++;    switch(*s)    {        case '-':            sign = -1;            s++;            break;        case '0':            if (s[1] == 'x')            {                base = 16;                s+=2;            }            break;        case '+':            s++;            sign = 1;            break;        default:            sign = 1;            break;    }    i = 0;    if (base == 10)    {        while(*s >= '0' && *s <= '9')        {            i = (i * 10) + (*s - '0');            s++;        }    }    else    {        while((*s >= '0' && *s <= '9') || (*s >= 'a' && *s <= 'f') ||                (*s >= 'A' && *s <= 'F'))        {            if (*s >= 'a')                i = (i * 16) + (*s - 'a' + 10);            else if (*s >= 'A')                i = (i * 16) + (*s - 'A' + 10);            else                i = (i * 16) + (*s - '0');            s++;        }    }    if (sign < 0)        i = -i;    *e = s;        return i;}void logterm_flushbuf(void);/* *  Function: logterm_Initialise *   Purpose:  * *  Pre-conditions: none. * *    Params: *       Input:  * *   Returns: 0. *//* REMEMBER: This routine gets called VERY EARLY!! */bool logterm_Initialise(void){    logserial_Reset(LOGTERM_PORT, BAUDVALUE) ;    /*     * output is polled, but input is interrupt-driven.     */#ifdef DEBUG_WITHINTERRUPTS    st16c552_DisableTxInterrupt(serchip);    st16c552_EnableRxInterrupt(serchip);#endif        /*     * print a logon banner to say we're here!     */    log_emitstr(LOGONMESSAGE);    log_emitstr(PROMPT);        log_deferredprompt = FALSE;    log_tracing = TRUE;        log_setupsave(&savebuf, msgsavebuf, SAVEBUFSIZE);        log_set_logging_options(WL_SAVEMSG|WL_PRINTMSG);    log_set_log_id(LOG_ALWAYS, 1);    /* this works because it's polled input... interrupts     * are disabled in this code     */    log_pause(0,0);        return 0;}struct LogSaveBuffer *log_getlogtermbuf(void){    return &savebuf;}bool logterm_PreWarn(WarnLevel level){    /*     * set up the buffer pointers... reset in flushbuf     */    logterm_pos = logterm_buf;    logterm_end = (logterm_buf + sizeof(logterm_buf) - 1);    logterm_level = level;    return TRUE;}void logterm_flushbuf(void){    char *p;        p = logterm_buf;    while(p < logterm_pos)    {        log_emitch(*p++);    }    logterm_pos = logterm_buf;    logterm_end = logterm_buf + sizeof(logterm_buf) - 1;}int logterm_PutChar(char c){    if (logterm_pos >= logterm_end)        logterm_flushbuf();    *logterm_pos++ = c;    return 0;}void logterm_PutString(char *str){    while(*str)    {        logterm_PutChar(*str++);    }}void logterm_PostWarn(unsigned int len){    IGNORE(len);    if (logterm_pos > logterm_buf)        logterm_flushbuf();}/* * Show a number nlines of messages from the trace buffer, working * back from the current insert position. * * This is done by starting at the insert position and using the * count value (which is at 'insert' - 1) to skip backwards through * the buffer until either the oldest data is reached or the required * number of lines is found. * * Then work forward, calling log_logprint() to print the text. * */static void log_showitems(struct LogSaveBuffer *sb, int nlines){    int count, message_start = sb->message;    unsigned long *ptr = sb->current;    log_printf("showitems: sb = %x, lins %d, ptr = %x; *ptr = %x\n",    		sb, nlines, ptr, *ptr);    if (ptr == 0 || *ptr == 0) /* nothing to do */        return;    ptr--;      /* normally, savebufinsert points at next free slot */    /*     * while we haven't got to the start point  -- either the start of     * data, or the item we want to start with, or the oldest item in     * the buffer is reached, skip back from the insert point.     *     * Note: 'start of data' and 'oldest' are differently encoded -- start     * of data is indicated by a zero count, written when the buffer is     * set up. 'oldest' is reached when the current pointer is larger     * than the insert pointer, and (ptr - count) is less.     */    count = nlines;    while(count > 0 && *ptr != 0)    {	log_printf("showitems: count %d, mess %d\n", count, message_start);        /*         * got to oldest; no more (complete) messages available.         */        if (ptr >= sb->current && (ptr - (*ptr & 0xff)) < sb->current)            break;        /*         * if this message marks the end of a line (flagged by the top         * bits of the word being set), decrement the message number too.         */        if (*ptr & ~0xff)        {            message_start--;            count--;        }        /* skip one more back, wrapping around the beginning. */        ptr -= (*ptr & 0xff);        if (ptr < sb->start)                ptr += sb->size;    }    log_printf("showitems: count %d, ptr %x\n", count, ptr );    /*     * now run forward, printing each line from the data in the buffer. Of     * course, pointer values are printed from memory, and so may be incorrect     * if the program changed that memory in the meantime....     */    count = nlines;    while(count > 0)    {        log_logprint(message_start, ptr);        if (*ptr & ~0xff)        {            message_start++;            count--;        }        /* skip one more forward, wrapping around the beginning. */        ptr += *ptr;        if (ptr >= sb->end)                ptr -= sb->size;    }    log_printf("showitems: done\n" );}void log_emitch(char ch){    int status ;#ifdef LOGTERM_ADD_CR_TO_LF    if (ch == '\n')    {        do {            status = LOG_GET_STATUS(LOGTERM_PORT) ;        } while (!LOG_TX_READY(status)) ;        LOG_PUT_CHAR(LOGTERM_PORT, '\r') ;    }#endif    do {        status = LOG_GET_STATUS(LOGTERM_PORT) ;    } while (!LOG_TX_READY(status)) ;    LOG_PUT_CHAR(LOGTERM_PORT, ch) ;}void log_emitstr(char *str){    while(*str)    {        log_emitch(*str++);    }}/**************************************************************************//*                Command Interpreter                                     *//**************************************************************************//* *  Function: log_stat *   Purpose: Print status report; eventually, this should be able to, for *            example, print the number of packets sent, or CRC errors under ADP, *            or whatever else. Needs more work! * *  Pre-conditions: none. * *    Params: *       Input: argc, argv - "main" argc/argv pair containing args. argv[0] *                           is name of command (i.e. "stat"). * *   Returns: 0. */extern struct StatInfo spk_stat_info[];extern struct StatInfo intr_stat_info[];extern struct StatInfo task_stat_info[];static int log_stat(int argc, char **argv){    struct StatInfo *p = NULL;    char *h = "known modules: serpkt, intr, task\n";        if (argc < 2)    {        log_emitstr("stat: no module name given\n");        log_emitstr(h);        return 0;    }        if (__rt_strcmp(argv[1], "serpkt") == 0)    {        p = spk_stat_info;    }    else if (__rt_strcmp(argv[1], "intr") == 0)    {        p = intr_stat_info;    }    else if (__rt_strcmp(argv[1], "task") == 0)    {        p = task_stat_info;    }    if (p)    {        while(p->format != NULL)        {            int l;                        logterm_PreWarn(WL_INFO);            l = log_printf(p->format, *p->param);            logterm_PostWarn(l);            p++;        }    }    else     {        log_emitstr("stat: unknown module name\n");        log_emitstr(h);    }       return 0;}/* *  Function: log_level *   Purpose:  * *  Pre-conditions: none. * *    Params: *       Input: argc, argv - "main" argc/argv pair containing args. argv[0] *                           is name of command (i.e. "level"). * *   Returns: 0. */static int log_level(int argc, char **argv){    WarnLevel lvl;        if (argc == 1)    {        lvl = log_get_log_minlevel();                switch(lvl)        {            case WL_INFO:                log_emitstr("level: info\n");                break;                            case WL_WARN:                log_emitstr("level: warn\n");                break;                            case WL_ERROR:                log_emitstr("level: error\n");                break;        }    }    else if (argc == 2)    {                if (argv[1][0] == 'i')        {            log_set_log_minlevel(WL_INFO);        }        else if (argv[1][0] == 'w')        {            log_set_log_minlevel(WL_WARN);        }        else if (argv[1][0] == 'e')        {            log_set_log_minlevel(WL_ERROR);        }        else            log_emitstr("level: unknown level name\n");    }    else    {        log_emitstr("level: bad syntax\n");    }        return 0;}/* *  Function: log_go

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -