完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我们正在尝试使用 UART0 进行日志记录 (os_printf),并使用 UART1 与其他串行设备进行通信。我们观察到,当我们通过 UART1 发送数据时os_printf通过 UART0 消息输出数据时os_printf UART1 也在进行。
我们正在使用 tx_buff_enq() api 在 UART0 上发送数据,并为 UART1 发送os_printf数据。当我们通过 tx_buff_enq() 发送数据时,通常会在此 API 之前打印一条os_printf消息,在调用 tx_buff_enq 时传输到 UART0。 UART0 和 UART1 之间是否共享 Tx 缓冲区?看起来在 UART1(通过 os_printf)上发送数据时未完成,我们开始在 UART0 上传输,这导致 Last os_printf 字符串与 UART0 混淆。请告知如何解决问题? SDK:NONOS 2.0 下面提供了 uart.c 文件中的代码 /* * File : uart.c * Copyright (C) 2013 - 2016, Espressif Systems * * This program is free software: you can redistribute it and/or modify * it under the terms of version 3 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "ets_sys.h" #include "osapi.h" #include "driver/uart.h" #include "osapi.h" #include "driver/uart_register.h" #include "mem.h" #include "os_type.h" UartDev 在 rom 代码中定义和初始化。 extern UartDevice UartDev; 本地结构 UartBuffer* pTxBuffer = NULL; 本地结构 UartBuffer* pRxBuffer = NULL; /*带有系统任务的 UART 演示,输出 UART 接收的内容*/ /*这是处理任务中的UART数据的示例,如果存在,请更改优先级以适合您的应用程序任务*/ /*it might conflict with your task, if so,please arrange the priority of different task, or combine it to a different event in the same task. */ #define uart_recvTaskPrio 0 #define uart_recvTaskQueueLen 10 os_event_t uart_recvTaskQueue[uart_recvTaskQueueLen]; #define DBG #define DBG1 uart1_sendStr_no_wait #define DBG2 os_printf LOCAL 无效 uart0_rx_intr_handler(void *para); /****************************************************************************** * FunctionName : uart_config * Description : Internal used function * UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled * UART1 just used for debug output * Parameters : uart_no, use UART0 or UART1 defined ahead * Returns : NONE *******************************************************************************/ LOCAL 无效ICACHE_FLASH_ATTR uart_config(uint8 uart_no) { if (uart_no == UART1){ PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); }else{ /* rcv_buff size if 0x100 */ ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff)); PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); #if UART_HW_RTS PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); //HW FLOW CONTROL RTS PIN #endif #if UART_HW_CTS PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_U0CTS); //HW FLOW CONTROL CTS PIN #endif } uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));//SET BAUDRATE WRITE_PERI_REG(UART_CONF0(uart_no), ((UartDev.exist_parity & UART_PARITY_EN_M) << UART_PARITY_EN_S) //SET BIT AND PARITY MODE | ((UartDev.parity & UART_PARITY_M) <> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { break; } } WRITE_PERI_REG(UART_FIFO(uart) , TxChar); return OK; } /****************************************************************************** * FunctionName : uart1_write_char * Description : Internal used function * Do some special deal while tx char is 'r' or 'n' * Parameters : char c - character to tx * Returns : NONE *******************************************************************************/ LOCAL 无效ICACHE_FLASH_ATTR uart1_write_char(字符 C) { if (c == 'n'){ uart_tx_one_char(UART1, 'r'); uart_tx_one_char(UART1, 'n'); }else if (c == 'r'){ }else{ uart_tx_one_char(UART1, c); } } os_printf输出到 FIFO 或 TX 缓冲器 LOCAL 无效ICACHE_FLASH_ATTR uart0_write_char_no_wait(字符 c) { #if UART_BUFF_EN //send to uart0 fifo but do not wait uint8 chr; if (c == 'n'){ chr = 'r'; tx_buff_enq(&chr, 1); chr = 'n'; tx_buff_enq(&chr, 1); }else if (c == 'r'){ }else{ tx_buff_enq(&c,1); } #else //send to uart tx buffer if (c == 'n'){ uart_tx_one_char_no_wait(UART0, 'r'); uart_tx_one_char_no_wait(UART0, 'n'); }else if (c == 'r'){ } else{ uart_tx_one_char_no_wait(UART0, c); } #endif } /****************************************************************************** * FunctionName : uart0_tx_buffer * Description : use uart0 to transfer buffer * Parameters : uint8 *buf - point to send buffer * uint16 len - buffer len * Returns : *******************************************************************************/ 无效ICACHE_FLASH_ATTR uart0_tx_buffer(uint8 *buf, uint16 len) { uint16 i; for (i = 0; i < len; i++) { uart_tx_one_char(UART0, buf); } } /****************************************************************************** * FunctionName : uart0_sendStr * Description : use uart0 to transfer buffer * Parameters : uint8 *buf - point to send buffer * uint16 len - buffer len * Returns : *******************************************************************************/ 无效ICACHE_FLASH_ATTR uart0_sendStr(常量字符 *str) { while(*str){ uart_tx_one_char(UART0, *str++); } } void at_port_print(const char *str) __attribute__((alias("uart0_sendStr"))); /****************************************************************************** * FunctionName : uart0_rx_intr_handler * Description : Internal used function * UART0 interrupt handler, add self handle code inside * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg * Returns : NONE *******************************************************************************/ LOCAL 无效 uart0_rx_intr_handler(void *para) { /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents * uart1 and uart0 respectively */ uint8 RcvChar; uint8 uart_no = UART0;//UartDev.buff_uart_no; uint8 fifo_len = 0; uint8 buf_idx = 0; uint8 temp,cnt; //RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para; /*ATTENTION:*/ /*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/ /*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */ /*IF NOT , POST AN EVENT AND PROCESS IN SYSTEM TASK */ if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)){ DBG1("FRM_ERRrn"); WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR); }else if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)){ DBG("f"); uart_rx_intr_disable(UART0); WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR); system_os_post(uart_recvTaskPrio, 0, 0); }else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)){ DBG("t"); uart_rx_intr_disable(UART0); WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR); system_os_post(uart_recvTaskPrio, 0, 0); }else if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST)){ DBG("e"); /* to output uart data from uart buffer directly in empty interrupt handler*/ /*instead of processing in system event, in order not to wait for current task/function to quit */ /*ATTENTION:*/ /*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/ /*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */ CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); #if UART_BUFF_EN tx_start_uart_buffer(UART0); #endif //system_os_post(uart_recvTaskPrio, 1, 0); WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR); }else if(UART_RXFIFO_OVF_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_OVF_INT_ST)){ WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_OVF_INT_CLR); DBG1("RX OVF!!rn"); } } /****************************************************************************** * FunctionName : uart_init * Description : user interface for init uart * Parameters : UartBautRate uart0_br - uart0 bautrate * UartBautRate uart1_br - uart1 bautrate * Returns : NONE *******************************************************************************/ #if UART_SELFTEST&UART_BUFF_EN os_timer_t buff_timer_t; 无效ICACHE_FLASH_ATTR uart_test_rx() { uint8 uart_buf[128]={0}; uint16 len = 0; len = rx_buff_deq(uart_buf, 128 ); tx_buff_enq(uart_buf,len); } #endif LOCAL 无效ICACHE_FLASH_ATTR /////// uart_recvTask(os_event_t *活动) { if(events->sig == 0){ #if UART_BUFF_EN Uart_rx_buff_enq(); #else uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; uint8 d_tmp = 0; uint8 idx=0; for(idx=0;idxsig == 1){ #if UART_BUFF_EN //already move uart buffer output to uart empty interrupt //tx_start_uart_buffer(UART0); #else #endif } } 无效ICACHE_FLASH_ATTR uart_init(UartBautRate uart0_br, UartBautRate uart1_br) { /*这是处理任务中的UART数据的示例,如果存在,请更改优先级以适合您的应用程序任务*/ system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen); //demo with a task to process the uart data UartDev.baut_rate = uart0_br; uart_config(UART0); UartDev.baut_rate = uart1_br; uart_config(UART1); ETS_UART_INTR_ENABLE(); #if UART_BUFF_EN pTxBuffer = Uart_Buf_Init(UART_TX_BUFFER_SIZE); pRxBuffer = Uart_Buf_Init(UART_RX_BUFFER_SIZE); #endif /*option 1: use default print, output from uart0 , will wait some time if fifo is full */ //do nothing... /*option 2: output from uart1,uart1 output will not wait , just for output debug info */ /*os_printf output uart data via uart1(GPIO2)*/ os_install_putc1((void *)uart1_write_char); //use this one to output debug information via uart1 // /*option 3: output from uart0 will skip current byte if fifo is full now... */ /*see uart0_write_char_no_wait:you can output via a buffer or output directly */ /*os_printf output uart data via uart0 or uart buffer*/ //os_install_putc1((void *)uart0_write_char_no_wait); //use this to print via uart0 #if UART_SELFTEST&UART_BUFF_EN os_timer_disarm(&buff_timer_t); os_timer_setfn(&buff_timer_t, uart_test_rx , NULL); //a demo to process the data in uart rx buffer os_timer_arm(&buff_timer_t,10,1); #endif } 无效ICACHE_FLASH_ATTR uart_reattach() { uart_init(BIT_RATE_115200, BIT_RATE_115200); } /****************************************************************************** * FunctionName : uart_tx_one_char_no_wait * Description : uart tx a single char without waiting for fifo * Parameters : uint8 uart - uart port * uint8 TxChar - char to tx * Returns : STATUS *******************************************************************************/ 状态 uart_tx_one_char_no_wait (uint8 uart, uint8 TxChar) { uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(uart))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT); if (fifo_cnt < 126) { WRITE_PERI_REG(UART_FIFO(uart) , TxChar); } return OK; } 状态 uart0_tx_one_char_no_wait(uint8 TxChar) { uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(UART0))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT); if (fifo_cnt < 126) { WRITE_PERI_REG(UART_FIFO(UART0) , TxChar); } return OK; } /****************************************************************************** * FunctionName : uart1_sendStr_no_wait * Description : uart tx a string without waiting for every char, used for print debug info which can be lost * Parameters : const char *str - string to be sent * Returns : NONE *******************************************************************************/ void uart1_sendStr_no_wait(const char *str) { while(*str){ uart_tx_one_char_no_wait(UART1, *str++); } } #if UART_BUFF_EN /****************************************************************************** * FunctionName : Uart_Buf_Init * Description : tx buffer enqueue: fill a first linked buffer * Parameters : char *pdata - data point to be enqueue * Returns : NONE *******************************************************************************/ struct UartBuffer* ICACHE_FLASH_ATTR Uart_Buf_Init(uint32 buf_size) { uint32 heap_size = system_get_free_heap_size(); if(heap_size <=buf_size){ DBG1("no buf for uartnr"); return NULL; }else{ DBG("test heap size: %dnr",heap_size); struct UartBuffer* pBuff = (struct UartBuffer* )os_malloc(sizeof(struct UartBuffer)); pBuff->UartBuffSize = buf_size; pBuff->pUartBuff = (uint8*)os_malloc(pBuff->UartBuffSize); pBuff->pInPos = pBuff->pUartBuff; pBuff->pOutPos = pBuff->pUartBuff; pBuff->Space = pBuff->UartBuffSize; pBuff->BuffState = OK; pBuff->nextBuff = NULL; pBuff->TcpControl = RUN; return pBuff; } } 复制 UART 缓冲区 LOCAL 无效ICACHE_FLASH_ATTR Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len) { if(data_len == 0) return ; uint16 tail_len = pCur->pUartBuff + pCur->UartBuffSize - pCur->pInPos ; if(tail_len >= data_len){ //do not need to loop back the queue os_memcpy(pCur->pInPos , pdata , data_len ); pCur->pInPos += ( data_len ); pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize ); pCur->Space -=data_len; }else{ os_memcpy(pCur->pInPos, pdata, tail_len); pCur->pInPos += ( tail_len ); pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize ); pCur->Space -=tail_len; os_memcpy(pCur->pInPos, pdata+tail_len , data_len-tail_len); pCur->pInPos += ( data_len-tail_len ); pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize ); pCur->Space -=( data_len-tail_len); } } /****************************************************************************** * FunctionName : uart_buf_free * Description : deinit of the tx buffer * Parameters : struct UartBuffer* pTxBuff - tx buffer struct pointer * Returns : NONE *******************************************************************************/ 无效ICACHE_FLASH_ATTR uart_buf_free(struct UartBuffer* pBuff) { os_free(pBuff->pUartBuff); os_free(pBuff); } RX 缓冲区取消排队 uint16 ICACHE_FLASH_ATTR rx_buff_deq(char* pdata, uint16 data_len ) { uint16 buf_len = (pRxBuffer->UartBuffSize- pRxBuffer->Space); uint16 tail_len = pRxBuffer->pUartBuff + pRxBuffer->UartBuffSize - pRxBuffer->pOutPos ; uint16 len_tmp = 0; len_tmp = ((data_len > buf_len)?buf_len:data_len); if(pRxBuffer->pOutPos <= pRxBuffer->pInPos){ os_memcpy(pdata, pRxBuffer->pOutPos,len_tmp); pRxBuffer->pOutPos+= len_tmp; pRxBuffer->Space += len_tmp; }else{ if(len_tmp>tail_len){ os_memcpy(pdata, pRxBuffer->pOutPos, tail_len); pRxBuffer->pOutPos += tail_len; pRxBuffer->pOutPos = (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize ); pRxBuffer->Space += tail_len; os_memcpy(pdata+tail_len , pRxBuffer->pOutPos, len_tmp-tail_len); pRxBuffer->pOutPos+= ( len_tmp-tail_len ); pRxBuffer->pOutPos= (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize ); pRxBuffer->Space +=( len_tmp-tail_len); }else{ //os_printf("case 3 in rx deqnr"); os_memcpy(pdata, pRxBuffer->pOutPos, len_tmp); pRxBuffer->pOutPos += len_tmp; pRxBuffer->pOutPos = (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize ); pRxBuffer->Space += len_tmp; } } if(pRxBuffer->Space >= UART_FIFO_LEN){ uart_rx_intr_enable(UART0); } return len_tmp; } 将数据从 UART FIFO 移动到 RX 缓冲区 无效 ICACHE_FLASH_ATTR Uart_rx_buff_enq() { uint8 fifo_len,buf_idx; uint8 fifo_data; #if 1 fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; if(fifo_len >= pRxBuffer->Space){ os_printf("buf full!!!nr"); }else{ buf_idx=0; while(buf_idx < fifo_len){ buf_idx++; fifo_data = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF; *(pRxBuffer->pInPos++) = fifo_data; if(pRxBuffer->pInPos == (pRxBuffer->pUartBuff + pRxBuffer->UartBuffSize)){ pRxBuffer->pInPos = pRxBuffer->pUartBuff; } } pRxBuffer->Space -= fifo_len ; if(pRxBuffer->Space >= UART_FIFO_LEN){ //os_printf("after rx enq buf enoughnr"); uart_rx_intr_enable(UART0); } } #endif } 填充 UART TX 缓冲区 无效ICACHE_FLASH_ATTR tx_buff_enq(char* pdata, uint16 data_len ) { if(pTxBuffer == NULL){ DBG1("nrnull, create buffer structnr"); pTxBuffer = Uart_Buf_Init(UART_TX_BUFFER_SIZE); if(pTxBuffer!= NULL){ Uart_Buf_Cpy(pTxBuffer , pdata, data_len ); }else{ DBG1("uart tx MALLOC no buf nr"); } }else{ if(data_len <= pTxBuffer->Space){ Uart_Buf_Cpy(pTxBuffer , pdata, data_len); }else{ DBG1("UART TX BUF FULL!!!!nr"); } } #if 0 if(pTxBuffer->Space <= URAT_TX_LOWER_SIZE){ set_tcp_block(); } #endif SET_PERI_REG_MASK(UART_CONF1(UART0), (UART_TX_EMPTY_THRESH_VAL & UART_TXFIFO_EMPTY_THRHD) pTxBuff->pOutPos = pTxBuff->pUartBuff; } } pTxBuff->pOutPos = (pTxBuff->pUartBuff + (pTxBuff->pOutPos - pTxBuff->pUartBuff) % pTxBuff->UartBuffSize ); pTxBuff->Space += data_len; } /****************************************************************************** * FunctionName : tx_start_uart_buffer * Description : get data from the tx buffer and fill the uart tx fifo, co-work with the uart fifo empty interrupt * Parameters : uint8 uart_no - uart port num * Returns : NONE *******************************************************************************/ 无效tx_start_uart_buffer(uint8 uart_no) { uint8 tx_fifo_len = (READ_PERI_REG(UART_STATUS(uart_no))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT; uint8 fifo_remain = UART_FIFO_LEN - tx_fifo_len ; uint8 len_tmp; uint16 tail_ptx_len,head_ptx_len,data_len; //struct UartBuffer* pTxBuff = *get_buff_prt(); if(pTxBuffer){ data_len = (pTxBuffer->UartBuffSize - pTxBuffer->Space); if(data_len > fifo_remain){ len_tmp = fifo_remain; tx_fifo_insert( pTxBuffer,len_tmp,uart_no); SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); }else{ len_tmp = data_len; tx_fifo_insert( pTxBuffer,len_tmp,uart_no); } }else{ DBG1("pTxBuff null nr"); } } #endif 无效uart_rx_intr_disable(uint8 uart_no) { #if 1 CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); #else ETS_UART_INTR_DISABLE(); #endif } 无效uart_rx_intr_enable(uint8 uart_no) { #if 1 SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); #else ETS_UART_INTR_ENABLE(); #endif } ======================================================== LOCAL 无效 uart0_write_char(字符 c) { if (c == 'n') { uart_tx_one_char(UART0, 'r'); uart_tx_one_char(UART0, 'n'); } else if (c == 'r') { } else { uart_tx_one_char(UART0, c); } } 无效ICACHE_FLASH_ATTR UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len) { SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_BIT_NUM,len,UART_BIT_NUM_S); } 无效ICACHE_FLASH_ATTR UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num) { SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_STOP_BIT_NUM,bit_num,UART_STOP_BIT_NUM_S); } 无效ICACHE_FLASH_ATTR UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask) { CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK); SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask); } 无效ICACHE_FLASH_ATTR UART_SetParity(uint8 uart_no, UartParityMode Parity_mode) { CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY |UART_PARITY_EN); if(Parity_mode==NONE_BITS){ }else{ SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode|UART_PARITY_EN); } } 无效ICACHE_FLASH_ATTR UART_SetBaudrate(uint8 uart_no,uint32 baud_rate) { uart_div_modify(uart_no, UART_CLK_FREQ /baud_rate); } 无效ICACHE_FLASH_ATTR UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh) { if(flow_ctrl&USART_HardwareFlowControl_RTS){ PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); SET_PERI_REG_BITS(UART_CONF1(uart_no),UART_RX_FLOW_THRHD,rx_thresh,UART_RX_FLOW_THRHD_S); SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); }else{ CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); } if(flow_ctrl&USART_HardwareFlowControl_CTS){ PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS); SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); }else{ CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); } } 无效ICACHE_FLASH_ATTR UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us) //如果启用了 tx 流控制,则不使用 { uint32 t_s = system_get_time(); while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)){ if(( system_get_time() - t_s )> time_out_us){ break; } WRITE_PERI_REG(0X60000914, 0X73);//WTD } } 布尔ICACHE_FLASH_ATTR UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us) { uint32 t_start = system_get_time(); uint8 tx_fifo_len; uint32 tx_buff_len; while(1){ tx_fifo_len =( (READ_PERI_REG(UART_STATUS(uart_no))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT); if(pTxBuffer){ tx_buff_len = ((pTxBuffer->UartBuffSize)-(pTxBuffer->Space)); }else{ tx_buff_len = 0; } if( tx_fifo_len==0 && tx_buff_len==0){ return TRUE; } if( system_get_time() - t_start > time_out_us){ return FALSE; } WRITE_PERI_REG(0X60000914, 0X73);//WTD } } 无效ICACHE_FLASH_ATTR UART_ResetFifo(uint8 uart_no) { SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); } 无效ICACHE_FLASH_ATTR UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask) { WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask); } 无效ICACHE_FLASH_ATTR UART_SetIntrEna(uint8 uart_no,uint32 ena_mask) { SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask); } 无效ICACHE_FLASH_ATTR UART_SetPrintPort(uint8 uart_no) { if(uart_no==1){ os_install_putc1(uart1_write_char); }else{ /*option 1: do not wait if uart fifo is full,drop current character*/ os_install_putc1(uart0_write_char_no_wait); /*option 2: wait for a while if uart fifo is full*/ os_install_putc1(uart0_write_char); } } ======================================================== /*测试代码*/ 无效ICACHE_FLASH_ATTR uart_init_2(UartBautRate uart0_br, UartBautRate uart1_br) { // rom use 74880 baut_rate, here reinitialize UartDev.baut_rate = uart0_br; UartDev.exist_parity = STICK_PARITY_EN; UartDev.parity = EVEN_BITS; UartDev.stop_bits = ONE_STOP_BIT; UartDev.data_bits = EIGHT_BITS; uart_config(UART0); UartDev.baut_rate = uart1_br; uart_config(UART1); ETS_UART_INTR_ENABLE(); // install uart1 putc callback os_install_putc1((void *)uart1_write_char);//print output at UART1 } out uart.h 文件 法典:全选 /* * File : uart.h * Copyright (C) 2013 - 2016, Espressif Systems * * This program is free software: you can redistribute it and/or modify * it under the terms of version 3 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef UART_APP_H #define UART_APP_H #include "uart_register.h" #include "eagle_soc.h" #include "c_types.h" #define UART_TX_BUFFER_SIZE 768 //Ring buffer length of tx buffer #define UART_RX_BUFFER_SIZE 768 //Ring buffer length of rx buffer #define UART_BUFF_EN 1 //use uart buffer , FOR UART0 #define UART_SELFTEST 0 //set 1:enable the loop test demo for uart buffer, FOR UART0 #define UART_HW_RTS 0 //set 1: enable uart hw flow control RTS, PIN MTDO, FOR UART0 #define UART_HW_CTS 0 //set1: enable uart hw flow contrl CTS , PIN MTCK, FOR UART0 #define UART0 0 #define UART1 1 typedef 枚举 { FIVE_BITS = 0x0, SIX_BITS = 0x1, SEVEN_BITS = 0x2, EIGHT_BITS = 0x3 } UartBitsNum4Char; typedef 枚举 { ONE_STOP_BIT = 0x1, ONE_HALF_STOP_BIT = 0x2, TWO_STOP_BIT = 0x3 } UartStopBitsNum; typedef 枚举 { NONE_BITS = 0x2, ODD_BITS = 1, EVEN_BITS = 0 } UartParityMode; typedef 枚举 { STICK_PARITY_DIS = 0, STICK_PARITY_EN = 1 } UartExistParity; typedef 枚举 { UART_None_Inverse = 0x0, UART_Rxd_Inverse = UART_RXD_INV, UART_CTS_Inverse = UART_CTS_INV, UART_Txd_Inverse = UART_TXD_INV, UART_RTS_Inverse = UART_RTS_INV, } UART_LineLevelInverse; typedef 枚举 { BIT_RATE_300 = 300, BIT_RATE_600 = 600, BIT_RATE_1200 = 1200, BIT_RATE_2400 = 2400, BIT_RATE_4800 = 4800, BIT_RATE_9600 = 9600, BIT_RATE_19200 = 19200, BIT_RATE_38400 = 38400, BIT_RATE_57600 = 57600, BIT_RATE_74880 = 74880, BIT_RATE_115200 = 115200, BIT_RATE_230400 = 230400, BIT_RATE_460800 = 460800, BIT_RATE_921600 = 921600, BIT_RATE_1843200 = 1843200, BIT_RATE_3686400 = 3686400, } UartBautRate; typedef 枚举 { NONE_CTRL, HARDWARE_CTRL, XON_XOFF_CTRL } UartFlowCtrl; typedef 枚举 { USART_HardwareFlowControl_None = 0x0, USART_HardwareFlowControl_RTS = 0x1, USART_HardwareFlowControl_CTS = 0x2, USART_HardwareFlowControl_CTS_RTS = 0x3 } UART_HwFlowCtrl; typedef 枚举 { EMPTY, UNDER_WRITE, WRITE_OVER } RcvMsgBuff状态; typedef 结构 { uint32 RcvBuffSize; uint8 *pRcvMsgBuff; uint8 *pWritePos; uint8 *pReadPos; uint8 TrigLvl; //JLU: may need to pad RcvMsgBuffState BuffState; } RcvMsgBuff; typedef 结构 { uint32 TrxBuffSize; uint8 *pTrxBuff; } TrxMsgBuff; typedef 枚举 { BAUD_RATE_DET, WAIT_SYNC_FRM, SRCH_MSG_HEAD, RCV_MSG_BODY, RCV_ESC_CHAR, } RcvMsgState; typedef 结构 { UartBautRate baut_rate; UartBitsNum4Char data_bits; UartExistParity exist_parity; UartParityMode parity; UartStopBitsNum stop_bits; UartFlowCtrl flow_ctrl; RcvMsgBuff rcv_buff; TrxMsgBuff trx_buff; RcvMsgState rcv_state; int received; int buff_uart_no; //indicate which uart use tx/rx buffer } UartDevice; 无效uart_init(UartBautRate uart0_br, UartBautRate uart1_br); 无效 uart0_sendStr(const char *str); /////////////////////////////////////// #define UART_FIFO_LEN 128 //define the tx fifo length #define UART_TX_EMPTY_THRESH_VAL 0x10 struct UartBuffer{ uint32 UartBuffSize; uint8 *pUartBuff; uint8 *pInPos; uint8 *pOutPos; STATUS BuffState; uint16 Space; //remanent space of the buffer uint8 TcpControl; struct UartBuffer * nextBuff; }; 结构 UartRxBuff{ uint32 UartRxBuffSize; uint8 *pUartRxBuff; uint8 *pWritePos; uint8 *pReadPos; STATUS RxBuffState; uint32 Space; //remanent space of the buffer } ; typedef 枚举 { RUN = 0, BLOCK = 1, } TCPState; 无效 ICACHE_FLASH_ATTR uart_test_rx(); 状态 uart_tx_one_char(uint8 uart, uint8 TxChar); 状态 uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar); void uart1_sendStr_no_wait(const char *str); struct UartBuffer* Uart_Buf_Init(); #if UART_BUFF_EN LOCAL 无效 Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len); void uart_buf_free(struct UartBuffer* pBuff); void tx_buff_enq(char* pdata, uint16 data_len ); LOCAL 无效 tx_fifo_insert(struct UartBuffer* pTxBuff, uint8 data_len, uint8 uart_no); void tx_start_uart_buffer(uint8 uart_no); uint16 rx_buff_deq(char* pdata, uint16 data_len ); void Uart_rx_buff_enq(); #endif void uart_rx_intr_enable(uint8 uart_no); void uart_rx_intr_disable(uint8 uart_no); void uart0_tx_buffer(uint8 *buf, uint16 len); ============================================== #define FUNC_UART0_CTS 4 #define FUNC_U0CTS 4 #define FUNC_U1TXD_BK 2 #define UART_LINE_INV_MASK (0x3f<<19) void UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len); void UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num); 无效 UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask); void UART_SetParity(uint8 uart_no, UartParityMode Parity_mode); 无效 UART_SetBaudrate(uint8 uart_no,uint32 baud_rate); 无效 UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh); 无效 UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us);如果启用了 TX 流量控制,则不使用 无效 UART_ResetFifo(uint8 uart_no); 无效 UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask); 无效 UART_SetIntrEna(uint8 uart_no,uint32 ena_mask); 无效 UART_SetPrintPort(uint8 uart_no); 布尔 UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us); ============================================== |
|
相关推荐
1个回答
|
|
UART0和UART1不应该共享Tx缓冲区。每个UART通常都有自己的独立硬件缓冲区,包括发送(Tx)和接收(Rx)缓冲区。然而,您遇到的问题可能是由于以下原因之一:
1. 软件问题:您可能在代码中意外地使用了错误的UART实例或混淆了UART0和UART1的API调用。请检查您的代码,确保您正确地使用了UART0和UART1的API。 2. 中断冲突:如果您的系统使用中断来处理UART传输,可能存在中断优先级设置不当或中断服务例程(ISR)实现不当的问题。请确保UART0和UART1的中断优先级设置正确,并且ISR正确处理了UART传输。 3. 缓冲区溢出:如果UART0或UART1的Tx缓冲区溢出,可能会导致数据丢失或错误。请检查您的缓冲区大小设置,并确保在发送数据之前有足够的空间。 4. 硬件问题:虽然不太可能,但硬件故障也可能导致UART0和UART1之间的Tx缓冲区共享。您可以检查硬件设计和UART模块的配置,确保它们正确连接和配置。 为了解决这个问题,您可以尝试以下步骤: 1. 审查代码:检查您的代码,确保UART0和UART1的API调用正确,没有混淆。 2. 检查中断设置:确保UART0和UART1的中断优先级设置正确,ISR正确处理UART传输。 3. 调整缓冲区大小:如果可能,请增加UART0和UART1的Tx缓冲区大小,以防止溢出。 4. 调试和测试:使用调试工具和测试代码来隔离问题。您可以尝试逐行执行代码,观察UART0和UART1的行为,以确定问题所在。 5. 检查硬件:如果可能,请检查硬件设计和UART模块的配置,确保它们正确连接和配置。 通过这些步骤,您应该能够确定问题的原因并解决UART0和UART1之间的Tx缓冲区共享问题。 |
|
|
|
只有小组成员才能发言,加入小组>>
486 浏览 1 评论
552浏览 6评论
461浏览 5评论
有没有办法在不使用混杂模式的情况下实现Wifi驱动程序接收缓冲区访问中断呢?
443浏览 5评论
445浏览 4评论
415浏览 4评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 20:51 , Processed in 0.877090 second(s), Total 83, Slave 65 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号