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

📄 hal_if.c

📁 ecos实时嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
static voidcyg_hal_diag_mangler_gdb_putc(void* __ch_data, cyg_uint8 c){#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0    int tries = CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES;#endif    // No need to send CRs    if( c == '\r' ) return;    CYGARC_HAL_SAVE_GP();    __mangler_line[__mangler_pos++] = c;    if( c == '\n' || __mangler_pos == sizeof(__mangler_line) )	cyg_hal_diag_mangler_gdb_flush(__ch_data);    CYGARC_HAL_RESTORE_GP();}static voidcyg_hal_diag_mangler_gdb_write(void* __ch_data,                               const cyg_uint8* __buf, cyg_uint32 __len){    CYGARC_HAL_SAVE_GP();    while(__len-- > 0)        cyg_hal_diag_mangler_gdb_putc(__ch_data, *__buf++);    CYGARC_HAL_RESTORE_GP();}static voidcyg_hal_diag_mangler_gdb_read(void* __ch_data,                               cyg_uint8* __buf, cyg_uint32 __len){    CYGARC_HAL_SAVE_GP();    while(__len-- > 0)        *__buf++ = cyg_hal_diag_mangler_gdb_getc(__ch_data);    CYGARC_HAL_RESTORE_GP();}static intcyg_hal_diag_mangler_gdb_control(void *__ch_data,                                  __comm_control_cmd_t __func, ...){    CYGARC_HAL_SAVE_GP();    if (__func == __COMMCTL_FLUSH_OUTPUT)	cyg_hal_diag_mangler_gdb_flush(__ch_data);    CYGARC_HAL_RESTORE_GP();    return 0;}// This is the COMMS init function. It gets called both by the stubs// and diag init code to initialize the COMMS mangler channel table -// that's all. The callers have to decide whether to actually use this// channel.voidcyg_hal_diag_mangler_gdb_init(void){    hal_virtual_comm_table_t* comm;    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);    // Initialize mangler procs    CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_MANGLER);    comm = CYGACC_CALL_IF_CONSOLE_PROCS();    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_diag_mangler_gdb_write);    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_diag_mangler_gdb_read);    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_diag_mangler_gdb_putc);    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_diag_mangler_gdb_getc);    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_diag_mangler_gdb_control);        // Restore the original console channel.    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);}//-----------------------------------------------------------------------------// Null console output mangler// COMMS init function at end.// This gets called via the virtual vector console comms entry and// just forwards IO to the debug comms entries.// This differs from setting the console channel to the same as the// debug channel in that console output will go to the debug channel// even if the debug channel is changed.static cyg_uint8cyg_hal_diag_mangler_null_getc(void* __ch_data){    cyg_uint8 __ch;    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();    CYGARC_HAL_SAVE_GP();    __ch = CYGACC_COMM_IF_GETC(*__chan);    CYGARC_HAL_RESTORE_GP();    return __ch;}static voidcyg_hal_diag_mangler_null_putc(void* __ch_data, cyg_uint8 c){    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();    CYGARC_HAL_SAVE_GP();    CYGACC_COMM_IF_PUTC(*__chan, c);    CYGARC_HAL_RESTORE_GP();}static voidcyg_hal_diag_mangler_null_write(void* __ch_data,                                const cyg_uint8* __buf, cyg_uint32 __len){    CYGARC_HAL_SAVE_GP();    while(__len-- > 0)        cyg_hal_diag_mangler_null_putc(__ch_data, *__buf++);    CYGARC_HAL_RESTORE_GP();}static voidcyg_hal_diag_mangler_null_read(void* __ch_data,                                cyg_uint8* __buf, cyg_uint32 __len){    CYGARC_HAL_SAVE_GP();    while(__len-- > 0)        *__buf++ = cyg_hal_diag_mangler_null_getc(__ch_data);    CYGARC_HAL_RESTORE_GP();}static intcyg_hal_diag_mangler_null_control(void *__ch_data,                                   __comm_control_cmd_t __func, ...){    // Do nothing (yet).    return 0;}// This is the COMMS init function. It gets called both by the stubs// and diag init code to initialize the COMMS mangler channel table -// that's all. The callers have to decide whether to actually use this// channel.voidcyg_hal_diag_mangler_null_init(void){    hal_virtual_comm_table_t* comm;    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);    // Initialize mangler procs    CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_MANGLER);    comm = CYGACC_CALL_IF_CONSOLE_PROCS();    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_diag_mangler_null_write);    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_diag_mangler_null_read);    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_diag_mangler_null_putc);    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_diag_mangler_null_getc);    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_diag_mangler_null_control);        // Restore the original console channel.    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);}//-----------------------------------------------------------------------------// Console IO functions that adhere to the virtual vector table semantics in// order to ensure proper debug agent mangling when required.//externC void cyg_hal_plf_comms_init(void);voidhal_if_diag_init(void){    // This function may be called from various places and the code    // should only run once.    static cyg_uint8 called = 0;    if (called) return;    called = 1;#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE#if defined(CYGDBG_HAL_DIAG_TO_DEBUG_CHAN)    // Use the mangler channel, which in turn uses the debug channel.    CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_MANGLER);    // Initialize the mangler channel.#if defined(CYGSEM_HAL_DIAG_MANGLER_GDB)    cyg_hal_diag_mangler_gdb_init();#elif defined(CYGSEM_HAL_DIAG_MANGLER_None)    cyg_hal_diag_mangler_null_init();#endif#else // CYGDBG_HAL_DIAG_TO_DEBUG_CHAN    // Use an actual (raw) IO channel    CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL);#endif // CYGDBG_HAL_DIAG_TO_DEBUG_CHAN#endif // CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE}void hal_if_diag_write_char(char c){    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();    if (__chan)        CYGACC_COMM_IF_PUTC(*__chan, c);    else {        __chan = CYGACC_CALL_IF_DEBUG_PROCS();        // FIXME: What should be done if assertions are not enabled?        // This is a bad bad situation - we have no means for diag        // output; we want to hit a breakpoint to alert the developer        // or something like that.        CYG_ASSERT(__chan, "No valid channel set");        CYGACC_COMM_IF_PUTC(*__chan, c);    }    // Check interrupt flag    if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) {        CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);        cyg_hal_user_break(0);    }}void hal_if_diag_read_char(char *c){    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();        if (__chan)        *c = CYGACC_COMM_IF_GETC(*__chan);    else {        __chan = CYGACC_CALL_IF_DEBUG_PROCS();        // FIXME: What should be done if assertions are not enabled?        // This is a bad bad situation - we have no means for diag        // output; we want to hit a breakpoint to alert the developer        // or something like that.        CYG_ASSERT(__chan, "No valid channel set");        *c = CYGACC_COMM_IF_GETC(*__chan);    }}#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG//=============================================================================// CtrlC support//=============================================================================#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \    || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)struct Hal_SavedRegisters *hal_saved_interrupt_state;voidhal_ctrlc_isr_init(void){    // A ROM monitor never enables the interrupt itself. This is left    // to the (RAM) application.#ifndef CYGSEM_HAL_ROM_MONITOR    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();#if 1 // Prevents crash on older stubs    int v_m;    // Allow only ctrl-c interrupt enabling when version in table is    // below legal max and above the necessary service, and _not_    // the value we set it to below.    v_m = CYGACC_CALL_IF_VERSION() & CYGNUM_CALL_IF_TABLE_VERSION_CALL_MASK;    if (v_m >= CYGNUM_CALL_IF_TABLE_VERSION_CALL_MAX         || v_m < CYGNUM_CALL_IF_SET_DEBUG_COMM        || v_m == CYGNUM_CALL_IF_TABLE_VERSION_CALL_HACK)        return;    // Now trash that value - otherwise downloading an image with    // builtin stubs on a board with older stubs (which will cause the    // version to be set to VERSION_CALL) may cause all subsequent    // runs to (wrongly) fall through to the below code.  If there is    // a new stub on the board, it will reinitialize the version field    // on reset.  Yes, this is a gross hack!    CYGACC_CALL_IF_VERSION_SET(CYGNUM_CALL_IF_TABLE_VERSION_CALL_HACK);#endif    // We can only enable interrupts on a valid debug channel.    if (__chan)        CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_ENABLE);#endif}cyg_uint32hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data){    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();    int isr_ret = 0, ctrlc = 0;    if (__chan) {        isr_ret = CYGACC_COMM_IF_DBG_ISR(*__chan, &ctrlc, vector, data);        if (ctrlc)            cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state );    }    return isr_ret;}cyg_boolhal_ctrlc_check(CYG_ADDRWORD vector, CYG_ADDRWORD data){    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();    int gdb_vector = vector-1;    int isr_ret, ctrlc = 0;    // This check only to avoid crash on older stubs in case of unhandled    // interrupts. It is a bit messy, but required in a transition period.    if (__chan &&         (CYGNUM_CALL_IF_TABLE_VERSION_CALL_HACK ==          (CYGACC_CALL_IF_VERSION() & CYGNUM_CALL_IF_TABLE_VERSION_CALL_MASK))){        gdb_vector = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DBG_ISR_VECTOR);    }    if (vector == gdb_vector) {        isr_ret = CYGACC_COMM_IF_DBG_ISR(*__chan, &ctrlc, vector, data);        if (ctrlc) {            cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state );            return true;        }    }    return false;}#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT || CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT//--------------------------------------------------------------------------// Init function. It should be called from the platform initialization code.// For monitor configurations it will initialize the calling interface table,// for client configurations it will patch the existing table as per// configuration.voidhal_if_init(void){    //**********************************************************************    //    // Note that if your RAM application is configured to initialize    // the whole table _or_ the communication channels, you _cannot_    // step through this function with the debugger. If your channel    // configurations are set to the default, you should be able to    // simply step over this function though (or use 'finish' once you    // have entered this function if that GDB command works).    //     // If you really do need to debug this code, the best approach is    // to have a working RedBoot / GDB stub in ROM and then change the    // hal_virtual_vector_table to reside at some other address in the    // RAM configuration than that used by the ROM monitor.  Then    // you'll be able to use the ROM monitor to debug the below code    // and check that it does the right thing.    //    // Note that if you have a ROM monitor in ROM/flash which does    // support virtual vectors, you should be able to disable the    // option CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE. On some    // targets (which predate the introduction of virtual vectors)    // that option is enabled per default and needs to be explicitly    // disabled when you have an updated ROM monitor.    //    //**********************************************************************#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE    {        int i;        // Initialize tables with the NOP service.        // This should only be done for service routine entries - data        // pointers should be NULLed.        for (i = 0; i < CYGNUM_CALL_IF_TABLE_SIZE; i++)            hal_virtual_vector_table[i] = (CYG_ADDRWORD) &nop_service;                // Version number        CYGACC_CALL_IF_VERSION_SET(CYGNUM_CALL_IF_TABLE_VERSION_CALL            |((CYG_ADDRWORD)CYGNUM_CALL_IF_TABLE_VERSION_COMM<<CYGNUM_CALL_IF_TABLE_VERSION_COMM_shift));    }#endif    // Miscellaneous services with wrappers in this file.#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_RESET    CYGACC_CALL_IF_RESET_SET(reset);    CYGACC_CALL_IF_KILL_VECTOR_SET(kill_by_reset);#endif#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DELAY_US    CYGACC_CALL_IF_DELAY_US_SET(delay_us);#endif#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_CACHE    // Cache functions    CYGACC_CALL_IF_FLUSH_ICACHE_SET(flush_icache);    CYGACC_CALL_IF_FLUSH_DCACHE_SET(flush_dcache);#endif#ifdef CYGSEM_REDBOOT_FLASH_CONFIG    CYGACC_CALL_IF_FLASH_CFG_OP_SET(flash_config_op);#endif    // Data entries not currently supported in eCos#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DATA    CYGACC_CALL_IF_DBG_DATA_SET(0);#endif#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_VERSION    CYGACC_CALL_IF_MONITOR_VERSION_SET(0);#endif    // Comm controls#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_COMMS    {        int i, j;        // Clear out tables with safe dummy function.        for (j = 0; j < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS+1; j++)            for (i = 0; i < CYGNUM_COMM_IF_TABLE_SIZE; i++)                comm_channels[j][i] = (CYG_ADDRWORD) &nop_service;        // Set accessor functions        CYGACC_CALL_IF_SET_DEBUG_COMM_SET(set_debug_comm);        CYGACC_CALL_IF_SET_CONSOLE_COMM_SET(set_console_comm);        // Initialize console/debug procs. Note that these _must_        // be set to empty before the comms init call.        set_debug_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY);        set_console_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY);        // Initialize channels. This used to be done in        // hal_diag_init() and the stub initHardware() functions, but        // it makes more sense to have here.        cyg_hal_plf_comms_init();        // Always set the debug channel. If stubs are included, it is        // necessary. If no stubs are included it does not hurt and is        // likely to be required by the hal_if_diag_init code anyway        // as it may rely on it if using a mangler.        set_debug_comm(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);        // Set console channel to a safe default. hal_if_diag_init        // will override with console channel or mangler if necessary.        set_console_comm(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);    }    // Reset console interrupt flag.    CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);#endif    // Set up services provided by clients#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)   &&  \    ( defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) \      || defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon))    patch_dbg_syscalls( (void *)(hal_virtual_vector_table) );#endif    // Init client services#if !defined(CYGPKG_KERNEL) && defined(CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT)    // Only include this code if we do not have a kernel. Otherwise    // the kernel supplies the functionality for the app we are linked    // with.    // Prepare for application installation of thread info function in    // vector table.    init_thread_syscall( (void *)&hal_virtual_vector_table[CYGNUM_CALL_IF_DBG_SYSCALL] );#endif    // Finally, install async breakpoint handler if it is configured in.    // FIXME: this should probably check for STUBS instead (but code is    //        conditional on BREAK for now)#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)    // Install async breakpoint handler into vector table.    CYGACC_CALL_IF_INSTALL_BPT_FN_SET(&cyg_hal_gdb_interrupt);#endif#if 0 != CYGINT_HAL_PLF_IF_INIT    // Call platform specific initializations - should only be used    // to augment what has already been set up, etc.    plf_if_init();#endif}

⌨️ 快捷键说明

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