2025-11-24 3:36 AM - last edited on 2025-11-24 3:58 AM by Andrew Neil
Hello ST Team,
I am using an STM32H755ZIT6 where CM7 handles a high-speed Quad-SPI flash interface with 100Mhz and UART communication with flow control 115200 baud.
The same firmware runs on two hardware revisions:
Revision V2: Works perfectly
Revision V3: Same firmware → occasional failure in UART frame processing
The QSPI itself receives data correctly (verified with CRC), but the “end of frame” indication is occasionally not processed.
In the UART receive callback, when “end of frame” (EOF) is detected, we set an RTOS event flag:
osEventFlagsSet(dataReceiveEvent, DataReceived);Problem on V3:
Sometimes the event flag is not triggered
Even though all received bytes are correct
CRC validation passes
The callback executes, but the main task does not wake
This leads to missed packets even though the data is fully received.
We replaced the RTOS event flag with a simple polling mechanism inside the processing task:
while(1)
{
if(osMessageQueueGet(...) == osOK)
process();
osDelay(10);
}With this change:
V3 hardware works consistently
No EOF detection failures
No lost frames
V2 continues to work as usual
This confirms the raw UART data is always correct — only the timing window of the RTOS wake-up is sensitive.
It appears that:
The UART ISR + RTOS event-flag + context switching timing is borderline in some conditions
Minor timing jitter causes occasional missed RTOS event wakeups
Polling hides this issue because it does not depend on a precise timing window
Are there known conditions where CMSIS-RTOS2 EventFlags used inside UART RX callbacks can be missed due to timing jitter or interrupt priority interactions?
Is there any recommendation on:
Minimum ISR execution time
Maximum recommended operations inside UART RX callback
Priority level requirements for tasks waiting on EventFlags
Does ST recommend using:
Ring buffer + task polling
Direct-to-queue from ISR
Stream buffer
Event flags
for continuous, critical UART communication?
Any known errata for STM32H7 regarding:
EventFlags not waking tasks
Interrupt latency
Missed wakeups under high-load conditions
Data reception is always correct
CRC is valid
Only the RTOS event flag wake-up occasionally fails
Polling solves the problem
Need guidance on recommended ISR → task signaling method for STM32H7
Thank you in advance.
2025-11-24 6:45 AM
Hello @Ibrahimsha
To ensure reliable signaling between the UART interrupt and your RTOS task (for example, when using EventFlags or other RTOS primitives), it is essential to configure the UART interrupt priority correctly. For example, if your RTOS kernel allows API calls from ISRs with priority values of 5 or higher, set the UART interrupt priority to 5, 6, or a higher number.
2025-11-24 8:34 AM
Hello @Saket_Om,
Thank you for the clarification.
I have verified the NVIC configuration, and all UART interrupts that interact with FreeRTOS are already configured at priority level 5, which is within the valid range for FreeRTOS ISR APIs (numerically ≥ configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY).
✔ UART1 global interrupt → Priority 5
✔ UART7 global interrupt → Priority 5
✔ QUADSPI, DMA, and I2C interrupts that call RTOS functions are also configured at priority 5
So the interrupt priorities are already set correctly according to the FreeRTOS requirements and should not cause ISR-to-task signaling issues.
I think this is correct. If anything looks wrong, kindly guide me.
Thank you for your support.
2025-11-25 5:49 AM
Hello @Ibrahimsha
Did you try with peripheral interrupt priorities > 5 ?
2025-11-25 10:04 PM
Hello @Saket_Om,
Yes, I tested using peripheral interrupt priorities greater than 5 (including priority 6) as recommended.
To provide complete visibility, here is the runtime NVIC priority table captured from the STM32H755:
================ NVIC PRIORITY DEBUG ================
Priority Grouping = 3 (0=NVIC_PRIORITYGROUP_0 ... 4=NVIC_PRIORITYGROUP_4)
IRQ Priority Pending
--------------------------
7 5 0 <-- UART-related
11 5 0
28 4 0
52 5 0
53 5 0
82 5 0
101 5 0
All UART, QSPI, DMA, and I2C interrupts that interact with RTOS APIs are assigned:
Priority 5 or 6
Priority grouping value that respects
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY = 5
We also changed some peripheral priorities from 5 to 6 (e.g., QUADSPI, UART) specifically for this investigation.
So the ISR priority configuration is correct and should not cause missed RTOS wakeups.
✔ Old Implementation (Works on V2, fails intermittently on V3)
This version uses EventFlags for ISR → Task signaling:
memset(&processData, 0, sizeof(ProcessData)); dataSize = inDataBufferIndex; processData.size = inDataBufferIndex; memset(&processData.receivedDataBuffer, 0, sizeof(receivedBuffer)); memcpy(&processData.receivedDataBuffer, receivedBuffer, dataSize); if (osMessageQueueGetSpace(ISCMessageQueue) > 0) { if (osMessageQueuePut(ISCMessageQueue, &processData, MessagePriority, QueueAccessTimeOutInMS) == osOK) { osEventFlagsSet(dataReceiveEvent, DataReceived); } } else { DebugLog("data error - Queue Full\r\n"); osEventFlagsSet(dataReceiveEvent, DataReceived); }
Behavior:
On V2 hardware → works perfectly
On V3 hardware → data is received correctly, CRC is valid, ISR executes, and the queue is updated
but the task occasionally does not wake from osEventFlagsWait()
In this case, osEventFlagsWait() returns osErrorResource (-3), even though the ISR was executed and data was placed in the queue.
This results in missing “end-of-frame” notifications even though the data path is correct.
✔ New Implementation (Stable on V3)
Changing the signaling from EventFlags to ThreadFlags made the system fully reliable on V3:
memset(&processData, 0, sizeof(ProcessData)); dataSize = inDataBufferIndex; processData.size = inDataBufferIndex; memset(&processData.receivedDataBuffer, 0, sizeof(receivedBuffer)); memcpy(&processData.receivedDataBuffer, receivedBuffer, dataSize); if (osMessageQueueGetSpace(ISCMessageQueue) > 0) { if (osMessageQueuePut(ISCMessageQueue, &processData, MessagePriority, QueueAccessTimeOutInMS) == osOK) { osThreadFlagsSet(dataReceivingTaskHandle, DataReceived); } } else { DebugLog("data error - Queue Full\r\n"); osThreadFlagsSet(dataReceivingTaskHandle, DataReceived); }
Result:
V3 hardware becomes fully stable
No missed wake-ups
No frame-processing failures
V2 continues to work exactly as before
✔ What I Am Trying to Understand
From my observations:
EventFlags seem more sensitive to ISR timing and may lose the wake-up if the event is set before the task enters osEventFlagsWait().
ThreadFlags appear strictly 1:1 and consistently wake the correct task without missing notifications.
:question_mark: Questions
Are there known differences in wake-up semantics between EventFlags and ThreadFlags when used from a UART ISR on STM32H7?
Is EventFlags more prone to race conditions in ISR → Task signaling compared to ThreadFlags?
Does ST recommend ThreadFlags, or direct-to-queue notification, instead of EventFlags for high-frequency UART communication?
Is there any STM32H7 or CMSIS-RTOS2 errata related to missed EventFlags wakeups or ISR → Task synchronization?
The data reception itself is correct in all cases—only the RTOS wake-up mechanism differs in reliability between EventFlags and ThreadFlags.
FYI
================ NVIC PRIORITY DEBUG ================
Priority Grouping = 3 (0=NVIC_PRIORITYGROUP_0 ... 4=NVIC_PRIORITYGROUP_4)
Active IRQ = -16
IRQ Priority Pending
--------------------------
0 0 0
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 5 0
8 0 0
9 0 0
10 0 0
11 5 0
12 0 0
13 0 0
14 0 0
15 0 0
16 0 0
17 0 0
18 0 0
19 0 0
20 0 0
21 0 0
22 0 0
23 0 0
24 0 0
25 0 0
26 0 0
27 0 0
28 4 0
29 0 0
30 0 0
31 0 0
32 0 0
33 0 0
34 0 0
35 0 0
36 0 0
37 0 0
38 0 0
39 0 0
40 0 0
41 0 0
42 0 0
43 0 0
44 0 0
45 0 0
46 0 0
47 0 0
48 0 0
49 0 0
50 0 0
51 0 0
52 5 0
53 5 0
54 0 0
55 0 0
56 0 0
57 0 0
58 0 0
59 0 0
60 0 0
61 0 0
62 0 0
63 0 0
64 0 0
65 0 1
66 0 0
67 0 0
68 0 0
69 0 0
70 0 0
71 0 0
72 0 0
73 0 0
74 0 0
75 0 0
76 0 0
77 0 0
78 0 0
79 0 0
80 0 0
81 0 0
82 5 0
83 0 0
84 0 0
85 0 0
86 0 0
87 0 0
88 0 0
89 0 0
90 0 0
91 0 0
92 0 0
93 0 0
94 0 0
95 0 0
96 0 0
97 0 0
98 0 0
99 0 0
100 0 0
101 5 0
102 0 0
103 0 0
104 0 0
105 0 0
106 0 0
107 0 0
108 0 0
109 0 0
110 0 0
111 0 0
112 0 0
113 0 0
114 0 0
115 0 0
116 0 0
117 0 0
118 0 0
119 0 0
120 0 0
121 0 0
122 0 0
123 0 0
124 0 0
125 0 0
126 0 0
127 0 0
128 0 0
129 0 0
130 0 0
131 0 0
132 0 0
133 0 0
134 0 0
135 0 0
136 0 0
137 0 0
138 0 0
139 0 0
140 0 0
141 0 0
142 0 0
143 0 0
144 0 0
145 0 0
146 0 0
147 0 0
148 0 0
149 0 0
150 0 0
151 0 0
152 0 0
153 0 0
154 0 0
155 0 0
156 0 0
157 0 0
158 0 0
159 0 0
160 0 0
161 0 0
162 0 0
163 0 0
164 0 0
165 0 0
166 0 0
167 0 0
168 0 0
169 0 0
170 0 0
171 0 0
172 0 0
173 0 0
174 0 0
175 0 0
176 0 0
177 0 0
178 0 0
179 0 0
180 0 0
181 0 0
182 0 0
183 0 0
184 0 0
185 0 0
186 0 0
187 0 0
188 0 0
189 0 0
190 0 0
191 0 0
192 0 0
193 0 0
194 0 0
195 0 0
196 0 0
197 0 0
198 0 0
199 0 0
200 0 0
201 0 0
202 0 0
203 0 0
204 0 0
205 0 0
206 0 0
207 0 0
208 0 0
209 0 0
210 0 0
211 0 0
212 0 0
213 0 0
214 0 0
215 0 0
216 0 0
217 0 0
218 0 0
219 0 0
220 0 0
221 0 0
222 0 0
223 0 0
224 0 0
225 0 0
226 0 0
227 0 0
228 0 0
229 0 0
230 0 0
231 0 0
232 0 0
233 0 0
234 0 0
235 0 0
236 0 0
237 0 0
238 0 0
239 0 0
Thank you again for your guidance.
I appreciate your continued support.