main.c

来自「eCos操作系统源码」· C语言 代码 · 共 759 行 · 第 1/2 页

C
759
字号
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS            if (res == _GETS_GDB) {		int dbgchan;                hal_virtual_comm_table_t *__chan;                int i;                // Special case of '$' - need to start GDB protocol                gdb_active = true;                // Mask interrupts on all channels                for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS;  i++) {                    CYGACC_CALL_IF_SET_CONSOLE_COMM(i);                    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();                    CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );                }                    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);                // set up a temporary context that will take us to the trampoline                HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end,                                        breakpoint, trampoline, 0);                // switch context to trampoline (get GDB stubs started)                HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);                gdb_active = false;		dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);		CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);            } else #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS            {                expand_aliases(line, sizeof(line));		command = (char *)&line;                if ((*command == '#') || (*command == '=')) {                    // Special cases                    if (*command == '=') {                        // Print line on console                        diag_printf("%s\n", &line[2]);                    }                } else {                    while (strlen(command) > 0) {                                            if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {                            // Try to handle aborts - messy because of the stack unwinding...                            __mem_fault_handler = error_handler;                            if (hal_setjmp(error_jmpbuf)) {                                diag_printf("** command abort - illegal memory access?\n");                            } else {                                (cmd->fun)(argc, argv);                            }                            __mem_fault_handler = 0;                        } else {                            diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);                        }                    }                }                prompt = true;            }        }    }}voidshow_help(struct cmd *cmd, struct cmd *cmd_end, char *which, char *pre){    bool show;    int len = 0;    if (which) {        len = strlen(which);    }    while (cmd != cmd_end) {        show = true;        if (which && (strncasecmp(which, cmd->str, len) != 0)) {            show = false;        }        if (show) {            diag_printf("%s\n  %s %s %s\n", cmd->help, pre, cmd->str, cmd->usage);            if ((cmd->sub_cmds != (struct cmd *)0) && (which != (char *)0)) {                show_help(cmd->sub_cmds, cmd->sub_cmds_end, 0, cmd->str);            }        }        cmd++;    }}voiddo_help(int argc, char *argv[]){    struct cmd *cmd;    char *which = (char *)0;    if (!scan_opts(argc, argv, 1, 0, 0, (void *)&which, OPTION_ARG_TYPE_STR, "<topic>")) {        diag_printf("Invalid argument\n");        return;    }    cmd = __RedBoot_CMD_TAB__;    show_help(cmd, &__RedBoot_CMD_TAB_END__, which, "");    return;}static voidtrampoline(unsigned long entry){    typedef void code_fun(void);    code_fun *fun = (code_fun *)entry;    unsigned long oldints;    HAL_DISABLE_INTERRUPTS(oldints);#ifdef HAL_ARCH_PROGRAM_NEW_STACK    HAL_ARCH_PROGRAM_NEW_STACK(fun);#else    (*fun)();#endif    HAL_THREAD_LOAD_CONTEXT(&saved_context);}static voidreturn_to_redboot(int status){    CYGARC_HAL_SAVE_GP();    return_status = status;    HAL_THREAD_LOAD_CONTEXT(&saved_context);    // never returns    // need this to balance above CYGARC_HAL_SAVE_GP on    // some platforms. It will never run, though.    CYGARC_HAL_RESTORE_GP();}voiddo_go(int argc, char *argv[]){    int i, cur, num_options;    unsigned long entry;    unsigned long oldints;    bool wait_time_set;    int  wait_time, res;    bool cache_enabled = false;#ifdef CYGPKG_IO_ETH_DRIVERS    bool stop_net = false;#endif    struct option_info opts[3];    char line[8];    hal_virtual_comm_table_t *__chan;    __mem_fault_handler = 0; // Let GDB handle any faults directly    entry = entry_address;  // Default from last 'load' operation    init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,               (void *)&wait_time, (bool *)&wait_time_set, "wait timeout");    init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG,               (void *)&cache_enabled, (bool *)0, "go with caches enabled");    num_options = 2;#ifdef CYGPKG_IO_ETH_DRIVERS    init_opts(&opts[2], 'n', false, OPTION_ARG_TYPE_FLG,               (void *)&stop_net, (bool *)0, "go with network driver stopped");    num_options++;#endif    CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options");    if (!scan_opts(argc, argv, 1, opts, num_options, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))    {        return;    }    if (entry == (unsigned long)NO_MEMORY) {        diag_printf("No entry point known - aborted\n");        return;    }    if (wait_time_set) {        int script_timeout_ms = wait_time * 1000;#ifdef CYGSEM_REDBOOT_FLASH_CONFIG        unsigned char *hold_script = script;        script = (unsigned char *)0;#endif        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",                    (void *)entry, wait_time);        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);            if (res == _GETS_CTRLC) {#ifdef CYGSEM_REDBOOT_FLASH_CONFIG                script = hold_script;  // Re-enable script#endif                return;            }            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;        }    }    // Mask interrupts on all channels    cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);    for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS;  i++) {	CYGACC_CALL_IF_SET_CONSOLE_COMM(i);	__chan = CYGACC_CALL_IF_CONSOLE_PROCS();	CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );    }    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);#ifdef CYGPKG_IO_ETH_DRIVERS    if (stop_net)	eth_drv_stop();#endif	    HAL_DISABLE_INTERRUPTS(oldints);    HAL_DCACHE_SYNC();    if (!cache_enabled) {	HAL_ICACHE_DISABLE();	HAL_DCACHE_DISABLE();	HAL_DCACHE_SYNC();    }    HAL_ICACHE_INVALIDATE_ALL();    HAL_DCACHE_INVALIDATE_ALL();    // set up a temporary context that will take us to the trampoline    HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, trampoline, 0);    // switch context to trampoline    HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);    // we get back here by way of return_to_redboot()    // undo the changes we made before switching context    if (!cache_enabled) {	HAL_ICACHE_ENABLE();	HAL_DCACHE_ENABLE();    }    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH);    HAL_RESTORE_INTERRUPTS(oldints);    diag_printf("\nProgram completed with status %d\n", return_status);}#ifdef HAL_PLATFORM_RESETvoiddo_reset(int argc, char *argv[]){    diag_printf("... Resetting.");    CYGACC_CALL_IF_DELAY_US(2*100000);    diag_printf("\n");    CYGACC_CALL_IF_RESET();    diag_printf("!! oops, RESET not working on this platform\n");}#endif#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE#ifdef CYGSEM_REDBOOT_FLASH_CONFIG#include <flash_config.h>#endifstatic intset_comm_baud_rate(hal_virtual_comm_table_t *chan, int rate){    int current_rate;    current_rate = CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_GETBAUD);    if (rate != current_rate)        return CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate);    return 0;}intset_console_baud_rate(int rate){    int ret = -1;#ifdef CYGPKG_REDBOOT_ANY_CONSOLE    if (!console_selected) {        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);        int i;        // Set baud for all channels        for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;  i++) {            CYGACC_CALL_IF_SET_CONSOLE_COMM(i);	    ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);	    if (ret < 0)		break;        }        CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);    } else#endif    ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);    if (ret < 0)	diag_printf("Setting console baud rate to %d failed\n", rate);    return ret;}static void_sleep(int ms){    int i;    for (i = 0;  i < ms;  i++) {        CYGACC_CALL_IF_DELAY_US((cyg_int32)1000);    }}voiddo_baud_rate(int argc, char *argv[]){    int new_rate, ret, old_rate;    bool new_rate_set;    hal_virtual_comm_table_t *__chan;    struct option_info opts[1];#ifdef CYGSEM_REDBOOT_FLASH_CONFIG    struct config_option opt;#endif    init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,               (void *)&new_rate, (bool *)&new_rate_set, "new baud rate");    if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) {        return;    }    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();    if (new_rate_set) {        diag_printf("Baud rate will be changed to %d - update your settings\n", new_rate);        _sleep(500);  // Give serial time to flush        old_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);        ret = set_console_baud_rate(new_rate);        if (ret < 0) {            if (old_rate > 0) {                // Try to restore                set_console_baud_rate(old_rate);                _sleep(500);  // Give serial time to flush                diag_printf("\nret = %d\n", ret);            }            return;  // Couldn't set the desired rate        }        // Make sure this new rate works or back off to previous value        // Sleep for a few seconds, then prompt to see if it works        _sleep(3000);  // Give serial time to flush        if (!verify_action_with_timeout(5000, "Baud rate changed to %d", new_rate)) {            _sleep(500);  // Give serial time to flush            set_console_baud_rate(old_rate);            _sleep(500);  // Give serial time to flush            return;        }#ifdef CYGSEM_REDBOOT_FLASH_CONFIG        opt.type = CONFIG_INT;        opt.enable = (char *)0;        opt.enable_sense = 1;        opt.key = "console_baud_rate";        opt.dflt = new_rate;        flash_add_config(&opt, true);#endif    } else {        ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);        diag_printf("Baud rate = ");        if (ret <= 0) {            diag_printf("unknown\n");        } else {            diag_printf("%d\n", ret);        }    }}#endif//// Validate an address to see if it is within any known RAM area//boolvalid_address(unsigned char *addr){    int seg;    for (seg = 0;  seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS;  seg++) {        if (mem_segments[seg].start != NO_MEMORY) {            if ((addr >= mem_segments[seg].start) && (addr < mem_segments[seg].end)) {                return true;            }        }    }    return false;}

⌨️ 快捷键说明

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