问题
I'm new here and I'm trying to solve my projects problem. I'm trying to send send data over UART from Raspberry Pi B+ to my STM32F407 and process that data in real-time. My problem is: How to actually synchronize main() thred and UART interruption handler not to stop for a long time my UART interruption. Data sent from Raspberry looks like (where n is number): nwnx Code:
void UART4_IRQHandler(void)
{
if(USART_GetITStatus(UART4, USART_IT_RXNE))
{
if(!flag)
{
processing = true;
widthTemp[j] = USART_ReceiveData(UART4);
USART_ClearITPendingBit(UART4, USART_IT_RXNE);
if(widthTemp[j] != 'w')
{
j++;
}
else
{
j = 0;
flaga = true;
processing = false;
//__disable_irq();
NVIC_DisableIRQ(UART4_IRQn);
}
}else if(flag)
{
processing = true;
heightTemp[j] = USART_ReceiveData(UART4);
USART_ClearITPendingBit(UART4, USART_IT_RXNE);
if(heightTemp[j] != 'x')
{
j++;
}
else
{
j++;
heightTemp[j] = '\n';
j = 0;
processing = false;
flag = false;
NVIC_DisableIRQ(UART4_IRQn);
}
}
}
}
and now main code:
while (1)
{
if(!NVIC_GetPendingIRQ(UART4_IRQn))
{
//if()
if(flag == true && processing == false)
{
sscanf(heightTemp, "%d", &height );
USART_puts(UART4, heightTemp); // sending back data to raspberry (temporary)
for(i = 0; i< sizeof(widthTemp);i++)
{
heightTemp[i] = '\0';
}
NVIC_EnableIRQ(UART4_IRQn);
}
if(flag == false && processing == false)
{
sscanf(widthTemp, "%d", &width );
USART_puts(UART4, widthTemp); // sending back data to raspberry (temporary)
for(i = 0; i< sizeof(widthTemp);i++)
{
widthTemp[i] = '\0';
}
NVIC_EnableIRQ(UART4_IRQn);
}
}
}
My problem is that at some point rasbperry is starting to have huge delays in recieved data.
Questions: 1. Can I disable interruptions in interruption handler like I did in my code to let my main() know that it can proceed data ? And if yes, do I check good register for this task ? 2. Is there a better way to send buffer (widthTemp f.e.) to some variable ? Maybe I don't need to complicate my code like this. 3. Can I use maybe threding in my code ? Will it help ? 4. This is my first post so any information about how to format questions, advices about the code etc. will be nice.
回答1:
In general, your UART ISR should do little more than:
- For a receive interrupt, place character from RXD in a ring buffer
- for a transmit interrupt, get character from a ring buffer and place it in TXD. On STM32, if the ring buffer is empty, you must explicitly switch off the transmitter.
- clear interrupt flags (handling of error flags optional).
Then your main thread (or some other thread/task if using an thread scheduler or RTOS), simply reads from the Rx ring buffer (or writes to the Tx ring buffer).
Note that on STM32 if the transmitter is not running, the first character should be placed directly in TXD, and the transmitter started, subsequent characters are then places in the Tx ring buffer.
If using an RTOS or other OS, you might use a queue or mailbox rather then implementing your own ring buffer. Some care is required to ensure consistent buffer control when more than one context is accessing the control data.
Note that the STM32 is capable of using DMA transfers to UART operation which may offer an alternative solution, especially if the data rate is very fast, since the STM32 UART has no FIFO and will overrun the RXD if each character is not removed from RXD in the time taken to receive another.
回答2:
As said in @arduic comment, you should not process data in the interrupt. You should keep interrupt service routine as short (and quick) as possible. Therefore, you will not need to disable them, preventing for losing data in the case of UART RX interrupt.
来源:https://stackoverflow.com/questions/34611870/disabling-interrupt-in-interrupt-handler-stm32f407