0
\$\begingroup\$

This is a general question about designing firmware for AVR microcontrollers, say, the AtMega16.

I have a routine that I am running through several thousand times per second. The routine is entirely interrupt driven outside of the main loop. I can still run code in the main loop, but it takes too long to operate with several thousand interrupts a second.

I would like to have a routine that scans for incoming data and modifies a variable that the interrupt-driven routine uses. This routine should be asynchronous to the interrupt-driven loop. The variable(s) will change whenever the second routine is ready. Until then, the interrupt-loop should continue running as it was before.

Imagine two processors that share direct CPU access to a common variable. They are both doing different jobs, but one reads the state of the other over the variable. Is there any way of simulating this setup on a single processor? I understand I may have to sacrifice processing power/speed for each routine to make this possible, but my interrupt-driven routine will naturally react to how fast the CPU can run it.

\$\endgroup\$
  • 1
    \$\begingroup\$ This is software, nothing to do with electronic design, and should be closed. \$\endgroup\$ – Leon Heller Jul 17 at 17:38
  • 2
    \$\begingroup\$ @Leon Heller I was debating about posting this on the Stack Overflow, but the help center specifically states that this forum is used for "the writing of firmware for bare-metal or RTOS applications" \$\endgroup\$ – Judson Hudson Jul 17 at 17:44
  • 1
    \$\begingroup\$ Ok ... so then run an OS on your AVR ... FreeRTOS is popular (if you don't mind the bloat). \$\endgroup\$ – brhans Jul 17 at 17:53
  • 1
    \$\begingroup\$ Anything you want to execute in a single core microcontroller in a defined time will have to be driven by interrupts. Stuff in the main loop just uses whatever free time is available. You can have a variable that accumulates 'tasks' e.g. incoming data that needs to be processed, that is incremented by event-driven interrupts, and apportion the number of timer-driven interrupts that are dedicated to doing those tasks. A kind of crude multitasking setup. \$\endgroup\$ – Phil G Jul 17 at 18:09
  • 3
    \$\begingroup\$ Once you start talking about interrupts and timing-sensitive code, that's definitely on-topic. \$\endgroup\$ – W5VO Jul 17 at 18:27
5
\$\begingroup\$

What you are describing are two genuine threads. The ISR and the main routine share the same memory space. For your simple application it is not necessary to use an RTOS. To communicate between the two threads you need a global variable, and you need to declare it to be volatile in C so that the compiler doesn't try to optimize accesses to it.

You also need to be sure that all accesses to the global variable are atomic, meaning that changes to the variable cannot be interrupted. The simplest way of doing this is to disable all interrupts, modify or read the global variable, then enable the interrupts.

\$\endgroup\$

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.