<?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>Using the Scheduler  (8051 OSAL system to nRF51822)</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/3949/using-the-scheduler-8051-osal-system-to-nrf51822</link><description>Hi all, 
 I just had some general questions regarding events and timers on the nRF51822. I&amp;#39;m coming from a Ti CC2540 8051 which used an OSAL system. This made it quite easy to create events and sub-tasks, and handlers for each event and task. This allowed</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 01 Oct 2014 15:13:06 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/3949/using-the-scheduler-8051-osal-system-to-nrf51822" /><item><title>RE: Using the Scheduler  (8051 OSAL system to nRF51822)</title><link>https://devzone.nordicsemi.com/thread/14209?ContentTypeID=1</link><pubDate>Wed, 01 Oct 2014 15:13:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0cd24ad4-0566-4415-a92e-d9c7cf08d84b</guid><dc:creator>scytulip</dc:creator><description>&lt;p&gt;For question 3: I didn&amp;#39;t get your idea. Can&amp;#39;t you use one timer for toggling LED? You don&amp;#39;t need another timer to detect button status, as app_button will tell you when button is pushed or released. It might be helpful if you can share your code snippet.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Using the Scheduler  (8051 OSAL system to nRF51822)</title><link>https://devzone.nordicsemi.com/thread/14208?ContentTypeID=1</link><pubDate>Wed, 01 Oct 2014 15:06:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:61b8400c-efc9-44e3-a243-e1a8df36cac7</guid><dc:creator>scytulip</dc:creator><description>&lt;p&gt;For question 2: You didn&amp;#39;t see any advantage because your program is very simple. If your application needs to process intensive interruption requests and do complicated signal processing, intuitively, you may write many lines of code in the IRQ handler. In this case, a new interruption may be triggered when you&amp;#39;re still running the code in the old interruption&amp;#39;s handler. The CPU may lost the new interruption, or push the old handler into the stack, which easily overflows the stack during intensive operation. To avoid this, the best way is to make the IRQ handler as short as possible (enqueue the data), and execute the computation later. That&amp;#39;s why we need the scheduler.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Using the Scheduler  (8051 OSAL system to nRF51822)</title><link>https://devzone.nordicsemi.com/thread/14207?ContentTypeID=1</link><pubDate>Wed, 01 Oct 2014 14:50:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:30686969-37d4-4005-ac98-cca1aa82e771</guid><dc:creator>scytulip</dc:creator><description>&lt;p&gt;For question 1: Start your app_timer instance using &amp;quot;app_timer_start(your_timer_id,  APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER), NULL);&amp;quot; Your app_timer event will be triggered every 1s. app_timer provides a HAL thus you can define your own timer intervals but not fixed 0.03ms for RTC interruptions.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Using the Scheduler  (8051 OSAL system to nRF51822)</title><link>https://devzone.nordicsemi.com/thread/14206?ContentTypeID=1</link><pubDate>Wed, 01 Oct 2014 04:36:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9f3a031a-f35c-4500-bea0-40c26bf3f471</guid><dc:creator>Locky</dc:creator><description>&lt;p&gt;Thank you for the response.  I actually had coded something quite similar to your suggestion.  But I have a few issues:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;I believe the 2nd Scheduler implementation example you showed is what I am trying to do.  I have a &lt;strong&gt;button_timer.c&lt;/strong&gt; class similar to the 1sec timer you suggested, which could &amp;quot;put&amp;quot; events in the queue.  The handler of for this event in &lt;strong&gt;main.c&lt;/strong&gt; could then handle toggling LEDs.   I don&amp;#39;t need sub msec timing for execution as its controlling LED events.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I&amp;#39;m not entirely clear what advantage there is to enabling the Scheduler parameter of a timer.  I understand how it will execute from the main loop rather then have the timer handler run as an interrupt.  But I don&amp;#39;t see how that really makes a difference.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I am trying to code things in a modular way.  So all my peripheral timers are coded in separate classes.   The &lt;strong&gt;button_timer&lt;/strong&gt; class which handles the 1 second timing is controlled from &lt;strong&gt;main.c&lt;/strong&gt;.   But on timeout in  &lt;strong&gt;button_timer.c&lt;/strong&gt; I don&amp;#39;t have a way to trigger &lt;strong&gt;main.c&lt;/strong&gt; to toggle LEDs.    I could have another timer with a handler residing in &lt;strong&gt;main.c&lt;/strong&gt; which I start from &lt;strong&gt;button_timer&lt;/strong&gt; to execute LED toggles on timeout.  I just give it a very short timeout parameter.  But now things would get quite messy having to code timers just to simulate real-time event handling.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Can anyone else who has migrated from the CC2540/2541 comment on this?  Thanks&lt;/p&gt;
&lt;p&gt;p.s. Again I don&amp;#39;t need greater than 10msec timing accuracy for this as it is reacting to a user pressing a button.&lt;/p&gt;
&lt;p&gt;EDIT:  Just to tie off this thread, I found an answer in the post.&lt;br /&gt;
&lt;a href="https://devzone.nordicsemi.com/question/17526/examples-using-the-scheduler/"&gt;devzone.nordicsemi.com/.../&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thanks guys&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Using the Scheduler  (8051 OSAL system to nRF51822)</title><link>https://devzone.nordicsemi.com/thread/14205?ContentTypeID=1</link><pubDate>Tue, 30 Sep 2014 14:57:40 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:39fe401f-a7e3-4462-9799-5aae89bdb14a</guid><dc:creator>scytulip</dc:creator><description>&lt;p&gt;Hi. Scheduler in nRF51822 is used to queue the &lt;strong&gt;non-real-time&lt;/strong&gt; operation and release the interruption resources quickly. It is equivalent to the traditional flag setting/resetting in the IRQ processing. For instance, a traditional IRQ processing is like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void xxx_IRQHandler(void)
{
    ....
    xxx_flag = true;
    ....
}

int main(void)
{
    for(;;)
    {
    	....
        if (xxx_flag == true) { /* Process interruption here */ }
        ....
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The alternative version using scheduler is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void xxx_IRQHandler(void)
{
    ....
    err_code = app_sched_event_put(..., xxx_func);
    ....
}

void xxx_func(void *p_event_data, uint16_t event_size)
{
    /* Process interruption here */
}

int main(void)
{
    ....
    for (;;)
    {
        err_code = sd_app_evt_wait();
        APP_ERROR_CHECK(err_code);
        app_sched_execute();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The queued operation may be executed at anytime. For your application, if you need instant response occurred at the exact time, scheduler may be not a good solution. What you can do is first register a button event using app_button,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static void button_evt_handler(uint8_t pin_no, uint8_t button_action)
{
    ....
    if (pin_no == BUTTON_PIN_NO &amp;amp;&amp;amp; button_action == APP_BUTTON_PUSH)
    {
        button_pushed = true;
        count = 0;
    } else if (pin_no == BUTTON_PIN_NO &amp;amp;&amp;amp; button_action == APP_BUTTON_RELEASE)
    {
        button_pushed = false;
        count = 0;
    }
    ....
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then register an app_timer triggered every 1s,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void timer_timeout_handler(void *p_context)
{
    ....
    if (button_pushed == true)
    {
        count ++;
        switch(count)
        {
            case 2: /* Turn on Red LED */
            case 3: /* Turn off LED */
            case 5: /* Trigger a buzzer */
            ....
         }
     }
     ....
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That should be fine. BTW, no matter how many app_timer instance you registered, there&amp;#39;s only one hardware timer used. (In fact, nRF51822 has only two RTCs, and another is occupied if you&amp;#39;re using the SoftDevice.) app_timer can respond to the RTC interruption, and distribute tasks among different app_timer instances. So don&amp;#39;t worry about how many &amp;quot;timers&amp;quot; you&amp;#39;re using. Particularly, when you initialize the app_timer using&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, true);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last parameter of &lt;code&gt;true&lt;/code&gt; means scheduler is enabled. All your app_timer event handler will be automatically queued and executed by the scheduler.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>