Skip to content

Commit

Permalink
Read me example file
Browse files Browse the repository at this point in the history
  • Loading branch information
GUSTAVO CAMPOS authored and GUSTAVO CAMPOS committed Aug 24, 2020
1 parent 16c6a68 commit 8486130
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 56 deletions.
4 changes: 2 additions & 2 deletions CorePartition.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,12 @@ static void StackHandler (uint8_t* pDestine, const uint8_t* pSource, size_t nSiz

static void BackupStack (void)
{
memcpy ((uint8_t*)&pCurrentThread->stackPage, (const uint8_t*)pCurrentThread->pLastStack, pCurrentThread->nStackSize);
StackHandler ((uint8_t*)&pCurrentThread->stackPage, (const uint8_t*)pCurrentThread->pLastStack, pCurrentThread->nStackSize);
}

static void RestoreStack (void)
{
memcpy ((uint8_t*)pCurrentThread->pLastStack, (const uint8_t*)&pCurrentThread->stackPage, pCurrentThread->nStackSize);
StackHandler ((uint8_t*)pCurrentThread->pLastStack, (const uint8_t*)&pCurrentThread->stackPage, pCurrentThread->nStackSize);
}

static uint32_t CorePartition_GetNextTime (size_t nThreadID)
Expand Down
Binary file added PCExample/SimpleExample
Binary file not shown.
63 changes: 63 additions & 0 deletions PCExample/SimpleExample.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <sys/time.h>
#include <unistd.h>
#include <assert.h>

#include "CorePartition.h"

void Thread1(void* pValue)
{
int nValue = 0;

while (CorePartition_Yield())
{
printf ("Thread %zu: Value [%d] every %u ms\n", CorePartition_GetID(), nValue++, CorePartition_GetNice());
}
}

void Thread2(void* pValue)
{
int nValue = 0;

while (CorePartition_Yield())
{
printf ("Thread %zu: Value [%d] every %u ms\n", CorePartition_GetID(), nValue++, CorePartition_GetNice());
}
}

void CorePartition_SleepTicks (uint32_t nSleepTime)
{
usleep ((useconds_t) nSleepTime * 1000);
}

uint32_t CorePartition_GetCurrentTick(void)
{
struct timeval tp;
gettimeofday(&tp, NULL);

return (uint32_t) tp.tv_sec * 1000 + tp.tv_usec / 1000; //get current timestamp in milliseconds
}

static void StackOverflowHandler ()
{
printf ("Error, Thread#%zu Stack %zu / %zu max\n", CorePartition_GetID(), CorePartition_GetStackSize(), CorePartition_GetMaxStackSize());
}


int main ()
{

assert (CorePartition_Start (3));

assert (CorePartition_SetStackOverflowHandler (StackOverflowHandler));

//Every 1000 cycles with a Stack page of 210 bytes
assert (CorePartition_CreateThread (Thread1, NULL, 210, 1000));

//All the time with a Stack page of 150 bytes and
//thread isolation
assert (CorePartition_CreateSecureThread (Thread2, NULL, 150, 2000));

assert (CorePartition_CreateSecureThread (Thread2, NULL, 150, 500));

CorePartition_Join();
}
105 changes: 55 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,40 @@
# CorePartition
# CorePartitionOS

Version 2.6.0 develop
Version 2.6.0 release

![License information](https://raw.githubusercontent.com/solariun/CorePartition/master/License.png)

Partitioning a CORE into several Threads with a fast scheduler capable to be specialised through Tick and tick-sleep interface, this way you can use nanoseconds, milliseconds or even real ticks to predict time, turning it into a powerful real time processor. This lib was designed to work, virtually, with any modern micro controller or Microchip as long as it uses reverse bottom - up stack addressing, but was aiming single core processors and user space like MSDOS, linux applications (embedded or not), windows applications, Mac and (experimental) FreeRTOS to allow OS softwares and embedded processor/microcontroler code to split a core/software space into threads coordinated by a momentum scheduler.
CorePartitionOS is a Operational System for, virtually, ANY SINGLE CORE PROCESSOR, really lightweight (context ranging from 60bits on 8bits processors), compatible with 8bits, 32bits and 64bits Processors and Microcontrollers and can virtually work EVERYWHERE. The concept behind the CorePartitionOS is a powerful implementations based exclusively on C standard principles, you will not find any Assembler code, but do not be deceived about it, it truly deploys contextualized Threads.

Using Cooperative thread, the developer will be able to control when to change context, so you can precise tune your code to spend little thread memory page, allow more memory for your application and by consequence everything related to the function will be atomic. CorePartitionOS will also offer async messages using a state of the art in kernel message broker using Publish / Subscriber principles and a sync wait /notify (one and all) and sync messages with a novel approach, you will be able to lock a process using Wait that will block the thread to come back running till a notification arrives, that wait/notify structure is based on tags (like topics) and can also carry messages, just use notifyMessage and use WaitMessage for receiving it.

That CorePartitionOS uses a different scheduler, a Timer based one, which means you can specify when a thread will be good to go. Note that it is not a Rigid real time OS, instead, the timer will control the context switch procedure soon it is due to be executed and sleep the processor when nothing is due to be executed.

PLEASE NOTE THAT:
This Thread Library is a full Cooperative Thread Library, (it is not a task lib, it will really contextualize the thread and memory) that uses stack context and scheduler managements. It was design to work virtually into any processor, microcontroller but will perform amazingly as a thread for your software, using little memory and giving you a power and control need for complex projects.
This Thread Library is a full Cooperative Thread Library, (it is not a task lib, it will really contextualize the thread and memory) that uses stack context pages on heap and scheduler managements. It was design to work virtually into any single core processor, microcontroller but will perform amazingly as a thread for your software, using little memory and giving you a power and control need for complex projects.

# CorePartitionOS as Library

The CorePartitionOS also can transform your software into a multithread one, since the execution is highly manageable, you can create portable softwares that will execute similarly anywhere from small linux embedded targets to super computers but also gives you something never seen before on a embedded OS, you can create the full implementation on your desktop, creating a detachable Hardware Abstraction Layer you can create the logic and easily implemente the HAL for any target you need, just leave the thread and inter process communication for CorePartitionOS Library. It will decrease the need for target to test logic execution and, also, brings a rare opportunity for automatized tests.

It is compatible with Linux, Windows, Mac, Unix like operational systems and DOS

# Preemptive Threads

This lib can, also, perform as Preemptive, but since the intent is a universal lib, I will leave it up to you, just define a timer to call CorePartition_Yield () a good lock and it will run. There is a example of how to do it.



# NEW
# 2.6.0 develop
# 2.6.1

- Introducing Async Message Broker using Publish/Subscriber and topics to control async process intercommunications.
- Introducing Sync Wait / Notify thread blocking procedures using Tags as the lock identifier and optionally capable to send messages
- Introducing Message Payload, messages will be always identified (what thread generated that) and with a (32bits)Attribute and (64bitds)Value, sou a single topic or tag can do more than just sending a simple message, can send parameters and values (tuple) across the system.
- Rewritten Scheduler to be adapt to the new functions.
- Dropping full FreeRTOS support. It means it still can work, but we will no longer officially support it executing it as part of the RTOS solution, only of Computers OS's

# 2.5.0

- Better memory management,
- Now using memory provisioning instead of full empty context,
Expand All @@ -24,30 +46,25 @@ This lib can, also, perform as Preemptive, but since the intent is a universal l
- Now you can name a thread up to 8 characters
- Experimental FreeRTOS support

# FreeRTOS

Now we are adding EXPERIMENTAL support for FreeRTOS, which means you can run cooperative and highly manageable threads over your existing FreeRTOS. To use it run it on the main after initializing all the threads. Do not mix CorePartition over different threads, it must stay confined in a single one.

Please note: Processors and Microcontroller or System that relays os Watchdog. it is necessary to give it at least a 100 nano seconds of free time once a while, otherwise it will trigger and reboot the system for supposedly infinity loop. so having thread with zero priority can be problematic, to fix it, always implement time and sleep interface to let the kernel call for sleep on appropriate time and be sure to execute at least 100 nano seconds for the sleep interface, even on zero sleep request (That is why it request zero...). For examples, look at any example provided by the lib

# Arduino

As always reported, it is fully compatible with Arduino, any one, to use it download the zip file from my master branch (https://github.com/solariun/CorePartition/archive/master.zip) and import it in at arduino -> Sketch -> Include Library -> Add ZIP Library... and you are good to go.
As always reported, it is fully compatible with Arduino, any one, with Single Core or NO OS, to use it download the zip file from the master branch (https://github.com/solariun/CorePartition/archive/master.zip) and import it in at arduino -> Sketch -> Include Library -> Add ZIP Library... and you are good to go.

Arduino official documentation for adding libraries: https://www.arduino.cc/en/guide/libraries

# Important information

Core partition was design for single cores processors and micro controllers, since it will not try to swtich betten different cores and will the currebt thread/core to create an full thread environment and control it. Note that it will also create cooperative thread for softwares, enabling it to be able to use Threads without compromising the whole system.
CorePartitionOS was design for single cores processors and micro controllers, since it will not switch between different cores, instead it will use one and slice it while controling it to create threads, deploying a full multi thread environment. Note that it will also create cooperative thread for softwares, enabling it to be able to use lightweight Threads without compromising the whole system.

By default it will use Cooperative thread, which mean the developer will need to call CorePartition_Yield() to trigger context changing. But, by using a timer you will be able to make it preemptive. An example of prenptivess is also provided for a micro controller Atmel 328Pm, run it at Arduino IDE and a NANO boards.
By default it will use Cooperative thread, which means the developer will need to call CorePartition_Yield(), CorePartition_Wait(), CorePartition_WaitMessage() or CorePartition_Sleep() to trigger context switching. But, by using a timer you will be able to make it preemptive. An example of prenptivess is also provided for a micro controller Atmel 328Pm, run it at Arduino IDE and a NANO boards.

All the examples are done using Arduino, why? First because it will act as a HAL (Hardware Abstraction Layer) interface, so, doesn't mater the processor or microcontroller, this Thread will deploy the same results, and will be ready for any hardware interaction: timer, interruption and architecture.

CorePartition really deploys threads, it is not proto-thread, task lib or any re-entrant thing, it is a fully thread implementation with memory page to isolate the thread context and even with a secure context (just introduced)
CorePartitionOS really deploys threads, it is not proto-thread, task lib or any re-entrant thing, it is a fully thread implementation with memory page to isolate the thread context and even with a secure context (just introduced)


# Minimal Resources
# Minimal C Resources

This lib uses NO ASSEMBLER, it will benefit from standard C (minimo of C99) principles, proving it is capable to create threads to any environment.

Expand Down Expand Up @@ -77,26 +94,26 @@ This feature will remain on Experimental for certain time.

# Momentum Scheduler

*The Momentum Scheduler* is optimised to only allow thread to come back to work only upon its "nice" time or later than that, it means it will work on soft real time as long as the developer keep all the functions clean. For some big logic, there will have two way to keep it peace for all the functions, using CorePartition_Yield, that will comply with the nice principle or CorePartition_Sleep that you can dynamically call a specialized nice. If you are using a Tick interface to work as milliseconds, nice will me n milliseconds, examples of how to do it is also provided for Desktop application and processor (through Arduino exempla for keeping it simple).
*The Momentum Scheduler* is Timer based Scheduler optimised to only allow thread to come back to work only its "nice" time or later than that, it means it will work on soft real time as long as the developer keep all the functions clean and fast till the point it call context for a context switch. For some big logic, there will have two way to keep it peace for all the functions, using CorePartition_Yield, that will comply with the nice principle or CorePartition_Sleep that you can dynamically call a specialized nice. If you are using a Tick interface to work as milliseconds, nice will me n milliseconds, examples of how to do it is also provided for Desktop application and processor (through Arduino exempla for keeping it simple).

HIGHLY suitable for Arduino (All official models included) as well, a .ino project is also provided with an example.
HIGHLY suitable for Arduino (All official single cores models included) as well, a .ino project is also provided with an example.

Be aware that the CorePartition Lib is a pico Virtual Core emulation, it will slice your CPU or user space application into n threads (partitions) and will create a virtual stack page (the size of each stack page will be defined by the moment you create a partition), for each partition starting by a function already assigned to initiate the virtual core.
Be aware that the CorePartitionOS Lib is a pico Virtual Core emulation, it will slice your CPU or user space application into n threads (partitions) and will create a virtual stack page (the size of each stack page will be defined by the moment you create a partition), for each partition starting by a function already assigned to initiate the virtual core.

To calculate how much memory it will consume, start with the notion that each thread will consume around 60 ~ 170 bites depending on your target default bit channel size (8bits, 16bits, 32bits ... processor) plus the virtual stack page.
To calculate how much memory it will consume, start with the notion that each thread will consume around (8btis)60 ~ 170 bites depending on your target default bit channel size (8bits, 16bits, 32bits ... processor) plus the virtual stack page.

Be AWARE comes with no warrant or guarantees, since I still have a limited number to target to test, but for those it is fully functional till this point. If you intend to use this code, please make a reference of me as its creator. The commercial use is also permitted as long as I am notified and referenced in the code.
Be AWARE that it comes with no warrant or guarantees, since I still have a limited number to target to test, but for those it is fully functional till this point. If you intend to use this code, please make a reference of me as its creator. The commercial use is also permitted as long as I am notified and referenced in the code.


## Important

If possible it is HIGHLY RECOMMEND to implement the momentum with a proper time function. It will ensure stability and the developer will be able to use time to control thread process, examples of it is provided here and in every example.
It is mandatory the implementation of all momentum interfaces with a proper time/counter function. It will ensure stability and the developer will be able to use time to control thread process, examples of it is provided here and in every example.

Tested at:

ESP8266 8 different boars including ESP-01

ESP32 - No OS and with FreeRTO - Note that ESP32 uses a lot of stack, so, if a example fails with stack over flow (it will appear on the terminal), read the error, it will say how muck stack it was needing, incrise the CreateThread to somerhing between the needed stack or higher)
ESP32 - No OS, also tested with Spressif RTOS but just for fun, I would not use it, use it with ESP8266 (FULLY compatible) or without FREERTOS, but it will only use one core.

Arduino Nano (avr 328p)
Arduino Nano (avr 168) -> Thread.ino must have 2 threads due to memory
Expand Down Expand Up @@ -137,56 +154,46 @@ tested on HPUX
tested on Solaris


If you want to start, what about you dust off a old arduino, like a nano, and open the thread.ino or LowMememryExame example that comes with examples and have a look at it?
If you want to start, what about you dust off a old arduino, like a nano, and open the thread.ino or LowMememryExample.ino example that comes with examples and have a look at it?


# A Simple example

This is how to use it

```
#include "CorePartition.h"
#include <sys/time.h>
#include <unistd.h>
#include <assert.h>
#include "CorePartition.h"
void Thread1(void* pValue)
{
int nValue = 100;
int nValue = 0;
while (1)
while (CorePartition_Yield())
{
printf ("Thread1: Value [%d]\n", nValue++);
CorePartition_Yield();
printf ("Thread %zu: Value [%d] every %u ms\n", CorePartition_GetID(), nValue++, CorePartition_GetNice());
}
}
void Thread2(void* pValue)
{
int nValue = 1000;
int nValue = 0;
while (1)
while (CorePartition_Yield())
{
printf ("Thread2: Value [%d]\n", nValue++);
CorePartition_Yield();
printf ("Thread %zu: Value [%d] every %u ms\n", CorePartition_GetID(), nValue++, CorePartition_GetNice());
}
}
/*
* I totally advise for the use of the
* momentum interface to setup a time measurement
* for the CorePartition Kernel, also, some
* controllers like ESP required a realignment
* that can be done by calling sleep, so
* using it is highly recommended
* /
static void sleepMSTicks (uint32_t nSleepTime)
void CorePartition_SleepTicks (uint32_t nSleepTime)
{
usleep ((useconds_t) nSleepTime * 1000);
}
static uint32_t getMsTicks(void)
uint32_t CorePartition_GetCurrentTick(void)
{
struct timeval tp;
gettimeofday(&tp, NULL);
Expand All @@ -205,30 +212,28 @@ int main ()
assert (CorePartition_Start (3));
assert (CorePartition_SetCurrentTimeInterface(getMsTicks));
assert (CorePartition_SetSleepTimeInterface (sleepMSTicks));
assert (CorePartition_SetStackOverflowHandler (StackOverflowHandler));
//Every 1000 cycles with a Stack page of 210 bytes
assert (CorePartition_CreateThread (Thread1, NULL, 210, 1000));
//All the time with a Stack page of 150 bytes and
//thread isolation
assert (CorePartition_CreateSecureThread (Thread2, NULL, 150, 0));
assert (CorePartition_CreateSecureThread (Thread2, NULL, 150, 2000));
assert (CorePartition_CreateSecureThread (Thread2, NULL, 150, 500));
CorePartition_Join();
}
```

inside your partitioned program (function) use the directive CorePartition_Yield() to let the nano microkernel process next thread, so do not forget to call CorePartition_Yield() or use CorePartition_Sleep() regularly.
Inside your partitioned program (function) use the directive CorePartition_Yield() to let the nano microkernel process next thread, so do not forget to call CorePartition_Yield() or use CorePartition_Sleep() regularly.

# Arduino Boards

This thread is HIGHLY SUITABLE for small arduinos like NANO (Works like magic) and ATTINY85

But it is suitable for ALL ARDUINOS.... just try it out.... it will work !
But it is suitable for ALL single core ARDUINOs.... just try it out.... it will work !


# Some visual examples
Expand Down
Loading

0 comments on commit 8486130

Please sign in to comment.