1
\$\begingroup\$

I'm developing a UI for embedded system application. I have to handle few critical tasks always which are being called in main infinite while() loop.

Program flow enters into sub-menu if key is pressed. Since sub-menu has its own infinite while() loop therefore control can not return back to main loop by on its own. It makes accessing of critical tasks impossible as long as sub-menu is active.

  • Is there any way to serve tasks in sub loop which are being called in main loop only?
  • One way of accessing is to call them in sub-loop as well. But I don't think its a right approach since UI has 50+ sub-menus and also does sub-loops.
\$\endgroup\$
  • \$\begingroup\$ It would help if you explained why you need another while loop inside sub-menu. Usually key pressing is detected inside main loop and appropriate function (to set up the menu) is called. And then returns to the main loop (where key pressing can be detected again). \$\endgroup\$ – Golaž Oct 1 '15 at 13:55
  • 1
    \$\begingroup\$ Have you considered using a preemptive RTOS like FreeRTOS, Or refactor you code into a event driven state machine. \$\endgroup\$ – Kvegaoro Oct 1 '15 at 14:20
  • \$\begingroup\$ @Golaž Every sub-menu has more then one menus inside it. If user wants to access one or more menus of every sub-menu then it is mandatory to keep control in sub-menu for sometime before returning to main loop. \$\endgroup\$ – M_Singh Oct 2 '15 at 5:22
  • \$\begingroup\$ @Kvegaoro I'm not using any RTOS here. Not familiar with "refactor code into a event driven state machine". \$\endgroup\$ – M_Singh Oct 2 '15 at 5:24
3
\$\begingroup\$

You have not mentioned which MCU you are using but looking at the tag I am assuming you are using PIC MCU. The best solution for your problem is to use FreeRTOS. FreeRTOS is available for PIC18 PIC24 PIC32. You can easily create as many task you want and can also include while(1) inside them.

xTaskCreate( vTask1, "Task 1", 240, NULL, 1, NULL );
xTaskCreate( vTask2, "Task 2", 240, NULL, 1, NULL );
xTaskCreate( vTask3, "Task 3", 240, NULL, 1, NULL );

void vTask1()
{
 for(;;)
 {
    PORTDbits.RD0 = 1;
    vTaskDelay( 1000 / portTICK_RATE_MS );
    PORTDbits.RD0 = 0;
    vTaskDelay( 1000 / portTICK_RATE_MS );

 }
}

same you can do for other task. Now all you need to do is run scheduler

vTaskStartScheduler();
\$\endgroup\$
1
\$\begingroup\$

There are many ways of doing this. The one I would use is to create a timer with a periodic interrupt, then call the critical tasks from the timer interrupt handler. The interrupt function will run all the time, no matter what other code is running in the main or sub menu loops.

Another method I have used is to put the call to the critical tasks in the 'wait for key' press function - while waiting for key, do critical taks. This has the advantage of being single threaded and having no concurrent data access issues, but it means you don't exactly know how often the critical tasks will be run - it depends on what the sub menu function has to do to process the key press, which will probably vary in different menus / sub-menus.

\$\endgroup\$
  • \$\begingroup\$ I am using first method(timer interrupt) already and it was helping till now. But i have to handle few new tasks which would update flag bits to EEprom based upon some events. Since parameters would update to EEprom using a loop(load all parameters at one shot to EEprom) so i can't call such functions in timer interrupt. Another method seems to be good, which means i have to call 'wait for key' press function in every sub menu? \$\endgroup\$ – M_Singh Oct 2 '15 at 5:18
  • \$\begingroup\$ Yes, don't you already do this? there must be some common function in your menu loops that recognises 'key press' events from the user. \$\endgroup\$ – Icy Oct 2 '15 at 7:07
  • \$\begingroup\$ Yes, I'm having function that recognises key press and does action accordingly. Ok, i would add another function that would do critical tasks if no key is pressed. This function has to call in every sub-menu so that crtical tasks can be accessed via every sub-menu/loop. \$\endgroup\$ – M_Singh Oct 3 '15 at 5:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.