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

📄 logterm.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 3 页
字号:
extern List angel_TQI_Run;extern struct angel_TaskLog* angel_DebugTaskBase;extern struct angel_TaskLog* angel_DebugTaskArea;extern int angel_DebugStartTaskCount;extern int angel_DebugQueueTaskCount;extern angel_TaskQueueItem angel_TQ_Pool[POOLSIZE];static char *rbnames[6] ={    "Intr", "SWI", "Undef", "Abort", "Yield", "Fatal"};static char *typenames[11] ={    "",    "StartTsk", "QueueTsk", "IntHand", "SaveTsk",    "Yield", "SWIHand", "BRKHand", "Wait",    "Abort", "DelTask"};static char *tasknames[7] ={    "IdleLoop",    "AngelInit",    "Application",    "AngelCallBack",    "ApplCallBack", /* not used */    "PollLoop",    "AngelWantLock"};static char *taskstates[5] ={    "Undefined",    "Defined",    "Runnable",    "Running",    "Blocked"};static void log_RegblockName(void *rb){    if (rb == 0)        logterm_PutString("        ");    else if (rb >= (void *)&Angel_GlobalRegBlock[0] &&        rb < (void *)&Angel_GlobalRegBlock[RB_NumRegblocks])    {        int index = (angel_RegBlock*)rb - &Angel_GlobalRegBlock[0];                log_printf("RB %5s", rbnames[index]);    }       else if (rb >= (void *)&angel_TQ_Pool[0] &&             rb < (void *)&angel_TQ_Pool[POOLSIZE])    {        int index = (angel_TaskQueueItem*)rb - &angel_TQ_Pool[0];                log_printf("TQ %5d", index);    }    else        log_printf("rb%6lx", rb);}static void log_ShowRegblock(angel_RegBlock *rb){    log_printf("      pc = %08lx cpsr = %08lx\n",               rb->pc, rb->cpsr);        log_printf("      r0 = %08lx   r1 = %08lx   r2 = %08lx   r3 = %08lx\n",               rb->r0, rb->r1, rb->r2, rb->r3);    log_printf("      r4 = %08lx   r5 = %08lx   r6 = %08lx   r7 = %08lx\n",               rb->r4, rb->r5, rb->r6, rb->r7);        log_printf("USR:  r8 = %08lx   r9 = %08lx  r10 = %08lx  r11 = %08lx\n",               rb->r8usr, rb->r9usr, rb->r10usr, rb->r11usr);    log_printf("     r12 = %08lx  r13 = %08lx  r14 = %08lx\n",               rb->r12usr, rb->r13usr, rb->r14usr);        log_printf("FIQ:  r8 = %08lx   r9 = %08lx  r10 = %08lx  r11 = %08lx\n",               rb->r8fiq, rb->r9fiq, rb->r10fiq, rb->r11fiq);    log_printf("     r12 = %08lx  r13 = %08lx  r14 = %08lx spsr = %08lx\n",               rb->r12fiq, rb->r13fiq, rb->r14fiq, rb->spsrirq);        log_printf("IRQ:                 r13 = %08lx  r14 = %08lx spsr = %08lx\n",               rb->r13irq, rb->r14irq, rb->spsrirq);        log_printf("SVC:                 r13 = %08lx  r14 = %08lx spsr = %08lx\n",               rb->r13svc, rb->r14svc, rb->spsrsvc);        log_printf("UND:                 r13 = %08lx  r14 = %08lx spsr = %08lx\n",               rb->r13und, rb->r14und, rb->spsrund);        log_printf("ABT:                 r13 = %08lx  r14 = %08lx spsr = %08lx\n",               rb->r13abt, rb->r14abt, rb->spsrabt);}static void log_ShowTaskItem(int tqi, angel_TaskQueueItem *tq){    log_printf("Task Queue %d: (%08lx) %s\n"               "Next = %08lx, Index = %d, Type = %s, State = %s, Priority = %u\n",               tqi, tq, (tq->n.n_name) ? tq->n.n_name : "", tq->n.n.mn_next,               tq->n.n_type, tasknames[tq->type], taskstates[tq->state], tq->n.n_pri);        log_printf("Stack Base = %08lx, Limit = %08lx, Entrypoint = %08lx\n",               tq->stack->stackBase, tq->stack->stackLimit, tq->entryPoint);        log_printf("Signal Wait = %08lx, Signal Bits = %08lx\n",               tq->signalWaiting, tq->signalReceived);        log_ShowRegblock(&angel_TQ_Pool[tqi].rb);}/* *  Function: log_task *   Purpose: The trace action. trace syntax is: *       task             show current task stats *       task <number>    show <number> prior task switches *  *  Pre-conditions: none. * *    Params: *       Input: argc, argv - "main" argc/argv pair containing args. argv[0] *                           is name of command (i.e. "trace"). * *   Returns: 0 */static int log_task(int argc, char **argv){        if (argc == 1) /* no args */    {        logterm_PreWarn(WL_INFO);                log_printf("Log Base:        %8lx\n", angel_DebugTaskBase);        log_printf("Next Entry @:    %8lx\n", angel_DebugTaskArea);        log_printf("Started Tasks:   %8ld\n", angel_DebugStartTaskCount);        log_printf("Queued Tasks:    %8ld\n", angel_DebugQueueTaskCount);        log_printf("Deferred Block   %8ld\n", angel_SWIDeferredBlock);        log_printf("Processing SWI   %8ld\n", angel_SWIReturnToApp);                logterm_PostWarn(0);    }    else if (argc > 1 && __rt_strcmp(argv[1], "list") == 0) /* at least one arg */    {        angel_TaskQueueItem *tq = (angel_TaskQueueItem *)FirstNode(&angel_TQI_Run);                logterm_PreWarn(WL_INFO);        while(!AtEndOfList((MinNode*)tq))        {            log_ShowTaskItem(tq->n.n_type, tq);                        tq = (angel_TaskQueueItem *)Succ((MinNode*)tq);            if (!AtEndOfList((MinNode*)tq))                logterm_PutString("\n");        }                logterm_PostWarn(0);    }    else if (argc > 1 && __rt_strcmp(argv[1], "log") == 0) /* at least one arg */    {        int ntasks;        char *ep;        struct angel_TaskLog *tl = angel_DebugTaskArea;        struct angel_TaskLog *tlbase = angel_DebugTaskBase;        logterm_PreWarn(WL_INFO);        ntasks = stoi(argv[2], &ep);        if (ep > argv[1] && ntasks > 0 && ntasks < 100000)        {            tl--; /* tl starts off pointing at next free block */            while(ntasks > 0 && tl >= tlbase)            {                log_printf("%9d: %8s ", tl->count, typenames[tl->id]);                log_RegblockName(tl->taskblock);                logterm_PutString(", ");                log_RegblockName(tl->regblock);                log_printf(", from: [cpsr %08lx, sp %08lx] ",                           tl->cur_CPSR, tl->cur_SP);                log_printf("to: [pc %08lx, cpsr %08lx, sp %08lx, r0 %08lx]\n",                           tl->rb_PC, tl->rb_CPSR, tl->rb_SP, tl->rb_r0);                logterm_flushbuf();                tl--;                ntasks--;            }        }        else            logterm_PutString("task: not a number\n");                logterm_PostWarn(0);    }    else if (argc > 2 && __rt_strcmp(argv[1], "rb") == 0)    {        int i;                logterm_PreWarn(WL_INFO);        for (i = 0; i < RB_NumRegblocks; i++)        {            if (__rt_strcmp(argv[2], rbnames[i]) == 0)            {                log_printf("Global Regblock %s:\n", rbnames[i]);                log_ShowRegblock(&Angel_GlobalRegBlock[i]);                break;            }        }        logterm_PostWarn(0);    }    else if (argc > 2 && __rt_strcmp(argv[1], "tq") == 0)    {        char *ep;        int tqi = stoi(argv[2], &ep);                logterm_PreWarn(WL_INFO);        if (ep > argv[2] && tqi >= 0 && tqi < POOLSIZE)        {            angel_TaskQueueItem *tq = &angel_TQ_Pool[tqi];                        log_ShowTaskItem(tq->n.n_type, tq);        }        else            logterm_PutString("Invalid queue index\n");                logterm_PostWarn(0);    }    return 0;}/* *  Function: log_execute *   Purpose: Accept a command string which will be split up by into *            overwriting spaces into individual strings indexed by *            an array of string pointers, to create a C library like *            argc/argv pair. Look up the command (the first such string, *            if any) in the list of known commands, and if found call *            the execution function. If the command is not found, print *            an error message ("Eh?"!!) and return. * *            Unless the command set log_deferredprompt, print a prompt *            for the user once command processing complete. * *  Pre-conditions: log_Initialise called * *    Params: *       Input: cmd - pointer to command string. *               *   Returns: nothing. */static void log_execute(char *cmd){    char *s = cmd;    char *argv[MAXARGS];    int argc, i;    for(argc = 0; argc < MAXARGS && *s != '\0';)    {        while(*s == ' ' || *s == '\t')            s++;        /*         * if quoted arg, search for end of quote;         * else search for next whitespace.         */        if (*s == '\"')        {            argv[argc++] = ++s;            while(*s != '\"' && *s != '\0')                s++;        }        else        {            argv[argc++] = s;            while(*s != ' ' && *s != '\t' && *s != '\0')                s++;        }        /*         * replace character which ended search (if not EOS)         * with EOS (to terminate this arg) and increment s         * so we can search for more...         */        if (*s == ' ' || *s == '\t' || *s == '\"')        {            *s = '\0';            s++;        }    }    argv[argc] = NULL;    if (argv[0] == NULL)        goto finish;    for (i = 0; i < log_ncmds; i++)    {        switch(__rt_strcmp(argv[0], log_cmds[i].str))        {            case 0: /* match ! */                log_cmds[i].pfn(argc, argv);                goto finish;            case -1: /* no match found */                log_emitstr("Eh? Didn't understand: ");                log_emitstr(argv[0]);                log_emitch('\n');                goto finish;                        case 1: /* still looking; */                break;        }    }finish:    if (log_deferredprompt == FALSE)        log_emitstr(PROMPT);        return;}/* main_table   "", do_nothing, 0,   "help", do_execute, helptable,   NULL,    helptable   "", do_general_help, helptable,   "stat", do_specific_help, "Print Statistics\0syntax: ..." *//* *  Function: log_serialexecute *   Purpose: Wrapper for log_execute, when that function is being called *            from the serializer. It basically maintains various locks, *            and resets the command buffer... * *  Pre-conditions: none. * *    Params: *       Input: cmd - the command to execute * *       Output: none *               *   Returns: none. */static void log_serialexecute(char *cmd){    static char buf[CMDBUFSIZE];    __rt_strcpy(buf, cmd);        log_commandbuf[0] = '\0';    log_cursor = 0;    log_buflock = FALSE;        log_emitstr("Executing: ");    log_emitstr(buf);    log_output(TRUE);        log_commandbuf[0] = '\0';    log_cursor = 0;    log_execute(buf);        log_cmdlock = FALSE;}/* *  Function: log_processchar *   Purpose: CALLED AS AN INTERRUPT ROUTINE! * *            Process a character received from the controlling *            terminal. Form a command string for execution by *            log_execute, using the serialiser to enable the *            commands to overcome the 'fast' limitation of int *            handlers. *             *            Handle some simplistic echo/deletion codes too. *             *            If log_deferredprompt is set, we must print a prompt *            before eching the character. We must also bracket *            the operation with a request to kill run time trace *            ouptut temporarily while a command is typed. * *  Pre-conditions: log_Initialise, interrupt handler set up * *    Params: *       Input: ch - the character read from the terminal *              empty-stack - passed in by the int handler for the *                            serialiser. *               *   Returns: nothing. */static void log_processchar(char ch, unsigned int empty_stack){    /* can't process -- previous command hasn't copied buffer yet */    if (log_buflock)        return;        if (log_deferredprompt)    {        log_emitstr(PROMPT);        log_output(FALSE);        log_deferredprompt = FALSE;    }        switch(ch)    {        case '\b':    /* backspace */        case '\177':  /* delete */            if (log_cursor > 0)            {                log_emitstr("\b \b"); /* delete */                log_commandbuf[log_cursor--] = '\0';                log_commandbuf[log_cursor] = '\0';            }            if (log_cursor == 0)            {                log_deferredprompt = TRUE;                log_emitstr("\b\b  \b\b"); /* length of prompt */                log_output(TRUE);            }            break;                case '\n':        case '\r':            log_emitch('\n');            if ( 1 /* empty_stack == 0*/ ) /* if called from 'pause' */            {                log_output(TRUE);                log_execute(log_commandbuf);                                log_commandbuf[0] = '\0';                log_cursor = 0;            }            else            {                /* can't execute; previous command hasn't finished yet */                if (log_cmdlock)                    break;                                /* lock buffer while we're copying it from log_commandbuf;                   lock command interp. until command completed */                log_cmdlock = TRUE;                log_buflock = TRUE;                            Angel_SerialiseTask(0,                                    (angel_SerialisedFn)log_serialexecute,                                    (void *)log_commandbuf,                                    empty_stack,                                    &Angel_GlobalRegBlock[RB_Interrupted]);            }            break;                        default:            if (ch >= 32) /* note: ch signed, so only 32-126 get through (127 above)! */            {                log_commandbuf[log_cursor++] = ch;                log_commandbuf[log_cursor] = '\0';                log_emitch(ch);                log_output(FALSE);            }            break;    }}/* *  Function: log_output *   Purpose: To enable/disable real-time trace output while commands are *            being typed. If log_tracing is TRUE, then overall we want tracing, *            while if false, we don't. log_ouptut is intended to bracket *            regions of code when trace would be a bad idea. * *  Pre-conditions: none. * *    Params: *       Input: enable          true if we're leaving a sensitive area, *                              false if entering one. * *   Returns: Nothing */static void log_output(int enable){    if (enable && log_tracing)    {        log_set_logging_options(log_get_logging_options() | WL_PRINTMSG);    }    else    {        log_set_logging_options(log_get_logging_options() & ~WL_PRINTMSG);            }}void logterm_fatalhandler(void){    log_printf("\nFatal error. Type 'help' for command list.\n");    log_printf("CPU Registers:\n");    logterm_flushbuf();    log_ShowRegblock(&Angel_GlobalRegBlock[RB_Fatal]);    log_printf("\n");    log_emitstr(PROMPT);        log_deferredprompt = FALSE;    log_paused = FALSE;    log_pause(0, 0);}/* *  Function: int_* *   Purpose: Set of handlers for the various prioritised interrupts. *              These routines do all the urgent processing required *              for the interrupt condition * *  Pre-conditions: Processor is in IRQ / FIQ mode, with a minimal stack, *                      AND NO STACK LIMIT SET UP. * *    Params: *       Input: devid           device ID of the driver *              port            serial port identifier *              empty_stack     top of the stack * *   Returns: Nothing */static void int_txrdy(unsigned int empty_stack){    unsigned int lsr;        IGNORE(empty_stack);    /*     * we really couldn't care less about these signals (in     * fact, we shouldn't really ever get this interrupt     * because it is never enabled); read the status to clear     * the interrupt and go away again     */    lsr = LOG_GET_STATUS(LOGTERM_PORT) ;}static void int_rxrdy(unsigned int empty_stack){    unsigned int intStatus ;    /*     * keep looping for as long as there are characters     * in the Rx FIFO     */    intStatus = LOG_GET_STATUS(LOGTERM_PORT) ;    if ( LOG_RX_DATA(intStatus) ) {        do {            unsigned char ch = LOG_GET_CHAR(LOGTERM_PORT);            log_processchar(ch, empty_stack);                    intStatus = LOG_GET_STATUS(LOGTERM_PORT) ;        } while ( LOG_RX_DATA(intStatus) ) ;    }}/* *  Function: angel_LogtermIntHandler *   Purpose: Entry point for interrupts from the ST16C552 UART *            See documentation for angel_IntHandlerFn in devdriv.h */void angel_LogtermIntHandler(unsigned int ident, unsigned int devid,                             unsigned int empty_stack){    unsigned int IntSource, IntStatus ;        IGNORE(ident);    IGNORE(devid);    IntSource = LOG_READ_INTERRUPT(LOGTERM_PORT) ;    if (IntSource & LOG_RX_INTERRUPT) {        int_rxrdy(empty_stack) ;       }    else if (IntSource & LOG_TX_INTERRUPT) {        int_txrdy(empty_stack) ;       }    else {        /* Unknown interrupt source */        /* clear out any errors by reading the line status register */        IntStatus = LOG_GET_STATUS(LOGTERM_PORT) ;    }}#endif /* DEBUG && !MINIMAL ANGEL *//* EOF logterm.c */

⌨️ 快捷键说明

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