Serial.print different behavior before/after function pointers assignments

Hi,

this is my latest work on thread manager.

Note: my goal is to do it in C for now.

  1. task_manager.h
#ifndef task_manager_h
#define task_manager_h

#include <inttypes.h>
#include <Arduino.h>
#include <SPI.h>
#include <string.h>
#include <avr/pgmspace.h>
#include <avr/io.h>

////////////////////////////////////////////////////////////////////////////////////////
// enumerations
typedef enum: uint8_t {NOT_FINISHED, FINISHED, DONE}STATE;
//typedef enum: bool {NOT_FINISHED, FINISHED}STATE;

// variables
typedef void (*f_ptr)();
typedef void args;

// structs
typedef struct __attribute__((__packed__)) TASK{
    uint8_t args_cnts;
	args    *tsk_args;
	f_ptr   tsk_fptr;
}TASK;

typedef struct __attribute__((__packed__)) THREAD{
	uint8_t tsk_cnts;               // task counts
	uint8_t tsk_cntr;               // task counter
	STATE   thrd_st;                // thread flag states
	STATE   *tsk_st;				// ptr to tsk_st in other scr files               
}THREAD;

//functions/////////////////////////////////////////////////////////////////////////////
// threads
				 
void run_thread(THREAD *thrd, TASK *tsk);

#endif
  1. task_manager.cpp
#include "task_manager.h"
#include "glcd_spi.h"

////////////////////////////////////////////////////////////////////////////////////////////
// main functions definitions

void run_thread(THREAD *thrd, TASK *tsk){
	if(thrd->thrd_st == NOT_FINISHED){									// check if thread finished all tasks
		if((thrd->tsk_cntr) < (thrd->tsk_cnts)){						// check linear task execution
			if(*((STATE*)thrd->tsk_st) == NOT_FINISHED){				// check this task is NOT_FINISHED
				switch((tsk+thrd->tsk_cntr)->args_cnts){				// run task by args_cnts
					case 0:	// dereferencing 0 args
						((void(*)())(tsk+thrd->tsk_cntr)->tsk_fptr)();
					break;

					case 1: // dereferencing 1 args
						((void(*)(uint8_t*))(tsk+thrd->tsk_cntr)->tsk_fptr)(
						(uint8_t*)(tsk+thrd->tsk_cntr)->tsk_args+0);
					break;

					case 2: // dereferencing 2 args
						((void(*)(uint8_t*,uint8_t*))(tsk+thrd->tsk_cntr)->tsk_fptr)(
						(uint8_t*)(tsk+thrd->tsk_cntr)->tsk_args+0,
						(uint8_t*)(tsk+thrd->tsk_cntr)->tsk_args+1);
					break;
					
					case 3: // dereferencing 3 args
						((void(*)(uint8_t*,uint8_t*,uint8_t*))
						(tsk+thrd->tsk_cntr)->tsk_fptr)(
						(uint8_t*)(tsk+thrd->tsk_cntr)->tsk_args+0,
						(uint8_t*)(tsk+thrd->tsk_cntr)->tsk_args+1,
						(uint8_t*)(tsk+thrd->tsk_cntr)->tsk_args+2);
					break;

					case 4: // dereferencing 4 args
						((void(*)(uint8_t*,uint8_t*,uint8_t*,uint8_t*))
						(tsk+thrd->tsk_cntr)->tsk_fptr)(
						(uint8_t*)(tsk+thrd->tsk_cntr)->tsk_args+0,
						(uint8_t*)(tsk+thrd->tsk_cntr)->tsk_args+1,
						(uint8_t*)(tsk+thrd->tsk_cntr)->tsk_args+2,
						(uint8_t*)(tsk+thrd->tsk_cntr)->tsk_args+3);
					break;
				}
			}
			else{											// if current task is finished
				Serial.print("thrd->tsk_cntr"); Serial.println(thrd->tsk_cntr);
				thrd->tsk_cntr++;							// go to next task
				*((STATE*)thrd->tsk_st) = NOT_FINISHED;		// reset finish st flag	
			}
		}
	}
	else{
		Serial.println("thrd FINISHED");
		*((STATE*)thrd->thrd_st) = FINISHED;
	}
}
  1. program_run.ino
#include "task_manager.h"
#include "glcd_spi.h"
#include "sensors_modules.h"
#include "arrays.h"

extern STATE lcd_st_flag;

void setup() {
  Serial.begin(9600);
  ///////////////////////////////////// LCD THREAD /////////////////////////////////////
  // allocate & initialize lcd thread
  THREAD *lcd = (THREAD*)malloc(1*sizeof(THREAD));
  TASK *lcd_tsk = (TASK*)malloc(4*sizeof(TASK)); // method #1

  // lcd thread initialization
  *lcd = (THREAD){4,0,NOT_FINISHED,&lcd_st_flag};
  
  // lcd task initialization
  *(lcd_tsk+0) = (TASK){0,(uint8_t*)0,(void(*)())glcd_init};
  *(lcd_tsk+1) = (TASK){1,(uint8_t*)1,(void(*)())glcd_graphics_mode};
  *(lcd_tsk+2) = (TASK){0,(uint8_t*)0,(void(*)())glcd_clr};
  *(lcd_tsk+3) = (TASK){1,(uint8_t*)&PIC3,(void(*)())glcd_img};
  
  while(lcd->thrd_st != FINISHED){
    run_thread(lcd, lcd_tsk);
  }

  ///////////////////////////////////// SERIAL THREAD /////////////////////////////////////  

  Serial.println("thread finished");
  
}

What you think ? How about my code ? I know there's a lot of casting :slight_smile:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.