hal_diag.c
来自「eCos操作系统源码」· C语言 代码 · 共 621 行 · 第 1/2 页
C
621 行
{ int delay_count; channel_data_t* chan = (channel_data_t*)__ch_data; cyg_bool res; CYGARC_HAL_SAVE_GP(); delay_count = chan->msec_timeout * 10; // delay in .1 ms steps for(;;) { res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch); if (res || 0 == delay_count--) break; CYGACC_CALL_IF_DELAY_US(100); } CYGARC_HAL_RESTORE_GP(); return res;}static intcyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...){ static int irq_state = 0; channel_data_t* chan = (channel_data_t*)__ch_data; int ret = 0; CYGARC_HAL_SAVE_GP(); switch (__func) { case __COMMCTL_GETBAUD: ret = chan->baud_rate; break; case __COMMCTL_SETBAUD: { va_list ap; va_start(ap, __func); ret = chan->baud_rate; chan->baud_rate = va_arg(ap, cyg_int32); init_serial_channel(chan); va_end(ap); } break; case __COMMCTL_IRQ_ENABLE: HAL_INTERRUPT_SET_LEVEL(chan->imb3_vector, chan->level); HAL_INTERRUPT_UNMASK(chan->imb3_vector); HAL_INTERRUPT_UNMASK(chan->siu_vector); irq_state = 1; break; case __COMMCTL_IRQ_DISABLE: ret = irq_state; irq_state = 0; HAL_INTERRUPT_MASK(chan->imb3_vector); HAL_INTERRUPT_MASK(chan->siu_vector); break; case __COMMCTL_DBG_ISR_VECTOR: ret = chan->siu_vector; break; case __COMMCTL_SET_TIMEOUT: { va_list ap; va_start(ap, __func); ret = chan->msec_timeout; chan->msec_timeout = va_arg(ap, cyg_uint32); va_end(ap); } break; default: break; } CYGARC_HAL_RESTORE_GP(); return ret;}static intcyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, CYG_ADDRWORD __vector, CYG_ADDRWORD __data){ int res = 0; cyg_uint16 status; cyg_uint16 control; cyg_uint16 * base = ((channel_data_t *)__ch_data)->base; CYGARC_HAL_SAVE_GP(); *__ctrlc = 0; HAL_READ_UINT16(base+CYG_DEV_SERIAL_RS232_SCSR, status); HAL_READ_UINT16(base+CYG_DEV_SERIAL_RS232_SCCR1, control); if((status & SCSR_RDRF) && (control & SCCR1_RIE)) { // Only if the interrupt was caused by the channel cyg_uint8 c; c = cyg_hal_plf_serial_getc(__ch_data); if(cyg_hal_is_break(&c, 1)) *__ctrlc = 1; HAL_INTERRUPT_ACKNOWLEDGE(((channel_data_t *)__ch_data)->imb3_vector); res = CYG_ISR_HANDLED; } CYGARC_HAL_RESTORE_GP(); return res;}static voidcyg_hal_plf_serial_init(void){ hal_virtual_comm_table_t* comm; int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); // Disable interrupts. HAL_INTERRUPT_MASK(channels[0].imb3_vector); HAL_INTERRUPT_MASK(channels[1].imb3_vector); // Init channels init_serial_channel(&channels[0]); init_serial_channel(&channels[1]); // Setup procs in the vector table // Set channel 0 CYGACC_CALL_IF_SET_CONSOLE_COMM(0); comm = CYGACC_CALL_IF_CONSOLE_PROCS(); CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[0]); CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr); CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout); // Set channel 1 CYGACC_CALL_IF_SET_CONSOLE_COMM(1); comm = CYGACC_CALL_IF_CONSOLE_PROCS(); CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[1]); CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr); CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout); // Restore original console CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);}//=============================================================================// Compatibility with older stubs//=============================================================================#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)#include <cyg/hal/hal_stub.h> // CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION#endif//-----------------------------------------------------------------------------// Assumption: all diagnostic output must be GDB packetized unless// this is a configuration for a stand-alone ROM system.#if defined(CYG_HAL_STARTUP_ROM) && !defined(CYGSEM_HAL_ROM_MONITOR)# define HAL_DIAG_USES_HARDWARE#endif#if (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 0)# define __BASE ((cyg_uint16*)CYG_DEV_SERIAL_BASE_A)#elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 1)# define __BASE ((cyg_uint16*)CYG_DEV_SERIAL_BASE_B)#else# error "LCD driver not (yet) implemented for cme555"#endifstatic channel_data_t channel = { __BASE, 0, 0 };#ifdef HAL_DIAG_USES_HARDWAREvoid hal_diag_init(void){ init_serial_channel(&channel);}void hal_diag_write_char(char __c){ cyg_hal_plf_serial_putc(&channel, __c);}void hal_diag_read_char(char *c){ *c = cyg_hal_plf_serial_getc(&channel);}#else // ifdef HAL_DIAG_USES_HARDWARE// Initialize diag portvoidhal_diag_init(void){ // Init devices init_serial_channel(&channel);}void hal_diag_write_char_serial( char c ){ unsigned long __state; HAL_DISABLE_INTERRUPTS(__state); cyg_hal_plf_serial_putc(&channel, c); HAL_RESTORE_INTERRUPTS(__state);}voidhal_diag_read_char(char *c){ *c = cyg_hal_plf_serial_getc(&channel);}void hal_diag_write_char(char c){ static char line[100]; static int pos = 0; // No need to send CRs if( c == '\r' ) return; line[pos++] = c; if( c == '\n' || pos == sizeof(line) ) { CYG_INTERRUPT_STATE old; // 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. #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);#else HAL_DISABLE_INTERRUPTS(old);#endif while(1) { char c1; static char hex[] = "0123456789ABCDEF"; cyg_uint8 csum = 0; int i; hal_diag_write_char_serial('$'); hal_diag_write_char_serial('O'); csum += 'O'; for( i = 0; i < pos; i++ ) { char ch = line[i]; char h = hex[(ch>>4)&0xF]; char l = hex[ch&0xF]; hal_diag_write_char_serial(h); hal_diag_write_char_serial(l); csum += h; csum += l; } hal_diag_write_char_serial('#'); hal_diag_write_char_serial(hex[(csum>>4)&0xF]); hal_diag_write_char_serial(hex[csum&0xF]); // Wait for the ACK character '+' from GDB here and handle // receiving a ^C instead. hal_diag_read_char(&c1); if( c1 == '+' ) break; // a good acknowledge#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT if( 3 == c1 ) { // Ctrl-C: breakpoint. cyg_hal_gdb_interrupt( (target_register_t)__builtin_return_address(0)); break; }#endif // otherwise, loop round again } pos = 0; // And re-enable interrupts#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);#else HAL_RESTORE_INTERRUPTS(old);#endif }}#endif // ifdef HAL_DIAG_USES_HARDWARE#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG//-----------------------------------------------------------------------------// End of hal_diag.c
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?