Electronic – Thread alternatives for embedded systems

cpic

I'm currently studying electrical engineering. Due to the pandemics, my classes were suspended and I'm using this time learning more about electronics and programming.

I'm currently trying to use a Pic16f628a and a generic digital display to build a digital clock with some features. The thing, is that I'd had to access a menu pressing a button in execution time, while the clock is being displayed. Normally I'd call a thread for the clock display and the main thread would be watching for inputs, but due to the simplicity of the pic controller I can't use the resource.

So, my C code (not yet implemented specifically to pic) is something like this:

void display_timer(){
  static struct current_time timer;
  static int is_time_set = 0;
  set_current_time(&timer, &is_time_set);

  while (is_time_set){
    system("clear");
    printf("########\n");
    printf("%d:%d:%d\n", timer.HOURS, timer.MINUTES, timer.SECONDS);
    printf("########\n");
    sleep(1);
    update_timer(&timer, &is_time_set);
  }
}
int main ()
{
  while (1){
    display_menu();

  }
}

During the sleep(), the controller would have to be able to watch for new inputs and act correspondingly.

One alternative I though was to use a state machine to store a button press, dividing the sleep function into 4 or 8 intervals, something like this:

  while (is_time_set){
    system("clear");
    printf("########\n");
    printf("%d:%d:%d\n", timer.HOURS, timer.MINUTES, timer.SECONDS);
    printf("########\n");
    for (int i = 0; i<8; i++){
    if (state_machine_input == 1){state_machine_input = 0; break;}
    sleep(1/8);
    }
    update_timer(&timer, &is_time_set);

It could be done, but I'd appreciate if I'd not have to add more complexity to the project, adding another state machine for example. What could I do in therms of software to implement this functionality?

Best Answer

Threading is a higher level concept than microcontroller programming. Simply put, threads are implemented as a scheduler that uses timer interrupts, which in turn saves the program counter + stack pointer etc and sets those to different locations. So it is quite possible and easy to implement a similar concept using interrupts - with the benefit that you get specialized interrupts instead of generic multi-threading.

That's about the only sensible way to do it with a restricted legacy 8 bitter like PIC, which is extremely limited when it comes to stack use. Forget about using thread libs, even those written for microcontrollers. That will only add excessive bloat and complexity, for nothing gained. It is a bad idea in general to drag PC programming concepts into the embedded world.

What you should be doing, is to put your button scanning inside a cyclic timer interrupt that's executed once per 10ms or so. From inside the interrupt, you poll the buttons and compare the button read with the previous once, for debouncing purposes. The result of this is stored in a variable shared with the main program, declared as volatile and protected from race conditions. Since you only write to the variable from inside the interrupts, it may be sufficient protection to ensure that reads are 8 bits, but you must disassemble to be sure. More info about that here: Using volatile in embedded C development.