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

📄 logterm.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
                log_showitems(&savebuf, lines); 
                log_output(TRUE);
            } 
            else 
                log_emitstr("trace: Bad number.\n"); 
        } 
        else if (strcmp(argv[1], "on") == 0)
        {
            log_emitstr("trace: on (was: "); 
            log_emitstr(log_tracing ? "on)\n" : "off)\n"); 
            log_tracing = TRUE;
        }
        else if (strcmp(argv[1], "off") == 0)
        {
            log_emitstr("trace: off (was: "); 
            log_emitstr(log_tracing ? "on)\n" : "off)\n"); 
            log_tracing = FALSE;
        }
        else
        {
            for(i = 1; i < argc; i++)
            {
                log_id id;

                if (argv[i][0] == '-')
                    rem = TRUE, p = argv[i]+1;
                else if (argv[i][0] == '+')
                    rem = FALSE, p = argv[i]+1;
                else
                    rem = FALSE, p = argv[i];

                id = log_tracebit(p);
                if (id != 0)
                {
                    log_set_log_id(id, !rem);
                }
                else
                {
                    log_emitstr("trace: unknown module ");
                    log_emitstr(p);
                    log_emitch('\n');
                }
            }
        }
    }
    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(strcmp(argv[0], log_cmds[i].str))
        {
            case 0: /* match ! */
                log_cmds[i].pfn(argc, argv);
                break;

            case -1: /* no match found */
                log_emitstr("Eh?\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];

    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 (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);
            }
            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);        
    }
}


/*
 *  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
 *
 *              serchip            address of the controller for the given port
 *
 *              empty_stack     top of the stack
 *
 *   Returns: Nothing
 */

static void int_msr(unsigned int devid,
                    unsigned int port,
                    ST16C552Reg *const serchip,
                    unsigned int empty_stack)
{
    unsigned int msr;

    UNUSED(empty_stack);
    UNUSED(port);
    UNUSED(devid);

    /*
     * 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
     */
    msr = serchip->msr;
}

static void int_txrdy(unsigned int devid,
                      unsigned int port,
                      ST16C552Reg *const serchip,
                      unsigned int empty_stack)
{
    unsigned int lsr;

    UNUSED(empty_stack);
    UNUSED(port);
    UNUSED(devid);

    /*
     * 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 = serchip->msr;
}

static void int_rxrdy(unsigned int devid,
                      unsigned int port,
                      ST16C552Reg *const serchip,
                      unsigned int empty_stack)
{
    UNUSED(devid);
    UNUSED(port);
    UNUSED(empty_stack);

    /*
     * keep looping for as long as there are characters
     * in the Rx FIFO
     */
    while (!st16c552_RxBuffEmpty(serchip))
    {
        unsigned char ch = st16c552_GetChar(serchip);
        log_processchar(ch, empty_stack);
    }
}

static void int_lsr(unsigned int devid,
                    unsigned int port,
                    ST16C552Reg *const serchip,
                    unsigned int empty_stack)
{
    unsigned int lsr;

    IGNORE(devid);
    IGNORE(empty_stack);
    UNUSED(port);

    lsr = serchip->lsr;
}

/*
 *  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)
{
    /*
     * jump table for prioritised interrupts
     */
    static void (*const intjump[4])(const unsigned int devid,
                                    const unsigned int port,
                                    ST16C552Reg *const serchip,
                                    const unsigned int empty_stack) =
    {
        int_msr, int_txrdy, int_rxrdy, int_lsr
    };
    
    unsigned int intsrc;
    const unsigned int port = SerCtrl(devid)->port;
    ST16C552Reg *const serchip = (port == ST16C552_IDENT_A) ?
        (ST16C552Reg *)NISA_SER_A : (ST16C552Reg *)NISA_SER_B;
    
    IGNORE(ident);

    /*
     * we are only interested in the first three bits of the
     * ISR: bit 0 signals whether another Int. is pending,
     * bits 1-2 indicate the prioritised interrupt; bit 3 is
     * only used to differentiate between a FIFO triggered
     * RxRDY Int and a character timeout RxRDY Int, and we
     * are not interested in this difference
     */
    while (((intsrc = (serchip->isr & 0x07)) & 0x01) == 0)
        intjump[intsrc >> 1](devid, port, serchip, empty_stack);
}

#endif /* DEBUG && !MINIMAL ANGEL */

/* EOF logterm.c */

⌨️ 快捷键说明

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