Coder Social home page Coder Social logo

heliosproj / helios Goto Github PK

View Code? Open in Web Editor NEW
351.0 23.0 44.0 12.64 MB

A community delivered, open source embedded operating system project.

Home Page: http://www.heliosproj.org

License: GNU General Public License v2.0

C 92.47% C++ 0.22% Shell 7.31%
rtos arduino arm avr freertos multitasking operating-system os real-time sam teensy zephyr embedded

helios's Introduction

HeliOS Logo

License: GPL Version 2 GitHub last commit GitHub release (latest by date) PlatformIO Registry arduino-library-badge GitHub stars GitHub watchers


🚀 Overview

HeliOS is an open source embedded operating system that is free for everyone to use. While called an operating system, HeliOS is a multitasking kernel for use in embedded applications. Its rich, fully documented, API allows the user to control every aspect of the system and access kernel services (syscalls) for task (process) management, scheduler management, inter-process communication, memory management, device management (i.e., device drivers) and more while maintaining a tiny footprint for a broad range of low-power embedded devices. HeliOS is also easily customized to fit the user’s specific needs through a single header file /src/config.h.

HeliOS supports two multitasking models that can be leveraged concurrently within the same application. The first multitasking model is event-driven. When a task is placed in the "waiting" state, the task will only respond to task events. HeliOS supports two types of task events. The first is direct-to-task notifications, which allow one task to send a notification to another task. In this scenario, the HeliOS scheduler will wake the recipient task and schedule it for execution. After the recipient task clears the direct-to-task notification, the recipient task will returning to "waiting" until another notification is received. The second type of task event is timer based. Task timers can be configured to tell HeliOS to schedule the task to run every so many ticks (typically milliseconds), though task timers should not be confused with application timers (or simply timers) as HeliOS supports both.

The second model for multitasking is a conventional cooperative model. In this model, cooperative tasks are always scheduled to run, unless suspended. Additionally, the cooperative model in HeliOS contains a unique scheduler feature that builds on the traditional cooperative model. In most cooperatively scheduled multitasking models, a simple round-robin approach is used (i.e., each task is executed consecutively). However, the HeliOS scheduler uses a “runtime balanced” algorithm for scheduling cooperative tasks. In other words, tasks that consume more runtime are deprioritized (i.e., executed less frequently) in favor of tasks that consume less runtime. This design prevents long running tasks from monopolizing the system’s execution time. Event-driven and cooperatively scheduled tasks run together seamlessly, although event-driven tasks always receive execution priority over cooperatively scheduled tasks.

One important aspect of multitasking in HeliOS is it does not rely on context switching. This reduces the need for the user to manage access to shared resources in a “thread safe” way using mutexes and semaphores. This also eliminates the need for the “port” or portability code required to save the context during a context switch. As a result, the user can focus his or her development effort on their specific application without having to contend with concurrent access to shared resources. Like everything in life, there are drawbacks. While a conventional cooperative model spares the user from contending with concurrent access to shared resources, if a task does not relinquish control to the HeliOS scheduler, it will monopolize all available runtime. This also means that the HeliOS scheduler does not enforce hard-timing (i.e., real-time). The HeliOS scheduler enforces soft-timing so if a waiting task timer has elapsed, the scheduler will prioritize the task but may miss the "deadline".

HeliOS also provides services for three inter-process communication models. The first, as discussed previously, is direct-to-task notifications. Direct-to-task notifications are an efficient communication channel between tasks that prevent a task from consuming runtime when there is nothing for the task to process. The second model is message queues. Message queues can be created at runtime and can be shared among any number of tasks. Queues are highly flexible FIFO communication channels that require very little code to implement. The third model is stream buffers. Stream buffers are very much like message queues with one important difference. While queues operate on multi-byte messages, stream buffers operate similarly on single-byte streams. Finally, while technically not one of HeliOS’s models for inter-process communication, HeliOS supports task parameters that can be leveraged for rudimentary inter-process communication if so desired.

The HeliOS kernel includes built-in memory management that improves the safety margin of dynamically allocated memory. While HeliOS’s dynamic memory allocation allocates “heap” memory, the heap in HeliOS is not a true heap. HeliOS uses a private heap that is implemented as static memory allocated at compile time. HeliOS does not use the standard library malloc() and free() functions and it is recommended that the user also avoid those functions in favor of HeliOS’s memory management syscalls. HeliOS also maintains a separate memory region for kernel objects which reduces the risk that memory access, in the user's application, would corrupt critical kernel objects. As of kernel 0.4.0, HeliOS also supports sophisticated memory defragmentation and consistency checking to ensure memory is utilized efficiently and with a high degree of integrity.

HeliOS also supports a kernel mode device driver model. Device drivers for virtually any feature or peripheral can be easily developed using the provided device driver template. While device drivers are not needed in most applications, when the microcontroller's MMU or MPU is enabled it may not be possible to access memory mapped registers and I/O from the user's code. While implementation of the ARM MMU and MPU in HeliOS is forthcoming, device driver support had to be added to HeliOS first. Information about the device driver system calls can be found in the HeliOS Developer's Guide. A device driver template can be found here /drivers/template/driver.c and here /drivers/template/driver.h.

HeliOS is built to be robust. HeliOS (0.3.0 and later) has undergone static analysis testing using a commercially licensed static analysis tool as well as MISRA C:2012 checks. While HeliOS is NOT certified for nor should be used (in full or in part) in any safety-critical application where a risk to life exists, user’s can be confident they are building their embedded application on a robust embedded operating system.

Lastly, for PlatformIO and Arduino users, HeliOS is easily added to their embedded application. The latest release of HeliOS is available directly through the PlatformIO Registry and the Arduino Library Manager. For users of other embedded platforms and/or tool-chains, simply download the latest release of HeliOS from GitHub and add the sources to your project.


📢 What's New

The HeliOS 0.4.x series kernel was recently released which supersedes all prior kernel versions. The syscall API and internals have undergone significant development rendering applications built on earlier kernels incompatible with 0.4.x. The key change that will impact compatibility is the introduction of a consistent return type for all syscalls. This provides a better mechanism for error propagation and a consistent interface handling errors.

For example, prior to kernel 0.4.0, a task would be created as follows.

xTask task = xTaskCreate("TASKMAIN", task_main, NULL);

if(task) {
  /* Use the task here. */
}

In this example, the user application would only know if an error or exception occurred by checking if "task" was null. In kernel 0.4.0 all syscalls have a standard return type xReturn that can either be ReturnOK or ReturnError. See the HeliOS Developer's Guide for more information about xReturn. Thus, in kernel 0.4.0 the same process of creating a task is done as follows.

xTask task;

if(ERROR(xTaskCreate(&task, (const xByte *) "TASKMAIN", task_main, null))) {
  xSystemHalt();
}

/* Use the task here. */

In this manner, the application can check all syscalls for success or failure even when a syscall does not modify or set arguments it is passed. For the very latest on what development is occurring, please check out the HeliOS Trello board. Anyone wanting to contribute to HeliOS should refer to the “Contributing” section.


🖱️ HeliOS Around The Web


🎯 Getting Started

Documentation

The HeliOS syscall API is documented in the HeliOS Developer's Guide. If you are in need of support, please refer to the "Contributing" section on how to submit an issue.

Arduino IDE

Using the HeliOS embedded operating system in your Arduino sketch could not be easier. Open the Arduino IDE and use the Library Manager to search for and install HeliOS. The folks at Arduino have documented the steps to install a library here. Once installed, you can experiment with the example sketches that are included with HeliOS and can be found under File -> Examples -> HeliOS in the Arduino IDE.

PlatformIO IDE

HeliOS is also available directly through the PlatformIO registry and can be added to your project either from the PlatformIO GUI or CLI. The steps for which are described in the PlatformIO documentation here. Like the Arduino IDE, several examples are included with HeliOS for you to experiment with.

ARM Cortex-M

If more advanced features are desired, HeliOS also has built-in support for CMSIS on ARM Cortex-M microcontrollers and can be easily integrated into your Keil uVision or vendor IDE project by:

  1. Downloading the current release here and unpacking the ZIP file into your project’s source directory
  2. Downloading the CMSIS headers and vendor’s HAL/BSP headers and placing them into your project’s include directory
  3. Adding the vendor’s HAL/BSP header to the HeliOS /src/port.h header directly below the #elif defined(CMSIS_ARCH_CORTEXM) statement (i.e., line 52)
  4. Setting SYSTEM_CORE_CLOCK_FREQUENCY and SYSTEM_CORE_CLOCK_PRESCALER in HeliOS’s /src/config.h header to match the Cortex-M’s core clock frequency and your desired prescaler
  5. Add the -DCMSIS_ARCH_CORTEXM compiler directive to your project’s build configuration

Espressif ESP32

Please note that HeliOS is not supported on the Espressif ESP32 microcontroller when using the ESP32 Arduino core. This is because the ESP32 Arduino core is built on FreeRTOS and HeliOS and FreeRTOS cannot coexist in the same application. To target ESP32, HeliOS must be built using Espressif's SDK without the ESP32 Arduino core. The files /src/port.h and /src/port.c will also need to be updated with the necessary code to control interrupts and access the microcontroller's tick timer. Espressif's SDK can be found here.


👨‍🏫 Example

Many embedded applications implement what is called a "super loop". A super loop is a loop that never exits (i.e., while(1) {}) and contains most of the code executed by the microcontroller. The problem with super loops is they can grow out of control and become difficult to manage. This becomes especially challenging given the relatively few options for controlling timing (e.g., delay()). Unfortunately the use of delay() to control timing also means the microcontroller is unable to perform other operations (at least without the help of an ISR) until delay() returns. Below is an example of how easy it is to leverage the event-driven multitasking capabilities within HeliOS to implement the Arduino "Blink" example.

Arduino "Blink" Example

Below is the "Blink" example sketch included with the Arduino platform.

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(1000);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);                      // wait for a second
}

HeliOS "Blink" Example

Below is the Arduino "Blink" example sketch implemented using HeliOS. In this example, a HeliOS task, which alternates the microcontroller's GPIO pin state between high and low, is added in a "wait" state and a task timer is set instructing HeliOS's scheduler to execute the task every 1,000 ticks (milliseconds on many microcontrollers).

#include <HeliOS.h>


/* Define the task's main function. This function is the entry point for the
 * task when executed by the scheduler. The "task_" parameter contains the task
 * itself and may be used to perform operations against the task such as
 * suspending it with xTaskSuspend(task_). The "parm_" parameter points to
 * memory containing the task parameter(s). This memory can be allocated by
 * xMemAlloc() if needed. The task parameter must be dereferenced inside the
 * task's main function. A convenient C macro, DEREF_TASKPARM(), is available to
 * simplify the task of dereferencing the task parameter. */
void blinkTask_main(xTask task_, xTaskParm parm_) {
  /* Dereference the task parameter and store its value in the local integer
   * "ledState". This integer contains the state of the LED (i.e., 1 (on) or 0
   * (off)). Global variables are discouraged in favor of task parameters when
   * sharing or persisting a value is required*/
  int ledState = DEREF_TASKPARM(int, parm_);


  /* Once inside the task's main function, do not call functions like Arduino's
   * delay(). HeliOS tasks should implement a state machine model like the one
   * used here to ensure control is returned to the scheduler as quickly as
   * possible so other tasks may run. */
  if(ledState) {
    digitalWrite(LED_BUILTIN, HIGH);
    ledState = 0;
  } else {
    digitalWrite(LED_BUILTIN, LOW);
    ledState = 1;
  }


  /* Because the value of "ledState" has changed, the task parameter must be
   * dereferenced again so that it may be updated. The task's main function will
   * receive the same value the next time the task is executed by the scheduler.
   * Task parameters are also the preferred method for sharing message queues,
   * stream buffers, etc. between tasks. */
  DEREF_TASKPARM(int, parm_) = ledState;

  return;
}


void setup() {
  int ledState = 0;


  pinMode(LED_BUILTIN, OUTPUT);


  /* Call xSystemInit() to initialize memory and call initialization functions
   * in the port layer. The xSystemInit() syscall must be made prior to making
   * any other syscall. The ERROR() and OK() C macros are a concise method for
   * checking the return value of the xSystemInit() syscall. A consistent return
   * type (xReturn) was introduced in kernel 0.4.0.  If the syscall fails,
   * xSystemHalt() will be called to halt the system.*/
  if(ERROR(xSystemInit())) {
    xSystemHalt();
  }


  /* Declare the task which will be used inside of the Arduino setup() function
   * to configure the task prior to handing over control to the HeliOS
   * scheduler. */
  xTask blink;


  /* Call the xTaskCreate() syscall to create the task. The xTaskCreate()
   * syscall prototype and parameters are as follows.
   *
   * PROTOTYPE
   * ~~~~~~~~~
   *   xReturn xTaskCreate(xTask *task_,
   *                       const xByte *name_,
   *                       void (*callback_)(xTask task_, xTaskParm parm_),
   *                       xTaskParm taskParameter_)
   *
   * PARAMETERS
   * ~~~~~~~~~~
   *   task_     A reference to the task. To pass the task by reference, the
   *             address-of ("&") operator must be used (e.g., &blink).
   *
   *   name_     A reference to the first byte of a byte array containing the
   *             ASCII name of the task. The task name is not a null terminated C char array
   *             (sometimes called a "string"). The length of the byte array must be
   *             precisely CONFIG_TASK_NAME_BYTES (default is 8) bytes. If the task name is
   *             shorter, then it must be padded to meet the precise length requirement. To
   *             avoid compiler warnings when using a literal (e.g., "BLINKTSK"), the
   *             argument must be cast as "const xByte *".
   *
   *   callBack_ A reference to the task's main function. The task's main
   *             function's prototype must be as follows. The name of the task's main
   *             function does *NOT* need to match the name given to the task through the
   *             "name_" parameter.
   *
   *               void <taskname>(xTask task_, xTaskParm parm_)
   *
   * If the syscall fails, xSystemHalt() will be called to halt the system.*/
  if(ERROR(xTaskCreate(&blink, (const xByte *) "BLINKTSK", blinkTask_main, &ledState))) {
    xSystemHalt();
  }


  /* Because the blink task will be an event-driven task (i.e., scheduled for
   * execution only when a task event occurs), the task must be placed in the
   * "waiting" state by xTaskWait(). There are two types of task events,
   * direct-to-task notifications and task timers. In this example we will be
   * using a task timer. If the syscall fails, xSystemHalt() will be called to
   * halt the system. */
  if(ERROR(xTaskWait(blink))) {
    xSystemHalt();
  }


  /* In order to use the task timer, the task timer period must be set to a
   * positive non-zero value. In this example we are setting the task timer to
   * 1,000 ticks. This way the HeliOS scheduler will schedule the blink task for
   * execution every 1,000 ticks. The length of a tick is platform and/or
   * architecture dependent though on most platforms a tick will occur every one
   * millisecond. If the syscall fails, xSystemHalt() will be called to halt the
   * system. */
  if(ERROR(xTaskChangePeriod(blink, 1000))) {
    xSystemHalt();
  }


  /* Now that the task(s) are created and configured they way we want, control
   * must be passed to the HeliOS scheduler. Once this is done, the only way to
   * return control back to the Arduino setup() function is by calling
   * xTaskSuspendAll() which will cause the scheduler to quit. If the syscall
   * fails, xSystemHalt() will be called to halt the system. */
  if(ERROR(xTaskStartScheduler())) {
    xSystemHalt();
  }


  /* While not required, it is advised to call xSystemHalt() at the end of the
   * Arduino setup() function. In this way, if the scheduler is forced to quit,
   * the application will halt and no further code will be executed. */
  xSystemHalt();
}


void loop() {
  /* The Arduino loop() function is not used in a HeliOS application and must
   * remain empty. */
}

📦 Releases

All releases, including the latest release, can be found here.

  • 0.4.1 - Fixed PlatformIO library.json file and updated readme
  • 0.4.0 - Consistent return type for all syscalls, additional memory consistency checking, new HeliOS Developer's Guide, new code documentation and many more changes and improvements.
  • 0.3.5 - Several new features including device drivers, stream buffers, task watchdog timer, improved memory defragmentation and many more including improvements to source code and documentation.
  • 0.3.4 - Corrected "blink" example in readme and in examples, fixed ESP8266 support, added queue locking and other improvements
  • 0.3.3 - Multi-region memory support, memory defragmentation, CMSIS support, new portability layer and other code improvements
  • 0.3.2 - Some fixes to the memory management system calls and related functions
  • 0.3.1 - A lot of refactoring, code clean-up from the 0.3.0 release and code documentation/readability improvements
  • 0.3.0 - First release of the new 0.3.x series kernel (many new features, most of the kernel rewritten, new example code and new documentation)
  • 0.2.7 - Added a contributed example, privatized the list pointers for scheduler and added support for Teensy 3/4
  • 0.2.6 - Added built-in support for ESP8266 and minor internal updates
  • 0.2.5 - Numerous internal enhancements including improved time precision and scheduler now gracefully handles overflow of run-time timer
  • 0.2.4 - Additional example Arduino sketches and other code improvements
  • 0.2.3 - Improved protection of system state, new examples, improved code documentation and some maintainability enhancements
  • 0.2.2 - Additional function calls, minor fixes and documentation enhancements
  • 0.2.1 - The first official release

🚧 Contributing

See the contributing guidelines on how to contribute to HeliOS. If you are going to make a source code or documentation contribution; please do not fork the master branch. Only pull requests forked from the develop branch will be accepted.


📜 Copyright & License

HeliOS Embedded Operating System Copyright (C) 2020-2023 HeliOS Project [email protected]

HeliOS is copyrighted open source software licensed under the Free Software Foundation's GNU General Public License (GPL) Version 2. The full text of the license can be found here.


☠️ Important Notice

HeliOS is not certified for use in safety-critical applications. The HeliOS source code, whether in full or in part, must never be used in applications where a risk to life exists. In other words, do not use HeliOS in your project if there is even a remote chance someone might get hurt.


💬 Other Notice

This project is not affiliated in any way, past or present, with the discontinued Unix-like operating system Helios developed by Dr. Tim King of Perihelion Software Ltd. or Axel Muhr's work on Helios-NG. Any resemblance is purely coincidental.


helios's People

Contributors

iixxteam avatar jakubrakus avatar juprgn avatar mannypeterson avatar stigbjorlykke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

helios's Issues

Linking problem with multiple files and HeliOS

Encountered a strange problem which I cannot find a solution. Linking problem with multiple files that link fine when using FreeRTOS but not with HeliOS.

Made a simple test to verify this issue as well.

What works:

  • single file where the whole code is
  • includes arduino.h and helios.h and few other includes.
  • compiling, linking, download and code runs properly

What does not work:

  • a dedicated local.h with prevention to include multiple times (#ifndef...) which contain arduino.h and helios.h
  • 2 source files, where the same code as in the working example is located in one file and in the 2nd file there's only one dummy task that does nothing + include of local.h
  • one additional include file (dummy.h) which includes local.h and declaration of the dummy task (extern) so that it can be found
  • main code is modified to include local.h and registration of dummy-task
  • compile fine, link fails

.pio/build/megaatmega2560/src/main.cpp.o (symbol from plugin): In function display':
(.text+0x0): multiple definition of xByte2String(unsigned int, unsigned char*)' .pio/build/megaatmega2560/src/dummy.cpp.o (symbol from plugin):(.text+0x0): first defined here collect2: error: ld returned 1 exit status *** [.pio/build/megaatmega2560/firmware.elf] Error 1

I have been using this local.h approach for a long time successfully e.g. with FreeRTOS but for some reason HeliOS doesn't like this at all (or linker doesn't like with HeliOS).

local.h:
`#ifndef local_h
#define local_h

#include <Arduino.h>
#include <HeliOS.h>

#endif
`

dummy.h:
`#include "local.h"

extern void TaskDummy(xTask task_, xTaskParm parm_);`

dummy.c:
`#include "local.h"

void TaskDummy(xTask task_, xTaskParm parm_)
{
// nothing
}`

main.c (beginning of the file):
#include "local.h" #include <SPI.h> #include <Adafruit_GFX.h> #include <Arduino_ST7789_Fast.h> #include "dummy.h"
There comes usual setup() and loop() functions. In setup tasks are registered etc.

2. What results, output, behavior are you expecting?

Expectation is that the code would link normally with HeliOS.

3. What version of HeliOS are you using?

heliosproj/HeliOS@^0.4.1

4. Provide the following details about your development environment and development board/microcontroller:

OS [Windows, macOS, Linux]: Linux

OS Version [Windows 10, Ventura, Ubuntu 22.04]: OpenSUSE Tumbleweed

IDE [Arduino IDE, PlatformIO, STM32CubeIDE, Keil]: PlatformIO

IDE Version: 1.85.2

Board/MCU Mfg [Arduino, PJRC, ST Micro]: Arduino MEGA 2560 Pro

5. Are you experiencing any compiler or linker errors? If so, copy and paste them here (please do not provide screenshots):

.pio/build/megaatmega2560/src/main.cpp.o (symbol from plugin): In function display':
(.text+0x0): multiple definition of xByte2String(unsigned int, unsigned char*)' .pio/build/megaatmega2560/src/dummy.cpp.o (symbol from plugin):(.text+0x0): first defined here collect2: error: ld returned 1 exit status *** [.pio/build/megaatmega2560/firmware.elf] Error 1

7. Attach a copy of your source code file(s) so we may compile them if needed:

HeliOS_test.zip

Default size of heap block

Default size of the OS's heap block (array static Byte_t heap[HEAP_RAW_SIZE] in mem.c) is IMHO a way too big for most usage scenarios. With the default values of CONFIG_HEAP_SIZE_IN_BLOCKS = 512 and CONFIG_HEAP_BLOCK_SIZE = 32 it takes 16 kB of RAM memory which is ridiculous number for most popular AVR-based Arduino boards like Uno, Mini, Micro, Leonardo with around 2 kB of SRAM. Even Arduino Mega has only 8 kB. For the ESP8266 boards, like Wemos D1 and clones, it eats half of RAM.

My proposal is to move these configs into defines.h section with architecture specific options. Then for example ARDUINO_ARCH_AVR should set defaults to no more than 128 B, current value of 16 kB may be usable only on architectures like ARDUINO_ARCH_SAM, ARDUINO_ARCH_SAMD, ESP32 ond other bigger ones with RAM counted in hundreds of kB or more.

Error: using typedef-name 'xTaskGetInfoResult' after 'struct'

I'm trying to compile the notification example given in the documentation but am getting the error: "exit status 1 using typedef-name 'xTaskGetInfoResult' after 'struct'". My code is below but all looks correct, can anyone tell me where I'm going wrong? Compiling for an Arduino Nano with IDE 1.8.15.

#include <HeliOS_Arduino.h>

//Our first task checks the state of the mp3 player
void taskA(int id_) {
  /*
     Obtain the task id of task "B" using its friendly name
     since it should not be assumed that task "B" will always
     have a task id of 2.
     Then check the status of the MP3 player
     pass a 4-byte notification containing the player state to the playAudio task
  */
  xTaskNotify(xTaskGetId("TASKB"), 4, "test");
} //end player state function

/*
   Create the second task "B"
*/
void taskB(int id_) {
  /*
     Obtain the notification bytes and value from the xTaskGetInfoResult
     structure by first making a call to the xTaskGetInfo() function call
     using the task's id stored in id_.
  */
  struct xTaskGetInfoResult* res = xTaskGetInfo(id_);
  /* Because xTaskInfo() can return a null pointer, always check
     that the structure's pointer is not null before accessing
     its members.
  */
  if (res) {
    /*
       res->notificationBytes contains the notification bytes
       res->notificationValue contains the notification value
    */
  }
  /* Always call xMemFree() to free the managed memory allocated by
     xTaskGetInfo();
  */
  xMemFree(res);
}

void setup() {
  /*
     xHeliOSSetup() must be the first function call
     made to initialize HeliOS and its data structures
  */
  xHeliOSSetup();

  /*
     Declare and initialize an int to temporarily hold the
     task id.
  */
  int id = 0;

  /*
     Pass the task friendly name and function to xTaskAdd()
     to add the task to HeliOS. xTaskAdd() will return a
     task id greater than zero if the task is added unsuccessfully.
  */
  id = xTaskAdd("TASKA", &taskA);

  /*
     Pass the task id of the task to set its state from stopped
     to running.
  */
  xTaskSart(id);

  /*
     Pass the task friendly name and function to xTaskAdd()
     to add the task to HeliOS. xTaskAdd() will return a
     task id greater than zero if the task is added unsuccessfully.
  */
  id = xTaskAdd("TASKB", &taskB);

  /*
     Pass the task id of the task to set its state from stopped
     to waiting.
  */
  xTaskWait(id);
}

void loop() {
  /*
     Pass control to the the HeliOS scheduler. xHeliOSLoop() should
     be the only code inside the microcontroller project's
     main loop.
  */
  xHeliOSLoop();
}

Time overflow and integer precision

The time value in HeliOS is defined as unsigned long, which most likely will be 32 Bit on typical embedded platforms.

With a time resolution of one microsecond it will "wrap around" (start over from zero...) after ~4295 seconds which is not much longer than one hour. To have a practical use of HeliOS the effects of timer overflow have to be mitigated. Not sure if this is handled in the code , I quick review shows this line in HeliOS.c:

 if (NOW() - waitingTask[i]->timerStartTime > waitingTask[i]->timerInterval) 

This will at least work also in overflow case, because all values are unsigned. But I'm not sure if all other cases handle wrap around well. At least users should be warned in the documentation that it will happen quite frequently.
Another possibility would be to ensure that the time values are 64 Bits, but this may be very expensive on 8 Bit AVRs (not even sure if avr-gcc supports 64 Bit integers...).
A general question is if relying on standard C "unsigned long" is an issue with portability, because "long" can be theoretically anything. Most portable software systems either define either their own integer types (like "u32", "u64") or include stdint.h
At least you should define a type for such a very critical value like time (e.g. "t_helios_time") with the possibility to adapt it for different ports.
This would also allow e.g. to run HeliOS in x86_64 Linux userland (where long is 64 Bits) but still emulate the behavior of a 32 Bit MCU platform.

[OTHER] M68K Port?

In 2024 it seems there are many enthusiasts who would love an OS like this. Tindie is one way to go to promote it with retro boards, but there are many other devices as well out there.

8-bit/16-bit Operating Systems Could Be For:

  • MC68000
  • MC68010

32-bit Operating System could be for:

— MC68020 with FPU chip

  • MC68EC20 with FPU chip
  • MC68030
  • MC68EC030
  • MC68040
  • MC68EC040
  • MC68LC040
  • MC68060
  • MC68EC060
  • MC68LC060
  • Freescale/NXP Dragonball CPUs

So that includes but isn’t limited to M68K Macs, Sun2, Sun3 systems, Amiga 68K systems, Sharp X680XX gaming systems, and a huge variety of tinker boards on Tindie, RetroBrew and a lot more sites.

ActionRetro and NCommander on YouTube would be some people to help finjd folks to make a port happen and contribute to this.

Porting Contribution for PIC18 Devices

Hi!
First of all, congratulations for your nice project HeliOS. I liked your project and I'd like to contribute it for porting HeliOS to PIC18 devices of Microchip and maybe for STM microcontrollers in the future. My contributions would be in bare metal code form to interface your OS with the low level built-in hardware like timers, UARTs etc. I have looked through the guides but haven't seen any contributing guide. Can you provide a porting guide where you describe the systems interfaces briefly unless you have one, then please provide the link here so I can make use of it.
A brief guide would be very time saving, you know, we are kind of busy and time limited because of the full time work hours.

Use Pragma once in Helios_Arduino.h

Would be nice if we can include it multiple times without breaking stuff :)

In order to do so
#pragma once
should be inserted at top of Helios_Arduino.h :)

Porting Contribution for PIC18 Devices

Hi!
First of all, congratulations for your nice project HeliOS. I liked your project and I'd like to contribute it for porting HeliOS to PIC18 devices of Microchip and maybe for STM microcontrollers in the future. My contributions would be in bare metal code form to interface your OS with the low level built-in hardware like timers, UARTs etc. I have looked through the guides but haven't seen any contributing guide. Can you provide a porting guide where you describe the systems interfaces briefly unless you have one, then please provide the link here so I can make use of it.
A brief guide would be very time saving, you know, we are kind of busy and time limited because of the full time work hours.

Teensy 4.1?

Hi, are you planning on supporting Teensyduino / Teensy 4.x boards? What is blocking support, currently?

This architecture is currently unsupported by HeliOS.

"Blink" example doesn't blink

Hi!
I loaded the example code in the arduino ide for blink and it didn't do anything.
I then loaded the basic example code for blink and it worked without problems.
I didn't change anything in the example - should i have?
I am using an arduino nano and i know HeliOS is about the limit for it, might that be a problem?
I have no experience with OS on microcontrollers and previously did everything "by hand".

Need Help for an example of QueueMessage

Hi guys:
I am learning how to use Queue of HeliOS , my code is not working ,I am not sure my codes is correct.Please do me a favor to explain how to use the function Queue in HeliOS .Thanks
here is my code :
main.cpp.zip

I create tasks, task1 and task2 are just sending message to queue ,and taskprint will read the message
and print it out . It's very simple .
Question 1 :So should I suppose to create a xQueue Queue1 = xQueueCreate(8) ?
Question2: How can I get the handler of Queue in Task?

void Task1(xTask task_, xTaskParm parm_) {
char userID="1";
xQueue Queue1; -------> for Queue1 handler Am I correct ? if I omit this line ,compiler will error : Queue1 is not declared.
if (xQueueIsQueueFull(Queue1) == false ){
xQueueSend(Queue1,
1,
"1" );
Serial.println("TASK1 sended");
} else {
Serial.println("QueueMsg is full");
}
}

Thanks you again!!!!
Best wishes!!!

What is the difference between xTaskResume() and xTaskWait() in function setup()?

Hi:
Here is my case:
I am trying to make a canbus thermocouple module with HeliOS ; the working flow as follow:
step1: power up and run init scripts for init
step2: create two task 1)get temperature 2)write canbus data and send out
wait for 750ms and make sure MAX6675 get the correct temperature data ,IN the meanwhile canbus data will NOT send out
step3: Task1:get temperature will run every 750ms and write the data in a float struct , notify task2 send out data
Task2:canbus data will send out data .

After I read thought examples pgm :Blink.ino and coop.ino .I don't quiet to understand the difference between xTaskResume() and xTaskWait()
In Blink.ino ,after create and check the task is OK .
xTaskWait(blink); -------->Is that means task in suspended mode ,not running
xTaskChangePeriod(blink, 1000); ------>that means wait for 1s , as a timer ,like function delay() of arduino ?

 In coop.ino,after create and check the task is OK . 
   xTaskResume(shortTask); -------->Is that means task run immediately?

For further study,How to use MUTEX (in freeRTOS ) to lock the data?

Thank you for you guys answering!!!
Best wishes!!!

[Proposition] Give user task pointer instead of ID

ID require you to search through the list to find corresponding task. I propose to replace ID with pointer to Task struct which will remove unnecessary lookup.

If you want to prevent user from messing with internals, I also propose to declare structs in separate header and typedef them as void in public header. This way from user point it's only a void pointer and he cannot change internal stuff whereas HeliOS functions will be able to do so.

Arduino Nano RP2040 Connect

I'm trying to compile a HeliOS program for Arduino Nano RP2040 Connect (RP2040 processor from Raspberry Pi Pico), it says:

"This architecture is currently unsupported by HeliOS. If building for Linux or Microsoft Windows, make sure to un-comment OTHER_ARCH_LINUX or OTHER_ARCH_WINDOWS in HeliOS.h."
#error "This architecture is currently unsupported by HeliOS. If building for Linux or Microsoft Windows, make sure to un-comment OTHER_ARCH_LINUX or OTHER_ARCH_WINDOWS in HeliOS.h."

Could you please add support for this architecture?
Thanks!

Dynamically Timed Tasks?

Hi all!

I'm trying this RTOS to write the software for a digital guitar effect pedal but I ran across some issues (other than the docs not being up-to-date) with regards to a dynamically timed task...

First, I have a timed task that runs every 10ms which reads a pot value (between 0 and 1023) and calculates a delay tempo from it. This sets the timer of the next task accordingly.

long delay_time_us = long(map(delay_time, 0, 1023, 53, 626)) * 1000;
xTaskSetTimer(xTaskGetId("TASKTEMPO"), delay_time_us);

This "TASKTEMPO" is a very simple task that toggles a LED:

void taskTempo(xTaskId id_) {
  if (smode == SMODE_TEMPO)
    analogWrite(pin_rgb_g, 127 * tempo_blink);

  tempo_blink = !tempo_blink;
}

If I only have those two tasks, it works fine. However, when I add a couple more tasks, things start to get a little different. The timing seems still alright but often the task completely skips... Meaning that the LED blinks irregularly... Based on the concept of cooperative scheduling I would assume that the priority is high (as the taskTempo is very short) but it doesn't seem to be the case... Can I somehow assign priorities to tasks or is there a different solution to the issue?

[BUG]

🎯 Help us help you by filling out this issue completely. This issue is ONLY for bug reports. If you are seeking support, please submit a support request.

1. Describe, in detail, the bug you have encountered and how to reproduce it (if providing a source code excerpt, use a markdown code block and please do not provide screenshots of source code):

HeliOS source files conflict with Arduino files under Windows because filenames are the same. Under Linux they are not the same (capital S versus lowercase s). This leads to a lot of errors in compiling under Windows.

2. What results, output, behavior are you expecting?

Same result in Windows as in Linux.

3. What version of HeliOS are you using?

The latest 0.4.1.

4. Provide the following details about your development environment and development board/microcontroller:

OS [Windows, macOS, Linux]: Windows

OS Version [Windows 10, Ventura, Ubuntu 22.04]: 7 and 10

IDE [Arduino IDE, PlatformIO, STM32CubeIDE, Keil]: Platform IO

IDE Version: 1.70.3 and the latest (18.x)

Board/MCU Mfg [Arduino, PJRC, ST Micro]: Arduino MEGA 2560 pro

Board/MCU Model [UNO, Teensy 4.1, NUCLEO-F429ZI]:

5. Are you experiencing any compiler or linker errors? If so, copy and paste them here (please do not provide screenshots):

Many. Please, take a look at following link for more details and a solution:
https://community.platformio.org/t/strange-issue-with-compiling-under-linux-fine-fails-badly-in-windows/38572/2

7. Attach a copy of your source code file(s) so we may compile them if needed:

Waiting Tasks are limited < WAITINGTASKSIZE

I think that could be a problem:

If you have for example 15 timer tasks.

Ten of them runs every 10ms for example and five of them runs every 200ms. That five are at the end of the task list.
It could be that this five tasks will never run, because the scheduler always make a TaskListRewind(), start from the front of the list and limit the waitingTask[waiting] to 8.
Because of that limit and the reset of the list it could be, that the scheduler will never reach the 200ms tasks because the 10ms task want alway to run.

HeliOS 0.3.3 seems to can not pass the globe var value to in "blink" example ...

Hi Guys :
I am learning how to make a multi-tasks project with HeliOS 0.3.3 ,I make the code as following:

heliOS_learning.zip
which is base on HeliOS example "Coop" .I am trying to run 3 tasks in this program
1:blink the LED (base on example "Blink")
2: two task-nobody (just delay(XXX) and print a letter out to serial port

Here is the task function:

void taskShort_main(xTask task_, xTaskParm parm_) {
int ledState = DEREF_TASKPARM(int, parm_);
Serial.print("led 1 ");Serial.println(ledState);
if (ledState) {
digitalWrite(LED_BUILTIN, HIGH);

Serial.print("led 2 ");Serial.println(ledState);

ledState = 0;

Serial.print("led 3 ");Serial.println(ledState);

} else {
digitalWrite(LED_BUILTIN, LOW);

ledState = 1;

Serial.print("led 4 ");Serial.println(ledState);

}
DEREF_TASKPARM(int, parm_) = ledState;
Serial.print("led 5 ");Serial.println(ledState);
return;
}

And serial print out :

08:38:03.355 -> L
08:38:03.966 -> M
08:38:03.966 -> led 1 0 timeloop1 in-value =0 ,init value ,OK
08:38:03.966 -> led 4 1 timeloop1 change ledstate ,working good
08:38:03.966 -> led 5 1
08:38:04.342 -> L
08:38:04.953 -> M
08:38:05.375 -> L
08:38:05.375 -> led 1 0 timeloop2 in-value =0?,suppose to be 1 ,working not OK now
08:38:05.375 -> led 4 1 timeloop2
08:38:05.375 -> led 5 1

The var Ledstate do changed in Task "taskShort_main" and pass-thought out to DEREF_TASKPARM(int, parm_) (LED 1 in-value = 0 , LED4 out-value = 1 ),but in the next task Schedule Led1 read in value still is 0 ,suppose to be LED1 = 1 .

so , I make the same coding in example "Blink" , as following :

Blink-check.zip

And serial print out :

08:46:44.589 -> led 1 0 timeloop1 in-value =0 ,init value ,OK
08:46:44.589 -> led 4 1 timeloop1 change ledstate ,working good
08:46:45.625 -> led 1 1 timeloop2 in-value =1 ,from lastloop led4 out-value ,working good
08:46:45.625 -> led 2 1 timeloop2
08:46:45.625 -> led 3 0 timeloop2 change ledstata, output value .
08:46:46.602 -> led 1 0
08:46:46.602 -> led 4 1
08:46:47.653 -> led 1 1
08:46:47.653 -> led 2 1
08:46:47.653 -> led 3 0

the coding is work....

I have tried Arduino Nano , LGT8F328P Nano , both "blink" program running OK , "Coop+Blink" not OK ,
I also tried D1 mini ,but seems HeliOS 0.3.3 not working good . I can not locate where is "ARDUINO_ARCH_ESP8266" in HeliOS.h.

I am not sure which parts is not OK now ......
Would you Please help me to check it out !!!!
Thanks all guys and best wishes !!!

Coop does now work on UNO

I get follwowing result on UNO:

ACBACBACBL
ACBACBACBL
ACBACBACBL
ACBACBACBL
ACBACBACBL
ACBACBACBL
ACBACBACBL
ACBACBACBL

while using following code:

`/*

  • HeliOS Embedded Operating System
  • Copyright (C) 2020 Manny Peterson [email protected]
  • This program is free software: you can redistribute it and/or modify
  • it under the terms of the GNU General Public License as published by
  • the Free Software Foundation, either version 3 of the License, or
  • (at your option) any later version.
  • This program is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  • GNU General Public License for more details.
  • You should have received a copy of the GNU General Public License
  • along with this program. If not, see https://www.gnu.org/licenses/.
    */

/*

/*

  • Include the standard HeliOS header for Arduino sketches. This header
  • includes the required HeliOS header files automatically.
    */
    #include "HeliOS_Arduino.h"

/*

  • The task definition for taskShort() which
  • will perform 100,000 arbitrary floating point
  • operations.
    */
    void taskShortA(int id_) {
    float a = 0.0f;

for (int32_t i = 0; i < 1000; i++)
a *= 3.14f;

Serial.print("A");
}

void taskShortB(int32_t id_) {
float a = 0.0f;

for (int32_t i = 0; i < 10000; i++)
a *= 3.14f;

Serial.print("B");
}

void taskShortC(int32_t id_) {
float a = 0.0f;

for (int32_t i = 0; i < 40000; i++)
a *= 3.14f;

Serial.print("C");
}

/*

  • The task definition for taskLong() which
  • will perform 1,000,000 arbitrary floating point
  • operations.
    */
    void taskLong(int32_t id_) {
    float a = 0.0f;

for (int32_t i = 0; i < 40000; i++)
a *= 3.14f;

Serial.println("L");
}

void setup() {
/*

  • Declare and initialize an int to hold the
  • task id.
    */
    int id = 0;

Serial.begin(9600);

/*

  • Call xHeliOSSetup() to initialize HeliOS and
  • its data structures. xHeliOSSetup() must be
  • called before any other HeliOS function call.
    */
    xHeliOSSetup();

/*

  • Add the task taskShort() to HeliOS by passing
  • xTaskAdd() the friendly name of the task as well
  • as a callback pointer to the task function.
    */
    id = xTaskAdd("TASKSHORTA", &taskShortA);

/*

  • Call xTaskStart() to start taskShort() by passing

  • xTaskStart() the id of the task to start.
    */
    xTaskStart(id);

    id = xTaskAdd("TASKSHORTB", &taskShortB);
    xTaskStart(id);

    id = xTaskAdd("TASKSHORTA", &taskShortC);
    xTaskStart(id);

/*

  • Add the task taskShort() to HeliOS by passing
  • xTaskAdd() the friendly name of the task as well
  • as a callback pointer to the task function.
    */
    id = xTaskAdd("TASKLONG", &taskLong);

/*

  • Call xTaskStart() to start taskLong() by passing
  • xTaskStart() the id of the task to start.
    */
    xTaskStart(id);
Serial.println("START");

}

void loop() {
/*

  • Momentarily pass control to HeliOS by calling the
  • xHeliOSLoop() function call. xHeliOSLoop() should be
  • the only code inside of the sketch's loop() function.
    */
    xHeliOSLoop();
    }`

Can not get Notify messages from xTaskNotifyTake()

Hi guys:
I am trying to make a canbus thermocouple module with HeliOS ; the working flow as follow:
step1: power up and run init scripts for init
step2: create two task 1)get temperature 2)write canbus data and send out
wait for 750ms and make sure MAX6675 get the correct temperature data ,IN the meanwhile canbus data will NOT send out
step3: Task1:get temperature will run every 750ms and write the data in a float struct .And then notify task2 to send data out

I tested example-- WaitNotify.ino ,it work well . so I write my pgm base on WaitNotify.ino,here is source files

sourcefile.zip

The main issue is xTaskNotifyTake(task_) can not attached ,not working

Task1 send out notifications :

void taskThermo_Get(xTask task_, xTaskParm parm_)
{
/* Get the task handle for the task that will receive the
direct-to-task notification. */
xTask WriteCANBUSTask = xTaskGetHandleByName("WRITECANBUS");

    temperature_data.BT_AvgTemp=30.12;
    temperature_data.ET_CurTemp=28.66; 

    Serial.print("task thermo_get");
    Serial.print("  ") ;
    Serial.print(temperature_data.BT_AvgTemp);
    Serial.print("  ") ;
    Serial.print(temperature_data.ET_CurTemp);
    Serial.println(" ");


    if (WriteCANBUSTask){  
        //Serial.println("geted task_writecanbus handler"); 
        /* Send the direct-to-task notification of "HELLO"
        which is five bytes. */
        Serial.println("task WriteCANBUSTask send noti "); --------> it's work 
        xTaskNotifyGive(WriteCANBUSTask,2, "OK");
    }
}

task2 :Receiver notifications
void taskCanbus_Write(xTask task_, xTaskParm parm_)
{
String notif_str = "";
Serial.print("before notif_str");
Serial.println(notif_str);
xTaskNotification notif = xTaskNotifyTake(task_); ------>here ,not working .
notif_str = notif->notificationValue;------>here ,not working .
Serial.print("after notif_str");
Serial.println(notif_str);------->print out nothing...which is suppose is 'OK'

if ( notif ){. -------> here is not working neither
notif_str = notif->notificationValue;-------> here is not working neither
Serial.println(notif_str);-------> here is not working neither
xMemFree(notif);-------> here is not working neither
}

The rest of codes is the same as example ino file but the task name....
create task as below:
xTask GetThermoTask = xTaskCreate("GET_THERMO", taskThermo_Get,NULL);
xTask WriteCANBUSTask = xTaskCreate("WRITECANBUS", taskCanbus_Write, NULL);

and then set task in waiting mode :
xTaskWait(GetThermoTask);
xTaskWait(WriteCANBUSTask);
and set sending notify task in running mode which loop in 1s.
xTaskChangePeriod(GetThermoTask, 1000); //1000ms

Thank you for you guys answering!!!
Best wishes!!!

Passing Parameters to task

Hi!
I had a question: is it possible to pass parameters to a task you're creating?
So for example have two buttons but with a single task definition?
void taskButton(xTaskId id_, const uint8_t port)
which then is called with something like:
int p = 1; id = xTaskAdd("TASKSW1", &taskSW, p)

HeliOS 0.3.5 cannot compile on ESP8266

Hi guys:
i am trying to compile the following code in vscode+platfromIO :
code.zip
Not success, here is the output

PLATFORM: Espressif 8266 (4.1.0) > WeMos D1 R2 and mini
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
PACKAGES:

  • framework-arduinoespressif8266 @ 3.30101.0 (3.1.1)
  • tool-esptool @ 1.413.0 (4.13)
  • tool-esptoolpy @ 1.30000.201119 (3.0.0)
  • toolchain-xtensa @ 2.100300.220621 (10.3.0)
    LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
    LDF Modes: Finder ~ chain, Compatibility ~ soft
    Found 41 compatible libraries
    Scanning dependencies...
    Dependency Graph
    |-- MAX6675 library @ 1.1.0
    |-- HeliOS @ 0.3.5
    |-- SPI @ 1.0
    |-- autowp-mcp2515 @ 1.0.3
    | |-- SPI @ 1.0
    Building in release mode
    Compiling .pio/build/LGT8F328P_esp8266/src/main.cpp.o
    Generating LD script .pio/build/LGT8F328P_esp8266/ld/local.eagle.app.v6.common.ld
    Compiling .pio/build/LGT8F328P_esp8266/lib4af/MAX6675 library/max6675.cpp.o
    Compiling .pio/build/LGT8F328P_esp8266/lib3ef/HeliOS/device.c.o
    Compiling .pio/build/LGT8F328P_esp8266/lib3ef/HeliOS/mem.c.o
    Compiling .pio/build/LGT8F328P_esp8266/lib3ef/HeliOS/port.c.o
    Compiling .pio/build/LGT8F328P_esp8266/lib3ef/HeliOS/queue.c.o
    Compiling .pio/build/LGT8F328P_esp8266/lib3ef/HeliOS/stream.c.o
    Compiling .pio/build/LGT8F328P_esp8266/lib3ef/HeliOS/sys.c.o
    Compiling .pio/build/LGT8F328P_esp8266/lib3ef/HeliOS/task.c.o
    Compiling .pio/build/LGT8F328P_esp8266/lib3ef/HeliOS/timer.c.o
    Compiling .pio/build/LGT8F328P_esp8266/libe14/SPI/SPI.cpp.o
    Archiving .pio/build/LGT8F328P_esp8266/lib3ef/libHeliOS.a
    Indexing .pio/build/LGT8F328P_esp8266/lib3ef/libHeliOS.a
    Compiling .pio/build/LGT8F328P_esp8266/lib187/arduino-mcp2515-master/mcp2515.cpp.o
    src/main.cpp: In function 'void setup()':
    src/main.cpp:146:37: error: invalid conversion from 'const char' to 'const xChar' {aka 'const unsigned char*'} [-fpermissive]
    146 | xTask GetThermoTask = xTaskCreate("THERMO",taskThermo_Get,&BT_ArrayIndex);**
    | ^~~~~~~~
    | |
    | const char*
    In file included from src/main.cpp:4:
    lib/HeliOS/src/HeliOS.h:1194:32: note: initializing argument 1 of 'Task_t* xTaskCreate(const xChar*, void (*)(xTask, xTaskParm), xTaskParm)'
    1194 | xTask xTaskCreate(const xChar *name_, void (*callback_)(xTask task_, xTaskParm parm_), xTaskParm taskParameter_);
    | ~~~~~~~~~~~~~^~~~~
    The same code in LGT8F328P is OK and working well ...
    Please have a check !
    Thank you very much!

What happens if totalRuntime has an overflow?

Sorry, I dind't went through all the code lines, but I have a question regarding coop scheduling.

In:

 if (task->state == TaskStateRunning && task->totalRuntime < leastRuntime) {
        leastRuntime = task->totalRuntime;
        runningTask = task;

you are searching for the task with the least runtime.

In:

  if (runningTask) {
    taskStartTime = NOW();
    (*runningTask->callback)(runningTask->id);
    runningTask->lastRuntime = NOW() - taskStartTime;
    runningTask->totalRuntime += runningTask->lastRuntime;
  }

you write the totalRuntime runningTask->totalRuntime += runningTask->lastRuntime;.

What happens, if the totalRuntime has an overflow?
And all other coop tasks are just before an overflow.
Then this task has the least runtime and will always selected in

      if (task->state == TaskStateRunning && task->totalRuntime < leastRuntime) {
        leastRuntime = task->totalRuntime;
        runningTask = task;
      }

Is that correct? I haven't found a correction in the code for that issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.