Skip to content

My own implementation for a Real-Time MicroKernel to be run on ARM-Cortex Microprocessors.

Notifications You must be signed in to change notification settings

heshamkhaledd/Jarvis-OS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Jarvis-OS

Jarvis-OS is a live Real time operating system ready to run on ARM Cortex-M processors.
Jarvis-OS MicroKernel supports the following features:

  • Preemptive Weighted Round-Robin Scheduler
  • Semaphores (Binary and Spinlock)
  • Dynamic Queues for Inter-Thread Communication

Table of contents

Jarvis-OS User Configurations

In order to configure Jarvis-OS to work in your favor, you need to change the parameters found in JarvisOS-CONFIG.h

#define F_CPU                   16000000      /* Your ARM Cortex-M Frequency */
#define NUM_OF_THREADS          3             /* Number of Threads Your System Require */
#define STACK_SIZE              100           /* Stack size for each thread */
#define QUANTA                  100           /* Scheduler's Quanta in milliseconds */
#define ThreadID_MAX_LENGTH     15            /* Thread ID string maximum length */
#define port_MAX_DELAY          2             /* An Optional Macro to determine delays in Quanta */

API Functions

• Threads Control

  1. ThreadCreate


  • Description: Creates a thread in the MicroKernel
  • Parameters:
Parameters Type Description
ThreadID uint8_t [ ] String to Identifiy the Thread
ThreadAddress void(*Thread) Thread Address
Thread Priority uint8_t Priority of Thread
  • Return: void
  • Example:
void Thread_1 (void){
    /* Thread inits */
    while (1)
    {
        /* Thread Subroutine */
    }
}

int main ()
{
    ThreadCreate ("ThreadID_1",Thread_1,5);
    /* Rest of main */
}

  1. Thread_Suspend

  • Description: Suspends a Thread for specific time in Quanta
  • Parameters:
Parameters Type Description
delayTime uint32_t Delay Time in Quanta
  • Return: void
  • Example:
void Thread_2 (void){
    /* Thread inits */
    while (1)
    {
        /* Thread Subroutine */
        Thread_Suspend (2);     /* Thread will be suspended two quantas */
    }
}

  1. Thread_Block

  • Description: Blocks a thread entirely and put it in blocked state
  • Parameters:
Parameters Type Description
ThreadID uint8_t[ ] String to Identifiy the Thread
  • Return: void
  • Example:
void Thread_1 (void){
    /* Thread inits */
    while (1)
    {
        /* Thread Subroutine */

        Thread_Block ("DataThread");

        /* Rest of Subroutine */
            
    }
}
void Thread_2 (void){
    
    while (1)
    {
        /* Thread Subroutine */ 

        /* THIS THREAD WILL BE BLOCKED UNTIL RESUMED */  
    }
}
int main ()
{
    ThreadCreate("DMAThread",Thread_1,2);
    ThreadCreate("DataThread",Thread_2,4);

    /* Rest of main */
}

  1. Thread_Resume

  • Description: Releases a Thread from its blocked state
  • Parameters:
Parameters Type Description
ThreadID uint8_t[ ] String to Identifiy the Thread
  • Return: void
  • Example:
void Thread_1 (void){
    /* Thread inits */
    while (1)
    {
        /* Thread Subroutine */

        Thread_Block ("DataThread");

        /* Rest of Subroutine */

        Thread_Resume ("DataThread");
            
    }
}
void Thread_2 (void){
    
    while (1)
    {
        /* Thread Subroutine */ 

        /* THIS THREAD WILL BE BLOCKED UNTIL RESUMED */  
    }
}
int main ()
{
    ThreadCreate("DMAThread",Thread_1,2);
    ThreadCreate("DataThread",Thread_2,4);

    /* Rest of main */
}

  1. JARVIS_initKernel

  • Description: Stars the Scheduler and initialize the Kernel
  • Parameters:
Parameters Type Description
void
  • Return: void
  • Example:
int main 
{
    /* Threads, Queues and Semaphores initializing */
    
    JARVIS_initKernel ();

    while (1);  /* UNREACHABLE CODE */
}


• Semaphores

  1. SemaphoreCreateBinary


  • Description: Creates a Binary Semaphore of 1 token
  • Parameters:
Parameters Type Description
&SemphHandle SemaphoreHandle_t Address to Semaphore
  • Return: void
  • Example:
SemaphoreHandle_t semaphore_1;  /* Delacring a semaphore Handle */

int main ()
{
    SemaphoreCreateBinary (&semaphore_1);
    /* Rest of main */
}

  1. SemaphoreCreate

  • Description: Creates a Semaphore of given number of tokens
  • Parameters:
Parameters Type Description
&SemphHandle SemaphoreHandle_t Address to Semaphore
Tokens uint32_t Number of Tokens this Semaphore
  • Return: void
  • Example:
SemaphoreHandle_t semaphore_1;  /* Delacring a semaphore Handle */

int main ()
{
    uint32_t num_of_tokens = 5;
    SemaphoreCreate (&semaphore_1,num_of_tokens);
    /* Rest of main */
}

  1. SemaphorePend

  • Description: Pends (Takes) one token of a given semaphore
  • Parameters:
Parameters Type Description
&SemphHandle SemaphoreHandle_t Address to Semaphore
ThreadDelay uint32_t Delay Time in Quanta if there is no tokens
  • Return: void
  • Example:
void Thread_1(void){

    while (1){
        SemaphorePend(&semaphore_1,port_MAX_DELAY); /*port_MAX_DELAY is
                                                      found at config file */
        /* Thread Subroutine */
    }
}

  1. SemaphorePost

  • Description: Posts (Gives) one token of a given semaphore
  • Parameters:
Parameters Type Description
&SemphHandle SemaphoreHandle_t Address to Semaphore
  • Return: void
  • Example:
void Thread_1(void){

    while (1){
        
                 /* Thread Subroutine */

        SemaphorePost(&semaphore_1);
    }
}


• Queues

  1. QueueCreate


  • Description: Creates a queue in heap segment of a given size
  • Parameters:
Parameters Type Description
length int32_t Queue Length
size uint8_t Size of Each Location
  • Return: QueueHandle_t, If it successfully allocated the Queue
                  NULL, If there's no heap space to allocate the Queue.
  • Example:
QueueHandle_t queue_1;
int main ()
{
    queue_1 = QueueCreate(17,sizeof(uint32_t));
    if (queue_1 == NULL)
    {
        /* Code to handle the case */
    }
    else
            /* Rest of main */
}

  1. QueueWrite


  • Description: Writes data to a specific queue.
  • Parameters:
Parameters Type Description
queue QueueHandle_t Queue Handle
data uint32_t Data to be written
  • Return: ERROR_QUEUE_NULL, If the queue doesn't exist
                'ERROR_QUEUE_FULL', If the queue is already full.
                'SUCCESS', If it successfully sent data to queue.
  • Example:
QueueHandle_t queue_1;

void Thread_1(void)
{
    uint32_t data = 87;

    while (1)
    {
        /* Thread Subroutine */

        int8_t var = QueueWrite(queue_1,data);

        if (var == ERROR_QUEUE_FULL)
        {
            /* Code to handle the case */
        }

        /* Rest of Thread Subroutine */

    }
}

  1. QueueReceive


  • Description: Reads data from a specific queue.
  • Parameters:
Parameters Type Description
queue QueueHandle_t Queue Handle
&var uint32_t Variable to read the data into
  • Return: ERROR_QUEUE_NULL, If the queue doesn't exist
                'ERROR_QUEUE_EMPTY', If the queue is already empty.
                'SUCCESS', If it successfully received data from queue.
  • Example:
QueueHandle_t queue_1;

void Thread_8(void)
{
    uint32_t data_receive;

    while (1)
    {
        /* Thread Subroutine */

        int8_t var = QueueReceive(queue_1,&data_receive);

        if (var == ERROR_QUEUE_EMPTY)
        {
            /* Code to handle the case */
        }

        /* Rest of Thread Subroutine */

    }
}

  1. QueueIsEmpty


  • Description: Checks if the Queue is Empty or not.
  • Parameters:
Parameters Type Description
queue QueueHandle_t Queue Handle
  • Return: '1', If the queue is empty.
                 '0', If the queue is not empty.

  1. QueueIsFull


  • Description: Checks if the Queue is Full or not.
  • Parameters:
Parameters Type Description
queue QueueHandle_t Queue Handle
  • Return: '1', If the queue is full.
                 '0', If the queue is not full.


Notes

• Jarvis-OS uses ARM Cortex-M processors SysTick timer. In order to port Jarvis to
your ARM processor, you need to extern SysTick_Handler in your startup (stub) code
and place it in SysTick location in the Interrupt Vector Table (IVT)

/* in startup code */

extern void SysTick_Handler (void);

• Since queues use dynamic allocation, change the value of heap size from the IDE you are using,
or from the linker script if you're using text editors using this flag

--heap_size = <the value you want>

Building ARM Project

If you don't use ARM supported IDE's and just prefer using your own developing environment
You can still use Jarvis-OS!
I recommend to use my generic ARM Cortex Build system
Repository Link: ARM Build System

About

My own implementation for a Real-Time MicroKernel to be run on ARM-Cortex Microprocessors.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages