Finde auch nix in Deinem Code. Sollte eigentlich tun. Das
USART_ClearITPendingBit(SART1, USART_IT_RXNE) solltest Du dir sogar
sparen können, da mit dem Lesen des Empfangsregister das RXNE Flag
gelöscht wird (Du solltest es Dir sogar sparen wegen möglicher
race-condition).
Das disablen und enablen von Interrupts sollte auch nicht nötig sein
(ich gehe mal davon aus, dass die Prioritäten FreeRTOS, uart2 richtig
gesetzt sind).
Bei mir tut das hier:
1 | void USART1_IRQHandler(void)
|
2 | {
|
3 | portBASE_TYPE task_woken = pdFALSE;
|
4 | char c;
|
5 |
|
6 | if (USART1->SR & USART_SR_RXNE)
|
7 | {
|
8 | /* rx data ready */
|
9 | c = USART1->DR;
|
10 | /* try to enqueue */
|
11 | xQueueSendFromISR(serial_queues.uart1_rx_queue, (void *)&c, &task_woken);
|
12 | }
|
13 | /* only try to get data from queue if tx register empty
|
14 | * and int is enabled. if we would not check for int enabled, rx from queue
|
15 | * would be tried on every rx interrupt since txe is allways set when tx register
|
16 | * is empty
|
17 | */
|
18 | if ((USART1->SR & USART_SR_TXE) && (USART1->CR1 & USART_CR1_TXEIE))
|
19 | {
|
20 | /* tx register empty */
|
21 |
|
22 | if (xQueueReceiveFromISR(serial_queues.uart1_tx_queue, (void *)&c, &task_woken))
|
23 | {
|
24 | /* got data from queue, send it */
|
25 | USART1->DR = c;
|
26 | }
|
27 | else
|
28 | {
|
29 | /* queue empty, disable further ints */
|
30 | USART1->CR1 &= ~USART_CR1_TXEIE;
|
31 | }
|
32 | }
|
33 | portEND_SWITCHING_ISR(task_woken);
|
34 | }
|
Grundsätzlich beim STM32:
In der ST FAQ (http://www.st.com/stonline/faq/user_faqbrowser.php) nach
"Interrupt re-enters" suchen (FAQ #1224). Grr.. direkter Link geht
nicht.
Sollte aber bei Dir nicht das Problem sein, da nach dem Löschen des
Flags (beim Lesen des Registers) ja noch genug passiert vor dem
Rücksprung.
Gruß
Clemens