<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>FreeRTOS Race Condition with Tickless Idle and Suspending Tasks</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/69831/freertos-race-condition-with-tickless-idle-and-suspending-tasks</link><description>Hi 
 We&amp;#39;ve recently added FreeRTOS to the firmware of an existing product (primarily to pre-empt big chunks of 3rd-party code over which we have no control and execute them in a well-timed fashion). The goal is to achieve almost the same low-power properties</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 20 Jan 2021 10:07:13 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/69831/freertos-race-condition-with-tickless-idle-and-suspending-tasks" /><item><title>RE: FreeRTOS Race Condition with Tickless Idle and Suspending Tasks</title><link>https://devzone.nordicsemi.com/thread/290186?ContentTypeID=1</link><pubDate>Wed, 20 Jan 2021 10:07:13 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5d24d90f-85d5-45f1-8915-67abcbf89263</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;Without touching all the application ISRs, I think it is quite difficult to solve this corner case.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: FreeRTOS Race Condition with Tickless Idle and Suspending Tasks</title><link>https://devzone.nordicsemi.com/thread/289847?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 16:28:44 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9576f06c-40c6-4c55-b9e8-e22ca50751ed</guid><dc:creator>A Knecht</dc:creator><description>&lt;p&gt;Generally I agree. Modifying all the interrupt handlers to modify an additional atomic variable is kind of a last resort solution, but probably the one I&amp;#39;ll have to use.&lt;br /&gt;But I&amp;#39;m not yet sure that it is feasible to modify all the interrupt handlers. Some might be hidden in binary 3rd party code that I am unable to modify and some might be in Nordic SDK code, which I can change, but would like to do so as little as possible.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: FreeRTOS Race Condition with Tickless Idle and Suspending Tasks</title><link>https://devzone.nordicsemi.com/thread/288698?ContentTypeID=1</link><pubDate>Tue, 12 Jan 2021 14:59:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:39a6f169-c8f5-428f-a6f0-0d9c8428009d</guid><dc:creator>Susheel Nuguru</dc:creator><description>[quote user="aknecht"]Say I have an interrupt that sets some atomic variable that leads the main loop to do something the next time it runs and given the following sequence switching away from the&amp;nbsp; main task:[/quote]
&lt;p&gt;&amp;nbsp;Can&amp;#39;t you include the atomic variable into your if condition? for example&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;before you suspend your main task, clear the atomic variable and the vTaskSuspend(main_task)&lt;/li&gt;
&lt;li&gt;in your interrupt service handler, set the atomic variable&lt;/li&gt;
&lt;li&gt;in configPOST_SLEEP_PROCESSING&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;if( (NVIC-&amp;gt;ISPR[0] | NVIC-&amp;gt;ISPR[1] | NVIC-&amp;gt;ISPR[2])  | (atomic_variable == 1))
{
    vTaskResume(m_main_task_handle);
    atomic_variable = 0;
}&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think the only possibility that the atomic_variable in that IF statement gets through is when the corner case you mentioned happens.&lt;/p&gt;
&lt;p&gt;Do you agree?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: FreeRTOS Race Condition with Tickless Idle and Suspending Tasks</title><link>https://devzone.nordicsemi.com/thread/288352?ContentTypeID=1</link><pubDate>Mon, 11 Jan 2021 11:02:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d0ee3c9a-6160-4e42-b191-26b5aad06010</guid><dc:creator>A Knecht</dc:creator><description>&lt;p&gt;It&amp;#39;s not about an observable behavior, but about theoretical correctness.&lt;br /&gt;&lt;br /&gt;- sd_app_evt_wait gets called inside a critical region. Hence interrupts that wake the CPU and resume code execution after sd_app_evt_wait will be pended and their presence can be checked via the NVIC-&amp;gt;ISPR flags.&lt;br /&gt;- sd_app_evt_wait will not sleep if an interrupt has occurred before it was last called, according to the note in the doxygen comment&lt;/p&gt;
&lt;div style="padding-left:30px;"&gt;&lt;span style="color:#a0a1a7;font-style:italic;"&gt;If&amp;nbsp;an&amp;nbsp;application&amp;nbsp;interrupt&amp;nbsp;has&amp;nbsp;happened&amp;nbsp;since&amp;nbsp;the&amp;nbsp;last&amp;nbsp;time&amp;nbsp;sd_app_evt_wait&amp;nbsp;was&lt;/span&gt;&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;&lt;span style="color:#a0a1a7;font-style:italic;"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;called&amp;nbsp;this&amp;nbsp;function&amp;nbsp;will&amp;nbsp;return&amp;nbsp;immediately&amp;nbsp;and&amp;nbsp;not&amp;nbsp;go&amp;nbsp;to&amp;nbsp;sleep.&amp;nbsp;This&amp;nbsp;is&amp;nbsp;to&amp;nbsp;avoid&amp;nbsp;race&lt;/span&gt;&lt;/div&gt;
&lt;div style="padding-left:30px;"&gt;&lt;span style="color:#a0a1a7;font-style:italic;"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conditions&amp;nbsp;that&amp;nbsp;can&amp;nbsp;occur&amp;nbsp;when&amp;nbsp;a&amp;nbsp;flag&amp;nbsp;is&amp;nbsp;updated&amp;nbsp;in&amp;nbsp;the&amp;nbsp;interrupt&amp;nbsp;handler&amp;nbsp;and&amp;nbsp;processed&lt;/span&gt;&lt;span style="color:#a0a1a7;font-style:italic;"&gt; *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;in&amp;nbsp;the&amp;nbsp;main&amp;nbsp;loop.&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;- Due to the way FreeRTOS is written, however, reaching this code after running some other task implies that an interrupt has occurred because task switching is implemented using software interrupts. Hence, sd_app_evt_wait will not sleep.&lt;br /&gt;- If no task is executable after running vPortSuppressTicksAndSleep, it will get called again from the loop in prvIdleTask. This time it will sleep if no interrupt has occurred.&lt;br /&gt;&lt;br /&gt;Hence, if I do not check the NVIC-&amp;gt;ISPR flags in my &lt;span&gt;configPOST_SLEEP_PROCESSING&lt;/span&gt; handler and simply resume the main task, the system will never sleep since every call to sd_app_evt_wait is preceded by an interrupt (the one switching to the idle task).&lt;br /&gt;If I do check the NVIC-&amp;gt;ISPR flags in my &lt;span&gt;configPOST_SLEEP_PROCESSING&lt;/span&gt; I might sleep too much due to a very similar race condition that the non-FreeRTOS use of sd_app_evt_wait is free of.&lt;br /&gt;&lt;br /&gt;Say I have an interrupt that sets some atomic variable that leads the main loop to do something the next time it runs and given the following sequence switching away from the&amp;nbsp; main task:&lt;br /&gt;&lt;br /&gt;1 vTaskSuspend(main task)&lt;br /&gt;2 switch over to idle task via software interrupt&lt;br /&gt;3 prvIdleTask calls portSUPPRESS_TICKS_AND_SLEEP&lt;br /&gt;4 the critical region is entered&lt;br /&gt;5 sd_app_evt_wait is called, returns immediately&lt;br /&gt;6 &lt;span&gt;configPOST_SLEEP_PROCESSING&lt;/span&gt; is called&lt;br /&gt;7 &lt;span&gt;configPOST_SLEEP_PROCESSING&lt;/span&gt; checks the NVIC-&amp;gt;ISPR flags and decides the main task must not yet be unsuspended&lt;br /&gt;8 the critical region is exited&lt;br /&gt;9 prvIdleTask calls portSUPPRESS_TICKS_AND_SLEEP&lt;br /&gt;10 the critical region is entered&lt;br /&gt;11 sd_app_evt_wait is called, this time it sleeps&lt;br /&gt;12 ...&lt;br /&gt;&lt;br /&gt;If the interrupt that sets the atomic variable happens anytime after 1 and before 4, the main task may not get unsuspended until much later by another interrupt. It cannot be checked in the NVIC-&amp;gt;ISPR flag because it happened before entering the critical region and it will not cause the second sd_app_evt_wait to return immediatley (it will do so for the first sd_app_evt_wait, but the first one returns immediately in all cases because of the software-interrupt based task switching).&lt;br /&gt;&lt;br /&gt;Are these correct assumptions?&lt;br /&gt;Let me know if this helps or if I should attempt some minimal code example outlining my concern.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: FreeRTOS Race Condition with Tickless Idle and Suspending Tasks</title><link>https://devzone.nordicsemi.com/thread/288310?ContentTypeID=1</link><pubDate>Mon, 11 Jan 2021 08:48:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:450cd475-239c-4ff5-bcda-21e42ee381b7</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;Thanks for clearing that. Can you please do the same test with FreeRTOS from SDK17.2 and see if you see the same issue. If so, then I will have to spend more time on this.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: FreeRTOS Race Condition with Tickless Idle and Suspending Tasks</title><link>https://devzone.nordicsemi.com/thread/288277?ContentTypeID=1</link><pubDate>Sun, 10 Jan 2021 14:57:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6bd92027-203a-4cff-a090-ab92c9e5ad3f</guid><dc:creator>A Knecht</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;Thaks for the tip concerning SDK 17.2. I&amp;#39;ll copy over the new code.&lt;br /&gt;Concerning &lt;span&gt;configPOST_SLEEP_PROCESSING&lt;/span&gt; I&amp;#39;m not calling it manually at all. It is called from vPortSuppressTicksAndSleep defined in port_cmsis_systick.c. The only thing I&amp;#39;m calling is vTaskSuspend for the main task (enabling the idle task to run) and vTaskResume from within &lt;span&gt;configPOST_SLEEP_PROCESSING&lt;/span&gt; as in the snippet in the original post.&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: FreeRTOS Race Condition with Tickless Idle and Suspending Tasks</title><link>https://devzone.nordicsemi.com/thread/287189?ContentTypeID=1</link><pubDate>Mon, 04 Jan 2021 10:47:16 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:de13effa-c400-4633-abf9-92927ead3b7f</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;Hi Andreas,&lt;/p&gt;
&lt;p&gt;There were few bug fixes that came into the SDK after SDK14, I recommend you to download &lt;a href="http://developer.nordicsemi.com/nRF51_SDK/nRF5_SDK_v17.x.x/nRF5_SDK_17.0.2_d674dde.zip"&gt;SDK17.2&lt;/a&gt;&amp;nbsp;and replace your old SDK14\external\freertos folder with the new SDK17.2\external\freertos folder. This should work fine as this folder is independent of other SDK modules.&lt;/p&gt;
&lt;p&gt;Regarding the race condition,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Where are you calling&amp;nbsp;&lt;span&gt;&lt;span&gt;configPOST_SLEEP_PROCESSING from? if this is in the interrupt context then you should use&amp;nbsp;&lt;/span&gt;&lt;/span&gt;xTaskResumeFromISR inside this macro.&lt;/li&gt;
&lt;li&gt;It seems that your suspicion is correct about the race condition in the way you resume the main task, but i still do not have a full picture as i need to see the code where you call&amp;nbsp;&lt;span&gt;configPOST_SLEEP_PROCESSING.&amp;nbsp; Can you please attach the code snippet where you used it so that i can get better understanding of the probable race condition.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: FreeRTOS Race Condition with Tickless Idle and Suspending Tasks</title><link>https://devzone.nordicsemi.com/thread/286443?ContentTypeID=1</link><pubDate>Wed, 23 Dec 2020 11:48:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f40ab83a-d5c8-4044-b312-44b5482631ec</guid><dc:creator>Marte Myrvold</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;I&amp;#39;m afraid our FreeRTOS expert is out of office because of holiday season, and will not be back before the new year. I&amp;#39;ll forward your case to him as soon as he&amp;#39;s back.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Marte&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>