I'm currently writing a time-dependant embedded systems application, specifically on an ARM Cortex M4. It has a series of tasks that happen at different frequencies, and so, we're using the ARMs SysTick timer to keep track of time within a 1 second frame. A main busy loop waits until the timer has incremented and starts a task, as so:
void main(){
while(1){
if(!timerTicked)
continue; //timer hasn't updated since last loop, do nothing.
if(time==0)
toggleStatusLED();
if(time==0 || time==500){
twoHzTask(); //some task that must run twice a second
}
if(time%300==5){ //run at ms=5, 305 and 605
threeHzTask(); //some task that must run three times a second
}
}
}
void SysTick_increment(){ //Interrupt Service Routine for SysTick timer
time=(time+1)%1000;
}
This works perfectly for high-priority tasks that can't hang. In addition, high-priority tasks are allowed to take as long as they need to complete, however going over time may cause the system to go into fail-safe, depending on the task. However, I'd like to add a simple mechanism to abort non-mission-critical code that takes too long, like this:
void main(){
while(1){
if(time==500){ //run at ms=500
savingWorld=1;
saveTheWorld(); //super important task
savingWorld=0;
}
else if(time==750){
spinningWheels=1;
spinWheels(); //not very important task. Code for this function is immutable, can not alter it to support task cancellation.
spinningWheels=0;
}
}
}
void SysTick_increment(){ //Interrupt Service Routine for SysTick timer
time=(time+1)%1000;
if(time==900 && spinningWheels){
spinningWheels_cancel(); //we have more important stuff to do
}
}
As this is a basic embedded system I'd prefer not to introduce the complexity of an operating system or a multithreading mechanism. In addition, the rest of the system should be in a stable state after spinningWheels_cancel()
is called. That is to say, saveTheWorld()
should still work as expected. What's the simplest way to accomplish this?