<?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>Nested CRITICAL_REGION_ENTER/CRITICAL_REGION_EXIT</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/3303/nested-critical_region_enter-critical_region_exit</link><description>Are you supposed to be able to nest critical regions using CRITICAL_REGION_ENTER and CRITICAL_REGION_EXIT? Here I mean you have a function which uses a critical region to surround some work, and you call that function from within another critical region</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 28 Aug 2014 15:44:10 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/3303/nested-critical_region_enter-critical_region_exit" /><item><title>RE: Nested CRITICAL_REGION_ENTER/CRITICAL_REGION_EXIT</title><link>https://devzone.nordicsemi.com/thread/12041?ContentTypeID=1</link><pubDate>Thu, 28 Aug 2014 15:44:10 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dc598f10-f69e-425a-8d2d-721d4ad42a48</guid><dc:creator>RK</dc:creator><description>&lt;p&gt;You could do all those things. I wondered about this too and why this wasn&amp;#39;t part of the CMSIS routines and eventually decided that it&amp;#39;s because reading the current enabled state of an interrupt is fairly useless and subject to loads of race conditions.&lt;/p&gt;
&lt;p&gt;If you are a level 0 interrupt, it doesn&amp;#39;t matter, you aren&amp;#39;t getting interrupted anyway. If you are anything less, than reading the current state of the interrupts opens a window for a higher priority interrupt to change them and then you go set it back to what it was before and break it.&lt;/p&gt;
&lt;p&gt;If you disable all interrupts it doesn&amp;#39;t matter what they were before, you disabled all interrupts globally and re-enable them globally.&lt;/p&gt;
&lt;p&gt;A function to read the current enabled state of an interrupt isn&amp;#39;t needed as it&amp;#39;s just a function which will eventually hit a race condition and break something.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Nested CRITICAL_REGION_ENTER/CRITICAL_REGION_EXIT</title><link>https://devzone.nordicsemi.com/thread/12040?ContentTypeID=1</link><pubDate>Thu, 28 Aug 2014 11:07:52 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:315a7560-05f9-4be8-916a-85ddd58fec61</guid><dc:creator>Joe Merten</dc:creator><description>&lt;p&gt;Looks that I could check the lsb of &lt;code&gt;PRIMASK&lt;/code&gt; (determined by &lt;code&gt;__get_PRIMASK()&lt;/code&gt;) to check if irq currently is enabled or not.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Nested CRITICAL_REGION_ENTER/CRITICAL_REGION_EXIT</title><link>https://devzone.nordicsemi.com/thread/12039?ContentTypeID=1</link><pubDate>Thu, 28 Aug 2014 10:40:29 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:abbeea30-df38-494f-9f02-0b2cc9c8b0d3</guid><dc:creator>Joe Merten</dc:creator><description>&lt;p&gt;When wrote your own &lt;code&gt;CRITICAL_REGION_ENTER/EXIT()&lt;/code&gt;, should you also take care of irq enabled at the first call of &lt;code&gt;CRITICAL_REGION_ENTER()&lt;/code&gt;?
Hmm, what&amp;#39;s the call to determine if irq is enabled or not?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Nested CRITICAL_REGION_ENTER/CRITICAL_REGION_EXIT</title><link>https://devzone.nordicsemi.com/thread/12038?ContentTypeID=1</link><pubDate>Wed, 30 Jul 2014 14:08:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8014cda8-30dc-415c-9abb-9b7254bed194</guid><dc:creator>RK</dc:creator><description>&lt;p&gt;I finally managed to set up a test case to test this by using functions which call each other, each of which makes its own critical scope. Sort of like this&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void foo( void )
{
    CRITICAL_REGION_ENTER()
    .. do some work ..
    CRITICAL_REGION_EXIT()
}

void bar( void )
{
    CRITICAL_REGION_ENTER()
    .. do some other work ..
    foo();    // call foo
    .. and do a little cleanup work .. 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;#39;s not a particularly unusual pattern, when you have a protected resource it does happen you end up protecting your work and also then calling a helper function which protects the same thing.&lt;/p&gt;
&lt;p&gt;If you have the softdevice enabled then it works. The reason for that is that the sd_nvic_critical_region_enter()/exit() functions disable/enable the individual user interrupts, they don&amp;#39;t use __irq_disable() to disable everything, so the call to __irq_enable() makes no difference, only when the finally non-nested sd_nvic_critical_region_exit() is called are the individual interrupts re-enabled and then they fire.&lt;/p&gt;
&lt;p&gt;However if the soft device is &lt;em&gt;disabled&lt;/em&gt; then it does fail, but for a different reason than I expected. The first entry to the critical region disables interrupts. When you come to the second entry (this is before you exit the first one, because they are nested) sd_nvic_critical_region_enter() is called again, however interrupts are at that point disabled and emitting an SVC call with interrupts disabled is a hard fault, so it hard faults.&lt;/p&gt;
&lt;p&gt;Since I do have this issue I&amp;#39;ll write my own version of the wrapper which checks only the first time if the SD is enabled/disabled and then just calls it or the _&lt;em&gt;irq&lt;/em&gt;* functions and nests properly, my library code has to work with and without a softdevice enabled and needs the nested critical regions. I need more than just calling sd_nvic_critical_region() however as if the SD &lt;em&gt;is&lt;/em&gt; disabled, I do need to at some point call __irq_disable() to actually get the criticality.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Nested CRITICAL_REGION_ENTER/CRITICAL_REGION_EXIT</title><link>https://devzone.nordicsemi.com/thread/12037?ContentTypeID=1</link><pubDate>Wed, 30 Jul 2014 13:00:14 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:507d31ad-ac65-49d1-b10d-a3434c778dc6</guid><dc:creator>John</dc:creator><description>&lt;p&gt;From examining the SDK documentation on the macros and the soft device critical region functions, you cannot nest the critical regions using the macros. You can if you call the soft device functions yourself and manage the is nested flag yourself. As for the exit macro implementation, I&amp;#39;m not knowledgeable enough to comment.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>