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
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 */
- 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 */
}
- 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 */
}
}
- 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 */
}
- 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 */
}
- 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 */
}
- 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 */
}
- 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 */
}
- 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 */
}
}
- 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);
}
}
- 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 */
}
- 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 */
}
}
- 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 */
}
}
- 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.
- 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.
• 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>
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