[Solved] uMT Library - Problem!

Simplified code for my firmware:

#include <Arduino.h> 
#include <uMT.h>

void setup()
{
  Serial.begin(57600);
  my_umt_init();
  my_umt_tasks();
}

void my_umt_init(void)
{
  uMTcfg umtCfg;
  Kernel.Kn_GetConfiguration(umtCfg);
  umtCfg.rw.Tasks_Num = 20; //20 - 19 available, including the Arduino main loop()
  umtCfg.rw.Semaphores_Num = 32; //Semaphores : 32
  umtCfg.rw.AgentTimers_Num = 20; //20 agent timers

  umtCfg.rw.AppTasks_Stack_Size = 1024; //Size (in bytes) of the STACK for any new created TASK. // Task's Stack size: 1024 bytes
  umtCfg.rw.Task1_Stack_Size = 1024; //Size (in bytes) of the reserved STACK for the Arduino loop() TASK. 
  umtCfg.rw.Idle_Stack_Size = 512; // Idle task stack size : 512 bytes

  umtCfg.rw.BlinkingLED = false; 
  umtCfg.rw.IdleLED = false;
  umtCfg.rw.TimeSharingEnabled = false; //uMT_TICKS_TIMESHARING

  umt_CheckError(F("Kn_Start"), Kernel.Kn_Start(umtCfg));
}

void my_umt_tasks(void) {
  TaskId_t TEvev_2s;
  umt_CheckError(F("CrTsk - loop_2s"), Kernel.Tk_CreateTask(my_loop_2s, TEvev_2s));
  umt_CheckError(F("StTsk - loop_2s"), Kernel.Tk_StartTask(TEvev_2s));
}

void my_loop_2s(void)
{
  unsigned counter = 0;
  Event_t my_loop_2s;
  Event_t eventout;
  TimerId_t Timer_2s;
  umt_CheckError(F("loop_2s-Ev"), Kernel.Tm_EvEvery(2000, 2, Timer_2s));  // Wake up after ... seconds
  Serial.print(F("LOOP: => ")); Serial.println(F("  2Sec"));
  while (1)
  {
   umt_CheckError(F("loop_2s-Re"), Kernel.Ev_Receive(2, uMT_ANY, &eventout));
   Serial.print(F("  loop_2s: => ")); Serial.print(F("  KernelTickCounter => ")); Serial.println(Kernel.isr_Kn_GetKernelTick());
  
  umt_CheckError(F("Yield - test_func"), Kernel.Tk_Yield());
  Serial.print(F("LOOP: => ")); Serial.println(F("  2 - Yield"));
  }
}

void loop()
{
umt_CheckError(F("Yield - test_func"), Kernel.Tk_Yield());

umt_task_tst1();

//  while (1)
//  {
//umt_CheckError(F("Yield - test_func"), Kernel.Tk_Yield());
 //  umt_task_tst1();
//  }

  Serial.print(F("LOOP: => ")); Serial.print(F("  END"));
}

void umt_task_tst1(void) {
  TaskId_t Tid_T1;
  umt_CheckError(F("CrTsk - test1"), Kernel.Tk_CreateTask(umt_task_func_1, Tid_T1));
  umt_CheckError(F("StTsk - test1"), Kernel.Tk_StartTask(Tid_T1));
  Serial.print(F("Test_1: => ")); Serial.print(F("  START"));
  umt_CheckError(F("Yield - test_func"), Kernel.Tk_Yield());
}

void umt_task_func_1(void) {
  unsigned counter = 0;
  TaskId_t myTid;
  umt_CheckError(F("GetTid - test_func"), Kernel.Tk_GetMyTid(myTid));
  Serial.print(F(" Test_1: => ")); Serial.print(counter++); Serial.print(F("  KernelTickCounter => ")); Serial.println(Kernel.isr_Kn_GetKernelTick());
  umt_CheckError(F("DelTsk - test_func"), Kernel.Tk_DeleteTask(myTid));
}

void umt_task_func_2(void) {
  unsigned counter = 0;
  TaskId_t myTid;
  umt_CheckError(F("GetTid - test_func"), Kernel.Tk_GetMyTid(myTid));
  Serial.print(F(" Test_2: => ")); Serial.print(counter++); Serial.print(F("  KernelTickCounter => ")); Serial.println(Kernel.isr_Kn_GetKernelTick());
  umt_CheckError(F("Yield - test_func"), Kernel.Tk_Yield());
  while (1)
  {
    //Serial.print(F(" Test 2A: => ")); Serial.print(counter++); Serial.print(F("  KernelTickCounter => ")); Serial.println(Kernel.isr_Kn_GetKernelTick());
  }
}

void umt_CheckError(const __FlashStringHelper *Msg, Errno_t error)
{
  if (error != E_SUCCESS)
  {
    Serial.print(F("FATAL ERROR: ")); Serial.print(Msg); Serial.print(F(" - ERRNO = ")); Serial.println((unsigned)error); Serial.flush();
    Kernel.isr_Kn_FatalError();
  }
}

I don’t understand how the library works.
I need to run the "A" function, each specific amount of time. You also need to run the function "B" from "A".
As well as the "C" function from anywhere else.
My code stops the microcontroller.

The second problem.
When using this library, floating point calculations do not work.

Here is the code I use with uMT and a DUE:
part 1

#include <uMT.h>
#include <Wire.h>
#include "TFMini.h"
#include <Servo.h>
#include <SimpleDHT.h>


//*************************************************
// scl pin 5, sda pin 4, vcc 3.3
// temperature, pressure, altitude, sealevelpressure
#define BMP085_ADDRESS 0x77  // I2C address of BMP085
#define BMP_Interval 65503
const unsigned char OSS = 0;  // Oversampling Setting
// Calibration values
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;
// b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
// so ...Temperature(...) must be called before ...Pressure(...).
long b5;
//*********************************************
const String sSeperator = " ";
//*********************************************
Servo ServoLIDAR;
#define ServoLIDARPosit 1450
#define  byteServo_LIDAR_Pin 11
String sA = "";
//*********************************************
//X Axis servo
Servo X_Axis;
#define byteXaxisServoPin 9
#define iX_Posit90 1538 //using writeMicroseconds
int iX_HowMuch = iX_Posit90;
//Y Axis servo
Servo Y_Axis;
#define byteYaxisServoPin 10
#define iY_Posit90 1492 //using writeMicroseconds
int iY_HowMuch = iY_Posit90;
//*************************************************
TFMini tfmini;
// unsigned long lPreviousLIDAR_SequenceMillis = 0;
#define lLIDAR_SequenceInterval 50 // milliseconds
// 25mS is 40Hz
// 33mS ~30Hz
// 50mS 20Hz
// bool bBlankLIDAR = false;
//*************************************************
//
#define byteUnoDataReady 22
//*************************************************
// unsigned long lCurrentMillis = 0;
//*************************************************
//microwave motion detector= iMW
#define MWM_PINin 34
#define MWM_PINout 36
//*************************************************
// #define lLEDRateInterval 125 //milliseconds,  second
// unsigned long lPreviousLED_BlinkMillis = 0;
// bool bLedOnOff = false;
//*************************************************
String sMessageToSend;
String sPi;
//*************************************************
//*************************************************
// bool bRcveDone = false;
//*************************************************
// for DHT11,
//      VCC: 5V or 3V
//      GND: GND
//      DATA: 2
#define pinDHT11 2
SimpleDHT11 dht11(pinDHT11);
#define iDHT_Interval 60503
//*************************************************
#define iDoVolts_Interval 45007
//*************************************************
#define MINservo 1000
#define MAXservo 2000
#define SerialBaudRate 9600
#define Serial2BaudRate 115200
#define StringBufferSize 50
//*************************************************
// bool bTask2Started = false;
//*************************************************
#define EVENT_A  0x0001
TaskId_t iEvtID_A;
//
#define EVENT_B  0x0002
TaskId_t iEvtID_B;
//
#define EVENT_C  0x0003
TaskId_t iEvtID_C;
//
#define EVENT_D  0x0004
TaskId_t iEvtID_D;
//
#define EVENT_E  0x0005
TaskId_t iEvtID_E;
//
#define EVENT_F  0x0006
TaskId_t iEvtID_F;
//*************************************************
#define  SEM_ID_01   1   // Semaphore id
#define  SEM_ID_02   2   // Semaphore id
#define  SEM_ID_03   3   // Semaphore id
#define  SEM_ID_04   4   // Semaphore id
// #define TIMEOUT_A
//*************************************************
Stream* stream2Ptr;
//*************************************************


void setup()
{

  pinMode(40, OUTPUT);
  digitalWrite( 40, LOW );
  ////
  pinMode(byteUnoDataReady, OUTPUT);//setup interrupt pin as output
  digitalWrite(byteUnoDataReady, LOW);//set state initial
  ////
  Serial1.begin(TFMINI_BAUDRATE);
  // Initialize the TFMini LIDAR
  tfmini.begin(&Serial1);
  // Initialize single measurement mode with external trigger
  tfmini.setSingleScanMode();
  ////
  Serial2.begin( Serial2BaudRate );
  stream2Ptr = &Serial2;
  ////
  pinMode(MWM_PINin, INPUT);
  pinMode(MWM_PINout, OUTPUT);
  ////
  pinMode(LED_BUILTIN, OUTPUT);//blink LED at pin 13
  ////
  analogReadResolution( 12 );
  ////
  ServoLIDAR.attach( byteServo_LIDAR_Pin, MINservo, MAXservo );  // attaches the servo pin to the servo object
  ServoLIDAR.writeMicroseconds(ServoLIDARPosit);//sets initial posit
  ////
  X_Axis.attach( byteXaxisServoPin, MINservo, MAXservo );
  X_Axis.writeMicroseconds( iX_Posit90 );
  ////
  Y_Axis.attach( byteYaxisServoPin, MINservo, MAXservo );
  Y_Axis.writeMicroseconds( iY_Posit90 );
  ////
  Serial.begin(SerialBaudRate);
  ////
  // allocate a buffer in memory for these strings
  sMessageToSend.reserve( StringBufferSize );
  sPi.reserve( StringBufferSize );
  ////
  Wire.begin();
  bmp085Calibration();
  ////
  ADC->ADC_MR |= 0x80;  //set free running mode on ADC
  REG_ADC_MR = (REG_ADC_MR & 0xFFF0FFFF) | 0x00020000; // adc start up value
  // ADC->ADC_CHER = 0x80; //enable ADC on pin A0
  ////
  Kernel.Kn_Start();

} // setup()

Part2:

void loop()
{
  // if ( !bTask2Started )
  // {
  Errno_t error;

  TaskId_t fC_P;
  // fCheck_Pressure
  error = Kernel.Tk_CreateTask(fCheck_Pressure, fC_P);
  if ( error != E_SUCCESS )
  {
    fKernalError( "fCheck_Pressure", error );
  }
  ////
  // bTask2Started = !bTask2Started;
  ////
  Kernel.Tk_StartTask(fC_P);
  // fCheck_TH
  TaskId_t fC_TH;
  error = Kernel.Tk_CreateTask(fCheck_TH, fC_TH);
  if ( error != E_SUCCESS )
  {
    fKernalError( "fCheck_TH", error );
  }
  Kernel.Tk_StartTask( fC_TH ) ;
  // fCheckInputVoltage
  TaskId_t fDoVolts;
  error = Kernel.Tk_CreateTask( fCheckInputVoltage, fDoVolts );
  if ( error != E_SUCCESS )
  {
    fKernalError( "fCheckInputVoltage", error );
  }
  Kernel.Tk_StartTask( fDoVolts ) ;
  //  fDoLIDAR
  TaskId_t fLIDAR;
  error = Kernel.Tk_CreateTask( fDoLIDAR, fLIDAR );
  if ( error != E_SUCCESS )
  {
    fKernalError( "fDoLIDAR", error );
  }
  Kernel.Tk_StartTask( fLIDAR ) ;
  //    //
  //    ////////////////////////////
  //    ////////////////////////////
  //    ////////////////////////////
  // fReadSerial
  error = Kernel.Tk_CreateTask( fReadSerial, iEvtID_A );
  Kernel.Tk_StartTask( iEvtID_A );
  // fDO_bRcveDone
  error = Kernel.Tk_CreateTask( fDO_bRcveDone, iEvtID_B );
  Kernel.Tk_StartTask( iEvtID_B );
  // fTweakServoX
  error = Kernel.Tk_CreateTask( fTweakServoX, iEvtID_C );
  Kernel.Tk_StartTask( iEvtID_C );
  // fTweakServoY
  error = Kernel.Tk_CreateTask( fTweakServoY, iEvtID_D );
  Kernel.Tk_StartTask( iEvtID_D );
  // fLIDAR_ServoAspectChange
  error = Kernel.Tk_CreateTask( fLIDAR_ServoAspectChange, iEvtID_E );
  Kernel.Sm_Release( SEM_ID_02 ); // release a single SEMAPHORE token
  Kernel.Sm_Release( SEM_ID_03 );
  Kernel.Tk_StartTask( iEvtID_E );
  // fSendOut_SEMAPHORE
  error = Kernel.Tk_CreateTask( fSendOut_SEMAPHORE, iEvtID_F );
  Kernel.Sm_Release( SEM_ID_01 ); // release a single SEMAPHORE token
  Kernel.Tk_StartTask( iEvtID_F );
  ////////////////////////////////////////
  ////////////////////////////////////////
  ////////////////////////////////////////
  // }
  for ( ;; )
  {
    if ( stream2Ptr->available() >= 1 )
    // if (Serial2.available() >= 1)
    {
      Kernel.Ev_Send(iEvtID_A, EVENT_A);
      Kernel.Sm_Claim(SEM_ID_04, uMT_WAIT); // stop and wait for serial to be received and release of SEMAPHORE token
    }  //  serial available
    Kernel.Tk_Yield();
  }
} // loop
//******************************************
//******************************************
//******************************************
//
void fKernalError(String sTask, unsigned error)
{
  Serial.print( " Tk_CreateTask(): " + sTask + " Failure! - returned " );
  Serial.println( error );
  Serial.flush();
  Kernel.isr_Kn_FatalError();
} // void fKernalError()
//******************************************
//   digitalWriteDirect / digitalReadDirect
//******************************************
// example: digitalWriteDirect(13, HIGH)
inline void digitalWriteDirect(int pin, boolean val)
{
  if (val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
  else    g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}
// example: digitalReadDirect(12)
inline int digitalReadDirect(int pin)
{
  return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin);
}
//******************************************
//
//******************************************
//
//******************************************
//******************************************
///
//******************************************
void fDoLIDAR()
{
  //
  long iLIDAR_Distance = 0;
  long iLIDAR_Strength = 0;
  String sMsgToSend;
  String s_cm = "cm ";
  sMsgToSend.reserve( 16 );
  // Kernel.Tm_WakeupAfter( 1500 ); // long delay to allow platform to settle
  while (1)
  {
    Kernel.Tm_WakeupAfter( lLIDAR_SequenceInterval );   // Wake up after ... milliseconds
    Kernel.Sm_Claim(SEM_ID_02, uMT_WAIT); // // stop lidar servo
    Kernel.Sm_Claim(SEM_ID_03, uMT_WAIT); // stop x y servo
    //    if ( !bBlankLIDAR )
    //    {
    if ( digitalReadDirect( MWM_PINin ) )
      // if ( digitalRead( MWM_PINin ) == 1 )
    {
      digitalWriteDirect( MWM_PINout, HIGH );
      tfmini.externalTrigger();
      iLIDAR_Distance = tfmini.getDistance();
      iLIDAR_Strength = tfmini.getRecentSignalStrength();
      if (iLIDAR_Distance < 600)
      {
        // Serial.println( "TF Mini distance " + String(iLIDAR_Distance) + s_cm + " strength " + String(iLIDAR_Strength ) );
        // Serial.flush();
        sMsgToSend.concat( s_cm + String(iLIDAR_Distance) + " " + String(iLIDAR_Strength ) );
        Kernel.Sm_Claim(SEM_ID_01, uMT_WAIT); // // claim a single SEMAPHORE token
        sMessageToSend = sMsgToSend;
        Kernel.Ev_Send(iEvtID_F, EVENT_F);  // trigger fSendOut_SEMAPHORE + consume a single SEMAPHORE token
        sMsgToSend = "";
      }
    }
    else
    {
      digitalWriteDirect( MWM_PINout, LOW );
    }
    Kernel.Sm_Release( SEM_ID_02 ); // release a single SEMAPHORE token
    Kernel.Sm_Release( SEM_ID_03 );
  }
}
//******************************************
//      bmp085 functions
//******************************************
// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp085GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.

part3

long bmp085GetPressure(unsigned long up)
{
  long x1, x2, x3, b3, b6, p;
  unsigned long b4, b7;

  b6 = b5 - 4000;
  // Calculate B3
  x1 = (b2 * (b6 * b6) >> 12) >> 11;
  x2 = (ac2 * b6) >> 11;
  x3 = x1 + x2;
  b3 = (((((long)ac1) * 4 + x3) << OSS) + 2) >> 2;

  // Calculate B4
  x1 = (ac3 * b6) >> 13;
  x2 = (b1 * ((b6 * b6) >> 12)) >> 16;
  x3 = ((x1 + x2) + 2) >> 2;
  b4 = (ac4 * (unsigned long)(x3 + 32768)) >> 15;

  b7 = ((unsigned long)(up - b3) * (50000 >> OSS));
  if (b7 < 0x80000000)
    p = (b7 << 1) / b4;
  else
    p = (b7 / b4) << 1;

  x1 = (p >> 8) * (p >> 8);
  x1 = (x1 * 3038) >> 16;
  x2 = (-7357 * p) >> 16;
  p += (x1 + x2 + 3791) >> 4;

  return p;
}
// Calculate temperature given ut.
// Value returned will be in units of 0.1 deg C
short bmp085GetTemperature(unsigned int ut)
{
  long x1, x2;

  x1 = (((long)ut - (long)ac6) * (long)ac5) >> 15;
  x2 = ((long)mc << 11) / (x1 + md);
  b5 = x1 + x2;

  return ((b5 + 8) >> 4);
}
// Read the uncompensated pressure value
unsigned long bmp085ReadUP()
{
  unsigned char msb, lsb, xlsb;
  unsigned long up = 0;

  // Write 0x34+(OSS<<6) into register 0xF4
  // Request a pressure reading w/ oversampling setting
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x4 + (OSS << 6));
  Wire.endTransmission();

  // Wait for conversion, delay time dependent on OSS
  // delay(2 + (3 << OSS));
  Kernel.Tm_WakeupAfter( 2 + (3 << OSS) );
  // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF6);
  Wire.endTransmission();
  Wire.requestFrom(BMP085_ADDRESS, 3);

  // Wait for data to become available
  while (Wire.available() < 3)
    ;
  msb = Wire.read();
  lsb = Wire.read();
  xlsb = Wire.read();
  up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8 - OSS);

  return up;
}
// Read the uncompensated temperature value
unsigned int bmp085ReadUT()
{
  unsigned int ut;
  // Write 0x2E into Register 0xF4
  // This requests a temperature reading
  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x2E);
  Wire.endTransmission();
  // Wait at least 4.5ms
  Kernel.Tm_WakeupAfter( 5 );
  // delay(5);
  // Read two bytes from registers 0xF6 and 0xF7
  ut = bmp085ReadInt(0xF6);
  return ut;
}
// Stores all of the bmp085's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
void bmp085Calibration()
{
  ac1 = bmp085ReadInt(0xAA);
  ac2 = bmp085ReadInt(0xAC);
  ac3 = bmp085ReadInt(0xAE);
  ac4 = bmp085ReadInt(0xB0);
  ac5 = bmp085ReadInt(0xB2);
  ac5 = bmp085ReadInt(0xB2);
  ac6 = bmp085ReadInt(0xB4);
  b1 = bmp085ReadInt(0xB6);
  b2 = bmp085ReadInt(0xB8);
  mb = bmp085ReadInt(0xBA);
  mc = bmp085ReadInt(0xBC);
  md = bmp085ReadInt(0xBE);
}
// Read 2 bytes from the BMP085
// First byte will be from 'address'
// Second byte will be from 'address'+1
int bmp085ReadInt(unsigned char address)
{
  unsigned char msb, lsb;

  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();

  Wire.requestFrom(BMP085_ADDRESS, 2);
  while (Wire.available() < 2);
  msb = Wire.read();
  lsb = Wire.read();

  return (int) msb << 8 | lsb;
}
// Read 1 byte from the BMP085 at 'address'
char bmp085Read(unsigned char address)
{
  unsigned char data;

  Wire.beginTransmission(BMP085_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();

  Wire.requestFrom(BMP085_ADDRESS, 1);
  while (!Wire.available())
    ;

  return Wire.read();
}
void fCheck_Pressure()
{
  Errno_t error;
  // TimerId_t TmId;
  String sMsgToSend;
  sMsgToSend.reserve( StringBufferSize );
  short bmp_temperature;
  long bmp_pressure;
  // float bmp_altitude;
  //Serial.println( "do fCheck_Pressure" );
  //Serial.flush();
  while (1)
  {
    error = Kernel.Tm_WakeupAfter( BMP_Interval );   // Wake up after ... seconds
    if (error != E_SUCCESS)
    {
      Serial.print(F(" WakeupAfter(): Tm_WakeupAfter() Failure! - returned "));
      Serial.print((unsigned)error);
      Serial.flush();
      break;
    }
    if ( digitalReadDirect( MWM_PINin ) == 0 )
    {
      sMsgToSend = "Pa ";
      // Serial.println( "do fCheck_Pressure3" );
      // Serial.flush();
      bmp_temperature = bmp085GetTemperature(bmp085ReadUT());
      bmp_pressure = bmp085GetPressure(bmp085ReadUP());
      // sMsgToSend.concat( String(bmp_temperature) + sSeperator );
      sMsgToSend.concat( String(bmp_pressure) + sSeperator );
      // sMsgToSend.concat( String(bmp_altitude) + sSeperator );
      // Serial.println( sMsgToSend );
      // Serial.flush();
      Kernel.Sm_Claim(SEM_ID_01, uMT_WAIT); // // claim a single SEMAPHORE token
      sMessageToSend = sMsgToSend;
      Kernel.Ev_Send(iEvtID_F, EVENT_F);  // trigger fSendOut_SEMAPHORE + consume a single SEMAPHORE token
      sMsgToSend = "";
    }
  }
  //  // bTask2Started = false;
}
//******************************************
void fCheck_TH()
{
  // TimerId_t TmId1;
  String sMsgToSend;
  byte temperature = 0;
  byte humidity = 0;
  String sTH = "TH ";
  sMsgToSend.reserve( 16 );
  while (1)
  {
    Kernel.Tm_WakeupAfter( iDHT_Interval );   // Wake up after ... seconds
    if ( digitalReadDirect( MWM_PINin ) == 0 )
    {
      dht11.read(&temperature, &humidity, NULL);
      sMsgToSend = sTH;
      sMsgToSend.concat( String(temperature) + sSeperator + String(humidity) );
      // Serial.println( sMsgToSend );
      // Serial.flush();
      Kernel.Sm_Claim(SEM_ID_01, uMT_WAIT); // // claim a single SEMAPHORE token
      sMessageToSend = sMsgToSend;
      Kernel.Ev_Send(iEvtID_F, EVENT_F);  // trigger fSendOut_SEMAPHORE + consume a single SEMAPHORE token
      sMsgToSend = "";
    }
  } // while (1)
}
//******************************************
//
//******************************************

part4

//******************************************
//
//******************************************
void fDO_bRcveDone()
{
  String sAspectCng = "AspectCng";
  String s_gX = "gX";
  String s_gY = "gY";
  Event_t  eventoutB;
  while (1)
  {
    Kernel.Ev_Receive(EVENT_B, uMT_ANY, &eventoutB);
    digitalWriteDirect( 40, HIGH );
    sPi.replace( "/", " " );
    // sPi.trim();
    // Serial.println(sPi + " bRcveDone" );
    // Serial.flush();
    ////
    if (sPi.substring(0, 9) == sAspectCng)
    {
      // Serial.println(sPi + " rcvd" );
      sA = sPi.substring(9);
      Kernel.Ev_Send(iEvtID_E, EVENT_E);
      // Serial.println("AspectString " + sA );
      // Serial.flush();
    }
    ////
    // Serial.println( sPi.substring(0, 2) );
    if ( sPi.substring(0, 2) == s_gX )
    {
      // Serial.println(sPi);
      // Serial.flush();
      // stop lidar if lidar has token do not wait for freed token skip torque attempt
      if ( Kernel.Sm_Claim(SEM_ID_03, uMT_NOWAIT) != E_WOULD_BLOCK )
      {
        iX_HowMuch = sPi.substring(3).toInt();
        Kernel.Ev_Send(iEvtID_C, EVENT_C);
      }
    }
    ////
    if ( sPi.substring(0, 2) == s_gY )
    {
      // Serial.println(sPi);
      // Serial.flush();
      if ( Kernel.Sm_Claim(SEM_ID_03, uMT_NOWAIT) != E_WOULD_BLOCK )
      {
        iY_HowMuch = sPi.substring(3).toInt();
        Kernel.Ev_Send(iEvtID_D, EVENT_D);
      }
    }
    sPi = "";
    digitalWriteDirect( 40, LOW );
  }
}
//******************************************
//
//******************************************
void fReadSerial()
{
  //
  Event_t  eventoutA;
  char OneChar;
  while (1)
  {
    // Event_t  eventoutA;
    Kernel.Ev_Receive(EVENT_A, uMT_ANY, &eventoutA);
    ////
    while ( stream2Ptr->available() )
    {
      OneChar = stream2Ptr->read();
      if ( (OneChar != '\n') )
      {
        //Serial.println(sPi);
        sPi.concat( OneChar );
        // Serial.println(sPi + " char" );
        // Serial.flush();
        digitalWrite( 40, LOW );
      } // if ( (OneChar != '\n') )
      else
      {
        Kernel.Ev_Send(iEvtID_B, EVENT_B);  // trigger fDO_bRcveDone
        // bRcveDone = true;
        // Serial.println( "bRcveDone set true" );
        Serial.flush();
        break;
      } // if ( (chrOne != '\n') ) else
    } // while ( Serial2.available() )
    Kernel.Sm_Release( SEM_ID_04); // release serial avaible trigger in loop
  } //  while (1)
}
//******************************************
//
/*
  1000 u sec to 2000 u sec limit = 90 degrees of travel +/-45 deg
  1K = 45 to 2K = 135

*/
//******************************************
void fTweakServoX()
{
  Event_t  eventoutC;
  while (1)
  {
    Kernel.Ev_Receive(EVENT_C, uMT_ANY, &eventoutC);
    X_Axis.writeMicroseconds( iX_HowMuch );
    Kernel.Sm_Release( SEM_ID_03 );
  }
}
void fTweakServoY()
{
  Event_t  eventoutD;
  while (1)
  {
    Kernel.Ev_Receive(EVENT_D, uMT_ANY, &eventoutD);
    // Serial.println( "iY_HowMuch = " + String(iY_HowMuch) );
    Y_Axis.writeMicroseconds( iY_HowMuch );
    Kernel.Sm_Release( SEM_ID_03 );
  }
}
//******************************************
//  send data to RPi
//******************************************
void fSendOut_SEMAPHORE()
{
  Event_t  eventoutF;
  while (1)
  {
    Kernel.Ev_Receive(EVENT_F, uMT_ANY, &eventoutF);
    // Serial.println("fSendOut_SEMAPHORE 0 " + sMessageToSend );
    // Serial1.flush();
    if ( sMessageToSend.length() >= 2 )
    {
      // Serial.println("fSendOut_SEMAPHORE 1 " + sMessageToSend );
      // Serial.flush();
      stream2Ptr->println( sMessageToSend );
      digitalWrite(byteUnoDataReady, HIGH);//TRIGGER RPi3 to read data
      // delay( .05 );
      Kernel.Tm_WakeupAfter( 50 );
      // Serial.println( sMessageToSend.length() );
      // Serial.println("fSendOut_SEMAPHORE " + sMessageToSend );
      // Serial.flush();
      digitalWrite(byteUnoDataReady, LOW);//reset
      sMessageToSend = "";
      Kernel.Sm_Release( SEM_ID_01 ); // release a single SEMAPHORE token
    }
  }
}
//****************************************************
//
//****************************************************
void fLIDAR_ServoAspectChange()
{

  char fltBuff[32];
  String sAspectComplete = "AspectComplete";
  Event_t  eventoutE;
  String sMsgToSend;
  sMsgToSend.reserve( 16 );
  //
  while (1)
  {
    Kernel.Ev_Receive(EVENT_E, uMT_ANY, &eventoutE);
    Kernel.Sm_Claim(SEM_ID_02, uMT_WAIT); // // claim a single SEMAPHORE token.
    if ( sA.length() < 8 )
    {
      // bBlankLIDAR = true;
      sA.toCharArray(fltBuff, sizeof(fltBuff));
      float fltAspect = atof(fltBuff);
      //
      if (fltAspect > 900.00)
      {
        // Serial.println("AspectString " + String(sA));
        // Serial.flush();
        ServoLIDAR.writeMicroseconds(fltAspect);
      }
      //delay(20);
      // Serial.println( "AspectComplete " + sA );
      // Serial.flush();
    }
    else
    {
      Serial.println("AspectString reject " + String(sA));
    }
    // Serial.println( "fLIDAR_ServoAspectChange " + sMessageToSend );
    // Serial.flush();
    Kernel.Sm_Release( SEM_ID_02 ); // release a single SEMAPHORE token
    Kernel.Sm_Claim(SEM_ID_01, uMT_WAIT); // // claim a single SEMAPHORE token
    sMsgToSend = sAspectComplete;
    sMessageToSend = sMsgToSend;
    Kernel.Ev_Send(iEvtID_F, EVENT_F);  // trigger fSendOut_SEMAPHORE + consume a single SEMAPHORE token
    // bBlankLIDAR = false;
    //
  }
}
//******************************************
//
//******************************************
void fCheckInputVoltage()
{
  String sMsgToSend;
  String s_Volts = "VOLT ";
  sMsgToSend.reserve( 16 );
  while (1)
  {
    Kernel.Tm_WakeupAfter( iDoVolts_Interval );   // Wake up after ... seconds
    // Serial.println( "dovolt awake1" );
    // Serial.flush();
    if ( digitalReadDirect( MWM_PINin ) == 0 )
    {
      sMsgToSend = s_Volts;
      sMsgToSend.concat(String(analogRead(A0)));
      // Serial.println( "fCheckInputVoltage" + sMsgToSend );
      // Serial.flush();
      Kernel.Sm_Claim(SEM_ID_01, uMT_WAIT); // // claim a single SEMAPHORE token
      sMessageToSend = sMsgToSend;
      Kernel.Ev_Send(iEvtID_F, EVENT_F);  // trigger fSendOut_SEMAPHORE + consume a single SEMAPHORE token
      sMsgToSend = "";
      // Kernel.Sm_Release(SEM_ID_02);
    }
  }
}
//******************************************
//
//*************************************************

As you may notice I run the uMT tasks in several different ways and there is some floating point math being done. All worked great when I used the DUE to run that code. I have switched to using a ESP32 and freeRTOS several months back.

Question №1: Why start a task in loop (), rather than setup ()?

Yea, I could have moved the code in the task loop into setup and if you look at this line for ( ;; ) task loop is not really running anymore.

Here is some code using freeRTOS where putting code in the loop() is a no, no:

void setup()
{
  ////
  // create event group, make before timer trigger
  eg = xEventGroupCreate();
  Serial.begin( SerialDataBits );
  SerialBrain.begin( SerialDataBits );
  SerialTFMini.begin(  SerialDataBits, SERIAL_8N1, 27, 26 );
  // Initialize the TFMini LIDAR
  tfmini.begin(&SerialTFMini);
  vTaskDelay( pdMS_TO_TICKS( 3 ) );
  // Initialize single measurement mode with external trigger
  tfmini.setSingleScanMode();
  ////
  //// pinMode( BlinkLED, OUTPUT );//blink LED at pin 2
  ////
  ledcSetup ( Channel_X, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( XaxisServoPin, Channel_X );   //
  ledcWrite (Channel_X, usToTicks ( iX_Posit90 ) );       //
  vTaskDelay( ServoDelay60mS );
  ////
  ledcSetup( Channel_LIDAR, TIMER_FREQUENCY, TIMER_WIDTH); //
  ledcAttachPin( Servo_LIDAR_Pin, Channel_LIDAR);   //
  ledcWrite( Channel_LIDAR, usToTicks ( iLIDAR_Posit90 ) );
  vTaskDelay( ServoDelay60mS );
  ////
  ledcSetup ( Channel_Y, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( YaxisServoPin, Channel_Y );   //
  ledcWrite (Channel_Y, usToTicks ( iY_Posit90 ) );  //
  vTaskDelay( ServoDelay60mS );
  // make semaphores used in timer function before timer function begins
  sema_X = xSemaphoreCreateMutex();
  sema_Y = xSemaphoreCreateMutex();
  sema_LIDAR_FOR_ALARM = xSemaphoreCreateMutex();
  sema_SendSerialToBrain = xSemaphoreCreateMutex();
  ///////////// create queues
  // queue length, queue item size
  xQ_LIDAR_INFO = xQueueCreate( 1, sizeof(struct stu_LIDAR_INFO) ); // sends a queue copy
  xQ_X_INFO  = xQueueCreate( 1, sizeof( float ) ); // sends a queue copy
  xQ_Y_INFO  = xQueueCreate( 1, sizeof( float ) ); // sends a queue copy
  xQ_LIDAR_FOR_ALARM = xQueueCreate( 1, sizeof(struct stu_LIDAR_INFO) ); // sends a queue copy
  ////////////////////////  freeRTOS TASKS
  //////////////////////////////// TASK CORE 1 ///////////////////////////////////////////////////////////////////////////////////////////////////
  xTaskCreatePinnedToCore( fLIDAR_ServoAspectChange, "fLIDAR_ServoAspectChange", TaskStack20K, NULL, Priority4, &xHANDLE_LIDAR_ServoAspectChange, TaskCore1 ); // assigned to core
  sema_LIDAR_INFO = xSemaphoreCreateMutex();
  xSemaphoreGive( sema_LIDAR_INFO );
  xTaskCreatePinnedToCore( fDoLIDAR, "fDoLIDAR", TaskStack20K, NULL, Priority4, &xHANDLE_DoLIDAR, TaskCore1 ); //assigned to core
  sema_LIDAR = xSemaphoreCreateMutex();
  xSemaphoreGive ( sema_LIDAR );
  xSemaphoreGive ( sema_LIDAR_FOR_ALARM );
  xTaskCreatePinnedToCore( fSendLIDAR_InfoSerialToBrain, "fSendSerialToBrain", TaskStack20K, NULL, Priority3, &xHANDLE_SendLIDAR_InfoSerialToBrain, TaskCore1 ); // assigned to core
  // add in task handles and check if null
  xTaskCreatePinnedToCore( fLIDAR_Is_OK, "fLIDAR_Is_OK", TaskStack20K, NULL, Priority3, NULL, TaskCore1 ); // assigned to core
  //////////////////////////////// TASK CORE 0 ///////////////////////////////////////////////////////////////////////////////////////////////////
  xTaskCreatePinnedToCore( fSendSerialToBrain, "fSendSerialToBrain", TaskStack20K, NULL, Priority3, &xHANDLE_SendSerialToBrain, TaskCore0 ); // assigned to core
  xTaskCreatePinnedToCore( fTweakServoX, "fTweakServoXY", TaskStack20K, NULL, Priority3, &xHANDLE_TweakServoX, TaskCore1 ); // assigned to core
  xTaskCreatePinnedToCore( fTweakServoY, "fTweakServoXY", TaskStack20K, NULL, Priority3, &xHANDLE_TweakServoY, TaskCore1 ); // assigned to core
  xTaskCreatePinnedToCore ( fGetIMU, "v_getIMU", TaskStack40K, NULL, Priority4, &xHANDLE_GetIMU, TaskCore0 );
//  vTaskDelay ( 300 );
//  xEventGroupSetBits( eg, evtGetIMU );

} // setup()
////******************************************
void loop() {} // loop

Under freeRTOS the loop() must be kept empty. loop() has the lowest priority under freeRTOS and its main function is as cleanup, when it is allowed to run.

Also, under freeRTOS, vTaskDelay() does not stop program execution, instead the delayed method is put on hold and other tasks are allowed to run during the delay time.

Yes. And in the examples of the author of the library, the loop () loop does not actually work.
However, I cannot yet combine the tasks that are performed repeatedly and the one-time tasks.

Are the sub-tasks?

DrAngelOK:
Yes. And in the examples of the author of the library, the loop () loop does not actually work.
However, I cannot yet combine the tasks that are performed repeatedly and the one-time tasks.

Are the sub-tasks?

Well, as you may see how I wrote the code for the Due and my use of loop() works.

sub-tasks, do you mean tasks calling other tasks? You can do that.

Also, you may want to use Kernel.Tm_WakeupAfter( lLIDAR_SequenceInterval );  // Wake up after ... milliseconds for your timed tasks.

Actually, I am sure that all the things you have expressed a desire for are things I have done in my posted code.

I looked at your code.
There are the following questions:

  1. Why do you use the function: Kernel.Tm_WakeupAfter (60503); // Wake up after ... seconds
    but not:
    Kernel.Tm_EvEvery (60503, 2, Timer_2s).

  2. Why are all the interval values not even: 60503, 45007? Does this have any fundamental significance?

  3. I did not see your nested tasks. Your tasks are created and run by semaphores and events. And they are not created by the parent task.

  4. All tasks you have started immediately. I just can not start the task later.

DrAngelOK:

  1. Why do you use the function: Kernel.Tm_WakeupAfter (60503); // Wake up after ... seconds
    but not:
    Kernel.Tm_EvEvery (60503, 2, Timer_2s).

I am satisfied that sometime after the time code sent that the code be ran instead of preempting a running task and switching tasks. I want the current running task to complete, fully before being switched away. If I was using a multi core, I'd trigger a task on the other core to run, now and use Every or if I needed to run a preemptive task on a single core.

DrAngelOK:
2. Why are all the interval values not even: 60503, 45007? Does this have any fundamental significance?

Something I felt like doing at the time.

DrAngelOK:
3. I did not see your nested tasks. Your tasks are created and run by semaphores and events. And they are not created by the parent task.

What do you mean by sub-task?

DrAngelOK:
3. I did not see your nested tasks. Your tasks are created and run by semaphores and events. And they are not created by the parent task.

DrAngelOK:
4. All tasks you have started immediately. I just can not start the task later.

Not true. All the tasks are created immediately.

 error = Kernel.Tk_CreateTask( fTweakServoX, iEvtID_C );
  Kernel.Tk_StartTask( iEvtID_C );

After the task is created, the task is set to run but look at the task

void fTweakServoX()
{
  Event_t  eventoutC;
  while (1)
  {
    Kernel.Ev_Receive(EVENT_C, uMT_ANY, &eventoutC);
    X_Axis.writeMicroseconds( iX_HowMuch );
    Kernel.Sm_Release( SEM_ID_03 );
  }
}

As soon as fTweakServoX() is started it does this Event_t eventoutC;, than it does this while (1), and then runs into this mess Kernel.Ev_Receive(EVENT_C, uMT_ANY, &eventoutC);, where the task is stopped from further execution until the event is triggered. If EVENT_C never occurs the then the task will not run.

On the matter of sub tasks

Notice task fReadSerial() triggers the fDO_bRcveDone() task, which can trigger a number of tasks, a hierarchical task structure.

  1. Why are all the interval values not even: 60503, 45007? Does this have any fundamental significance?

I remember now, the odds of those two times having multiples of each other are rather large. Thus, the times that those two tasks may be triggered at the same time are lowered. Keep in mind that the DUE is a single core, keeping the number of tasks running at "the same time" low, improves performance per task.

Thank you for help.
I redid my Every function in WakeupAfter.

We are a little do not understand each other with nested tasks.
If you rely on your code, then I need something like this:

void setup()
{
	Errno_t error;
	TaskId_t fC_P;
	Kernel.Tk_CreateTask(fCheck_Pressure, fC_P);
	Kernel.Tk_StartTask(fC_P);
}

void fCheck_Pressure()
{
	while (1)
	{
		Kernel.Tm_WakeupAfter(1000);   // Wake up after ... seconds

		if (digitalReadDirect(MWM_PINin) == 0)
		{

			TaskId_t fC_TH;
			Kernel.Tk_CreateTask(fCheck_TH, fC_TH);
			Kernel.Tk_StartTask(fC_TH);
			//... or function fCheck_TH()
			Kernel.Tk_DeleteTask(fC_TH); //!!! 
		}
	}
}

void fCheck_TH()
{
	String sMsgToSend;
	byte temperature = 0;
	byte humidity = 0;
	String sTH = "TH ";
	sMsgToSend.reserve(16);
		if (digitalReadDirect(MWM_PINin) == 0)
		{
			dht11.read(&temperature, &humidity, NULL);
			sMsgToSend = sTH;
			sMsgToSend.concat(String(temperature) + sSeperator + String(humidity));
			Kernel.Sm_Claim(SEM_ID_01, uMT_WAIT);
			sMessageToSend = sMsgToSend;
			Kernel.Ev_Send(iEvtID_F, EVENT_F); // trigger fSendOut_SEMAPHORE + consume a single SEMAPHORE token
			sMsgToSend = "";
		}
	//Or Delete task This
}

Idahowalker:
I remember now, the odds of those two times having multiples of each other are rather large. Thus, the times that those two tasks may be triggered at the same time are lowered. Keep in mind that the DUE is a single core, keeping the number of tasks running at "the same time" low, improves performance per task.

I thought that the main task of the library is precisely to solve the problem of order of tasks.

Kernel.Tk_CreateTask(fCheck_TH, fC_TH);
			Kernel.Tk_StartTask(fC_TH);
			//... or function fCheck_TH()
			Kernel.Tk_DeleteTask(fC_TH); //!!!

, sure you can do it that way. You will experience the overhead of task creation and task resource allocation. When you can just create the task, start the task and trigger the task when you desire. Hey, programmers discretion.

DrAngelOK:
I thought that the main task of the library is precisely to solve the problem of order of tasks.

You ever do a thing cause you want to do the thing? That's a thing, I did cause I wanted to do the thing. No other reason. You can do the thing your way.