c/c++开发分享与多任务下的UART FIFO相关的错误

附加程序:这些代码由我根据TI uart.c驱动程序库编写。

while(1){ //check if message on Queue -> read or check UART input if(uxQueueMessagesWaiting( UART_TASKQ ) != 0){ //may have bugs // deQueue xQueueReceive( UART_TASKQ, &UARTTaskHandle, 0x0A ); //do the task's mission using the data in the stucture(put by control task) //Print out the input data. //**********debugging data /* testPointer = UARTTaskHandle->dataBuffer; testAmount = UARTTaskHandle->dataSize; while(testAmount){ if(*testPointer != 1){ error = error + 1; } if(*(testPointer + 1) != 2){ error = error + 1; } if(*(testPointer + 2) != 3){ error = error + 1; } if(*(testPointer + 3) != 4){ error = error + 1; } if(*(testPointer + 4) != 5){ error = error + 1; } if(*(testPointer + 5) != 6){ error = error + 1; } if(*(testPointer + 6) != 7){ error = error + 1; } if(*(testPointer + 7) != 8){ error = error + 1; } testPointer = testPointer + 8; testAmount = testAmount - 8; } */ if(UART_write(UART_Handle, UARTTaskHandle->dataBuffer, UARTTaskHandle->dataSize, 0xff ) >= 0){ UARTwriteCount = UARTwriteCount + 1; } //let control task take new command //free allocated memory free(UARTTaskHandle->dataBuffer); free(UARTTaskHandle); // free memory space //(above is code using UART) //here are UART driver code: unsigned long UARTStatus(unsigned long ulBase){ ASSERT(UARTBaseValid(ulBase)); return(HWREG(ulBase + UART_O_FR)); } //***************************************** //UART_ISR //Interrupt service routine for //the UART read and write process //***************************************** void UART_ISR(){ //read FIFO full or read time out if(UARTIntStatus(UART_Handle->UART_PORT,false) & (UART_INT_RX | UART_INT_RT)){ UARTIntClear(UART_Handle->UART_PORT, UART_INT_RX | UART_INT_RT); //clear INT flag while (!(UARTStatus(UART_Handle->UART_PORT) & UART_FR_RXFE)){ //data reading *UART_Handle->pCurrentRead = UARTCharGet(UART_Handle->UART_PORT); //read autoly clear INT UART_Handle->pCurrentRead++; UART_Handle->ReadLength--; //adjust code here: if(UART_Handle->ReadLength == 0){ break; } } //check if read certain bytes finished if(UART_Handle->ReadLength == 0){ memcpy(UART_Handle->dataput, UART_Handle->pReadBuf,UART_Handle->ReadLengthcpy); // copy data back xSemaphoreGiveFromISR( UART_Handle->UARTRead_Semaphore, &xHigherPriorityTaskWoken );// release semaphore portYIELD_FROM_ISR( xHigherPriorityTaskWoken );//forcing context exchange } } //send FIFO empty if(UARTIntStatus(UART_Handle->UART_PORT,false) & UART_INT_TX){ UARTIntClear(UART_Handle->UART_PORT, UART_INT_TX); //clear INT flag if(UART_Handle->WriteLength == BUFFEMPTY){ UART_Handle->UART_SendComplete = true; xSemaphoreGiveFromISR( UART_Handle->UARTWrite_Semaphore, &xHigherPriorityTaskWoken );// release semaphore portYIELD_FROM_ISR( xHigherPriorityTaskWoken );//forcing context exchange } //putting data into send FIFO if(UART_Handle->WriteLength > FIFOMAX){ for( Cindex = 0 ; Cindex UART_PORT, *(UART_Handle->pCurrentWrite))){//write autoly clear INT (UART_Handle->pCurrentWrite) = (UART_Handle->pCurrentWrite) + 1; (UART_Handle->WriteLength) = (UART_Handle->WriteLength) - 1; Cindex = Cindex + 1; UART_Handle->sentCount = UART_Handle->sentCount + 1; } } }else{ templength = UART_Handle->WriteLength; for( Cindex = 0; Cindex UART_PORT, *(UART_Handle->pCurrentWrite))){//write autoly clear INT (UART_Handle->pCurrentWrite) = (UART_Handle->pCurrentWrite) + 1; (UART_Handle->WriteLength) = (UART_Handle->WriteLength) - 1; Cindex = Cindex + 1; UART_Handle->sentCount = UART_Handle->sentCount + 1; } } } } } //***************************************** //UART_write //write certain length of data to UART port //***************************************** int32_t UART_write( UART_STATE *UART_Handle, uint8_t *pData, uint32_t length, uint32_t time_out ){ while(!UART_Handle->UART_SendComplete); //debugging purpose UART_Handle->UART_SendComplete = false;//debugging purpose UART_Handle->WriteLength = length; if(UART_Handle->WriteLength WriteBufSize){ UARTIntClear(UART_Handle->UART_PORT, UART_INT_TX); //clear INT flag memcpy(UART_Handle->pWriteBuf,pData,UART_Handle->WriteLength); //copy data into writebuff UART_Handle->pCurrentWrite = UART_Handle->pWriteBuf; //putting data into send FIFO if(UART_Handle->WriteLength > FIFOMAX){ // if for( Cindex = 0 ; Cindex UART_PORT, *(UART_Handle->pCurrentWrite))){//write autoly clear INT (UART_Handle->pCurrentWrite) = (UART_Handle->pCurrentWrite) + 1; (UART_Handle->WriteLength) = (UART_Handle->WriteLength) - 1; Cindex = Cindex + 1; UART_Handle->sentCount = UART_Handle->sentCount + 1; } } }else{ for( Cindex = 0 ; Cindex UART_PORT, *(UART_Handle->pCurrentWrite))){//write autoly clear INT (UART_Handle->pCurrentWrite) = (UART_Handle->pCurrentWrite) + 1; (UART_Handle->WriteLength) = (UART_Handle->WriteLength) - 1; Cindex = Cindex + 1; UART_Handle->sentCount = UART_Handle->sentCount + 1; } } } //start sending UARTEnable(UART_Handle->UART_PORT); if(UART_Handle->UARTWrite_Semaphore != NULL ) { if(xSemaphoreTake(UART_Handle->UARTWrite_Semaphore, time_out/(portTICK_PERIOD_MS) ) == pdTRUE){ reValue = WRITESUCCESS; //wait return till write complete }else{ reValue = WRITETIMEOUT; // timeout (ms) } }else{ while(1); //no Semaphore } return reValue; }else{ return FAILURE; //wrong length } } //***************************************** //UART_read //read certain length of data from UART port //***************************************** int32_t UART_read(UART_STATE *UART_Handle, uint8_t *pData, uint32_t length, uint32_t time_out){ //later added part UARTDisable(UART_Handle->UART_PORT); //clearUART UARTFIFOEnable(UART_Handle->UART_PORT); // UART_Handle->ReadLength = length; // set readlength UART_Handle->ReadLengthcpy = length; if(UART_Handle->ReadLength ReadBufSize){ UARTIntClear(UART_Handle->UART_PORT, UART_INT_RX | UART_INT_RT); //clear INT flag UART_Handle->dataput = pData; //store the destination buffer address UART_Handle->pCurrentRead = UART_Handle->pReadBuf; //set current read UARTEnable(UART_Handle->UART_PORT); //start receiving //suspend before read ISR finish whole process if(UART_Handle->UARTRead_Semaphore != NULL ) { if(xSemaphoreTake(UART_Handle->UARTRead_Semaphore, time_out/(portTICK_PERIOD_MS) ) == pdTRUE){ reValue = READSUCCESS; //wait return till write complete }else{ reValue = READTIMEOUT; // timeout (ms) } }else{ while(1); //no Semaphore } return reValue; }else{ return FAILURE; //wrong length } } //***************************************** //UART_open //open UART for certain port and bandrate //***************************************** UART_HANDLE UART_open(uint32_t UART_port, uint32_t UART_portperiph, uint32_t UART_baudrate){ //initialize structure UART_Handle = (UART_HANDLE)malloc(sizeof(UART_STATE)); UART_Handle->ReadBufSize = UARTBUFFERSIZE; UART_Handle->WriteBufSize = UARTBUFFERSIZE; UART_Handle->UART_PORT = UART_port; UART_Handle->UART_PORTPERIPH = UART_portperiph; UART_Handle->UART_BRATE = UART_baudrate; UART_Handle->pWriteBuf = (uint8_t*)malloc(UART_Handle->WriteBufSize * sizeof(uint8_t)); UART_Handle->pReadBuf = (uint8_t*)malloc(UART_Handle->ReadBufSize * sizeof(uint8_t)); UART_Handle->pCurrentWrite = UART_Handle->pWriteBuf; UART_Handle->pCurrentRead = UART_Handle->pReadBuf; UART_Handle->UARTWrite_Semaphore = NULL; UART_Handle->UARTRead_Semaphore = NULL; UART_Handle->UARTprotect_Semaphore = NULL; UART_Handle->UART_SendComplete = true; UART_Handle->sentCount = 0;//debugging purpose vSemaphoreCreateBinary( UART_Handle->UARTWrite_Semaphore ); //semaphore create vSemaphoreCreateBinary( UART_Handle->UARTRead_Semaphore ); //semaphore create // vSemaphoreCreateBinary( UART_Handle->UARTprotect_Semaphore ); //debugging purpose xSemaphoreTake( UART_Handle->UARTRead_Semaphore, portMAX_DELAY ); //semaphore take xSemaphoreTake( UART_Handle->UARTWrite_Semaphore, portMAX_DELAY ); //semaphore take // Enable Peripheral Clocks MAP_PRCMPeripheralClkEnable(UART_Handle->UART_PORTPERIPH, PRCM_RUN_MODE_CLK); // Configure PIN_55 for UART0 UART0_TX MAP_PinTypeUART(PIN_55, PIN_MODE_3); // Configure PIN_57 for UART0 UART0_RX MAP_PinTypeUART(PIN_57, PIN_MODE_3); // configuration, 8 bits length data width, 1 stop bit, no parity check UARTConfigSetExpClk(UART_Handle->UART_PORT,PRCMPeripheralClockGet( UART_Handle->UART_PORTPERIPH), UART_Handle->UART_BRATE, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); // disable UART since function above contained UARTenable UARTDisable(UART_Handle->UART_PORT); UARTIntEnable(UART_Handle->UART_PORT, UART_INT_TX | UART_INT_RX | UART_INT_RT); // enable interrupt for send and receive and receive timeout UARTIntRegister(UART_Handle->UART_PORT, UART_ISR); //hook ISR UARTFIFOEnable(UART_Handle->UART_PORT); //enable FIFO for send and receive UARTFIFOLevelSet(UART_Handle->UART_PORT, UART_FIFO_TX1_8, UART_FIFO_RX4_8); //Interrupt occur when 7 bytes send from FIFO or read in FIFO return UART_Handle; } 

我正在处理一个multithreading的bug很长一段时间。 经过多次测试后,我意识到最有可能与UART FIFO传输有关的错误。

这是我对我的程序的描述:该程序基于Free-RTOS。 它有两个并行运行的线程。 一个线程通过I2C驱动程序从传感器读取。 另一种是通过UART驱动程序将数据从读取任务发送到计算机。 我有一个多任务框架,用于将数据从读取任务传输到发送任务。 我有一个计时器文件来控制实时测量。 我的I2C驱动程序和UART驱动程序都是基于中断的。

问题描述:我的数据读数只有2分钟。 之后,我的数据发生了变化。 在测试时,我阻止了I2C驱动程序,只将常数数据“1 2 3 4 5 6 7 8”放入I2C读缓冲区,并将它们传送到发送任务进行UART发送。 2分钟后,我读出的数据将变为“8 1 2 3 4 5 6 7”,在第一次更改后,后来的变化很快发生,“7 8 1 2 3 4 5 6”并继续到计时结束。 这是我的数据的一个通道的图,从8开始并改变

我已经为我的程序设置了很多测试,我确信我的多任务框架(从读取任务到发送任务的转换数据)不会改变数据。 重要观察:1。当我将read和send放入一个线程时,数据非常好,没有这个bug。 2.我在我的UART驱动程序中设置计数,发现发送量是正确的,这里发送将字节放入TX FIFO。 但是,在Excel中,我通过JAVA UART程序读取数据,错过了。 并且JAVA UART程序应该没问题,因为当我使用单线程测试时它运行良好。 3.调试时CCS没有内存泄漏错误。

所以我想,在multithreading环境下,在我将字节放入之后,某些东西停止了我的UART TX FIFO传输。 但我无法找到我的代码中的错误,它们似乎都是正确的。

另一个合理的原因可能是我的指针在中断中被改变了,在链接图片中是“pCurrentWrite”指针。 但该指针只能由UART驱动程序访问,并且在中断完成之前,下一次UART写操作无法进入。

我在链接中包含部分代码,我想在其中显示数据被放入TX FIFO,并且发送计数是正确的。

我不能包含所有代码,我认为没有人想检查那些长代码。 没有运行它,很难找出错误的地方。

所以,我只想描述我遇到的情况,看看之前是否有人有类似的错误。 也许有人知道multithreading环境下的UART FIFO问题。 如果有人可以帮助您查看代码,我们可以进一步联系。

谢谢(我的新帐户还不能包含图片,图片链接如下)

在发送中断中,此代码是我的UART驱动程序的一部分。 我使用PutCharNonBlocking来放置字节,因为如果成功则返回1,如果FIFO满,则返回0,所以这样我确保程序将所有数据发送到FIFO,结果是真的,所有数据都放了进入TX FIFO

    虽然您已经包含了信号量的使用,但我建议您进一步阅读互斥和共享资源。

    解决方案过于复杂,更好地抽象代码并简化。

    注意:你不应该转换malloc的结果 。

     UART_Handle = (UART_HANDLE)malloc(sizeof(UART_STATE)); 

      以上就是c/c++开发分享与多任务下的UART FIFO相关的错误相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注(猴子技术宅)。

      本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

      如若转载,请注明出处:https://www.ssfiction.com/c-cyuyankaifa/545951.html

      发表评论

      电子邮件地址不会被公开。 必填项已用*标注