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); } }
static void net_io_flush(void) { int n; char *bp = out_buf; #ifdef DEBUG_TCP if (show_tcp) { int old_console; old_console = start_console(); diag_printf("%s.%d\n", __FUNCTION__, __LINE__); diag_dump_buf(out_buf, out_buflen); end_console(old_console); } #endif // SHOW_TCP n = __tcp_write_block(&tcp_sock, bp, out_buflen); if (n < 0) { // The connection is gone! net_io_revert_console(); } else { out_buflen -= n; bp += n; } out_bufp = out_buf; out_buflen = 0; // Check interrupt flag if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) { CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0); cyg_hal_user_break(0); } }
//-------------------------------------------------------------------------- // 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. void hal_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); #endif #ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DELAY_US CYGACC_CALL_IF_DELAY_US_SET(delay_us); #endif #ifdef CYGSEM_REDBOOT_FLASH_CONFIG CYGACC_CALL_IF_FLASH_CFG_OP_SET(flash_config_op); #endif #ifdef CYGOPT_REDBOOT_FIS CYGACC_CALL_IF_FLASH_FIS_OP_SET(flash_fis_op); CYGACC_CALL_IF_FLASH_FIS_OP2_SET(flash_fis_op2); #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 }
static void cyg_hal_diag_mangler_gdb_flush(void* __ch_data) { CYG_INTERRUPT_STATE old; hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS(); #if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0 int tries = CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES; #endif // Nothing to do if mangler buffer is empty. if (__mangler_pos == 0) return; // Disable interrupts. This prevents GDB trying to interrupt us // while we are in the middle of sending a packet. The serial // receive interrupt will be seen when we re-enable interrupts // later. #if defined(CYG_HAL_STARTUP_ROM) \ || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION) HAL_DISABLE_INTERRUPTS(old); #else CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old); #endif #if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0 // Only wait 500ms for data to arrive - avoid "stuck" connections CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, CYGNUM_HAL_DEBUG_GDB_PROTOCOL_TIMEOUT); #endif while(1) { static const char hex[] = "0123456789ABCDEF"; cyg_uint8 csum = 0; char c1; int i; CYGACC_COMM_IF_PUTC(*__chan, '$'); CYGACC_COMM_IF_PUTC(*__chan, 'O'); csum += 'O'; for( i = 0; i < __mangler_pos; i++ ) { char ch = __mangler_line[i]; char h = hex[(ch>>4)&0xF]; char l = hex[ch&0xF]; CYGACC_COMM_IF_PUTC(*__chan, h); CYGACC_COMM_IF_PUTC(*__chan, l); csum += h; csum += l; } CYGACC_COMM_IF_PUTC(*__chan, '#'); CYGACC_COMM_IF_PUTC(*__chan, hex[(csum>>4)&0xF]); CYGACC_COMM_IF_PUTC(*__chan, hex[csum&0xF]); nak: #if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0 if (CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, &c1) == 0) { c1 = '-'; if (tries && (--tries == 0)) c1 = '+'; } #else c1 = CYGACC_COMM_IF_GETC(*__chan); #endif if( c1 == '+' ) break; if( cyg_hal_is_break( &c1 , 1 ) ) { // Caller's responsibility to react on this. CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(1); break; } if( c1 != '-' ) goto nak; } __mangler_pos = 0; // And re-enable interrupts #if defined(CYG_HAL_STARTUP_ROM) \ || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION) HAL_RESTORE_INTERRUPTS(old); #else CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old); #endif }