Tasks
The system provides preemptive and corporate multitasking.
Limitations:
1. The maximal amount of tasks = 255.
2. Program stask.
3. The minimal sizes: Flash = 2048, RAM = 256, stack of returns = 16, stack of data = 50
byte.
Conditions: Without use of the assembler language (only
asm-inserts).
The system includes subsystems:
- MULTI-TASKING;
- PRIMITIVES OF SYNCHRONIZATION.
MULTI-TASKING and PRIMITIVES OF SYNCHRONIZATION in sum provide
multiprogramming both
at a level of tasks and at a level of interruptions.
MULTI-TASKING provides the work in a mode of
multiprogramming and formalizes concept of a task.
In LG.RTOS a task is the object of synchronization - which consumes
resources (memory, execution time,
time of an exchange and so forth).
The representative of a task in system is the Passport of a task.
The Passport of a task is an object of a pseudo-class on ANSI-C, which
possesses the following properties:
- The address of a task in queue (not obligatory attribute);
- A word of a status (not obligatory attribute);
- The address of the memory administrator (not obligatory
attribute);
- A timer or timeout;
- A stack of a task;
- Executive function - a task body;
- A name or priority of a task (not obligatory attribute).
Methods of the passport are:
- The user procedure of the current step of a task (not obligatory
attribute);
- Methods of the memory administrator (not obligatory attribute);
The mechanism of a task is used for the organization of threads.
Existes two types of tasks: a static task and a dynamic task.
The static task exists constantly. The dynamic task can be created and
liquidated at the request of the user.
MULTI-TASKING has the following interface:
void MTASKS_Init ( void
); //Initialization of multitasking
BYTE MTASK_GetNAME ( TTASK*
); //Finds the task number
void MTASK_ReNAME ( BYTE , BYTE
); //To Update a task priority
void MTASK_Sleep ( NUM
); //To set a sleep mode for task
void MTASK_Activate ( BYTE , BOOL
); //To cancel a sleep mode for task
BOOL MTASK_IsSLEEP ( TTASK*
); //Is sleep task
BOOL MTASK_IsREADY ( BYTE
); //Is ready Task
void MTASK_Scheduler ( BOOL
); //Scheduler
void MTASK_Init ( BYTE, TTASK*,
void(*)() ); //Initialization of task
void MTASK_ISR_Enable( void
); //Interrupt enable
TTASK* MTASK_Create ( BYTE, NUM,NUM,NUM,void(*)());
//Procedure creates task
void MTASK_Free ( BYTE
); //To kill the task
The task list of is ordered according to tasks
priorities. The priority of any task can be updated.
After restart of the controller, OS execute a task TASK_0. Task TASK_0 has the
lowest priority.
The task body TASK_0 is function MAIN.
PRIMITIVES OF SYNCHRONIZATION containes libraries:
- CRITICAL SECTION;
- MUTEX;
- EVENT;
- LOCK.
PRIMITIVES OF SYNCHRONIZATION provide process of interaction of threads:
- in a mode of multiprogramming;
- for multiprocessor systems with the shareable storage .
CRITICAL SECTION synchronizes access of tasks to the shared resources by
way of interruptions lock.
The library has the following interface:
void CRITICAL_SECTION_Start ( void ) ;
//The beginning of critical section
void CRITICAL_SECTION_End ( void ) ;
//The end of critical section
MUTEX-library synchronizes access of tasks to the shared resources through a
binary-semaphore.
The library has the following interface:
void MUTEX_Init (
TMutex * ); //Initialization of
semaphore
BOOL MUTEX_Lock ( TMutex * , BOOL ); //Lock of
semaphore
void MUTEX_UnLock ( TMutex *
); //Un Lock of semaphore
BOOL MUTEX_IsLocked ( TMutex *
); //Check of semaphore status
EVENT-library provides signaling about events. Event can contain the message.
The library has the following interface:
void
EVENT_Init ( TEvent * , void* );
//Initialization of EVENT
void EVENT_PutMSG ( TEvent * , void* );
//To place the message into EVENT
void* EVENT_GetMSG ( TEvent *
); //To get the message from EVENT
BOOL EVENT_Wait ( TEvent * ,
WORD ); //To wait for event
void EVENT_Publishing ( TEvent *
); //Event publishing from TASK
void EVENT_ISR_Signal ( TEvent *
); //To signal about event from ISR
BOOL EVENT_Status ( TEvent *
); //To get the status
void EVENT_Clear ( TEvent *
); //Reset of event (clear status)
LOCK-library allow to solve the following
tasks:
- Synchronization of threads for access to the shareable resources in
multiprocessor systems;
- The signaling about events.
Synchronization of threads is executes through binary semaphores. The binary
semaphore is an object of a
pseudo-class on ANSI-C. Methods of a pseudo-class is procedures of reaction to
events of opening and
closing of a semaphore. The user can redefine system methods - reactions to
events of a semaphore and
create own strategy of the synchronization.
LOCK-library include the following functions:
- create a semaphore (initialization and allocation of resources for a
semaphore);
- remove a semaphore (deallocation of resources of a semaphore);
- open a semaphore (start-up of reaction of the user on opening of a semaphore;
further the system
opens a semaphore and a thread continues work);
- skip a semaphore (as against the previous operation, the semaphore does not
open);
- close a semaphore (indivisible operation of closing of a semaphore; if the
semaphore is open:
the system closes a semaphore and a thread continues work; if the semaphore is
closed, the system
executes the user reaction to the closed semaphore; further the system waits
when the semaphore will
be opened and closes a semaphore).
MULTI-TASKING and the
PRIMITIVES OF SYNCHRONIZATION provide the user
with
mechanisms for
creation
of the multitasking environment.
// File : main.c
//##########################################################################################//
//# E X A M P L E O F A M U L T I T A S K I N G #//
//##########################################################################################//
//==========================================================================================//
// Configuration: Hardware and RTOS
//==========================================================================================//
#include "OS_PARAM.h" //Parameters and modes
#include "Platform.h" //Target platform
#include "OS_CONF.h" //RTOS Configuration
#include "OS_CONF.c" //RTOS Implementation
//==========================================================================================//
// Application
//==========================================================================================//
#include "App.h" //Application globals
#include "App.c" //Application implementation
#include "App_ISR.c" //Interrupts into application
//##########################################################################################//
//# M A I N A P P L I C A T I O N #//
//##########################################################################################//
APPLICATION()
{// Start of a method //
RTOS_Init() ; //Init of RStack, RAM bounds...
ERR_Init() ; //Init of Exceptions Handler
DEBUG_Init() ; //Initialization of debuger
MTASKS_Init() ; //Initialization of multitasking.
APP_ISR_Init() ; //Initialization of interruptions
//Initialization of tasks
MTASK_Init( 1, TASK_1, Task1WaitAndGetMessage ) ; //Creation of a TASK 1
MTASK_Init( 2, TASK_2, Task2EventPublishingFromTASK ) ; //Creation of a TASK 2
MTASK_Init( 3, TASK_3, Task3WaitEventFromISR ) ; //Creation of a TASK 3
//Initialization of events
EVENT_Init ( &eDATA , &msgTX ) ; //Event initiation + Message
EVENT_Init ( &eFLAG , 0 ) ; //Event initiation
EVENT_Init ( &eISR , 0 ) ; //Event initiation from ISR
MUTEX_Init ( &Mutex ) ; //Mutex initialization
//============================================================================================
// Main algorithm ( TASK_0 Body )
//============================================================================================
while(1) {
MTASK_ISR_Enable(); //SEI-Enable + SEI + not RAW in ISR
CRITICAL_SECTION_Start(); //The beginning of critical section
if ( MUTEX_IsLocked ( &Mutex ) == NO ) { //If the semaphore is open
resSHARED++; //Access of a task to shared resource
}
CRITICAL_SECTION_End(); //The end of critical section
//Sleeping and Event Publishing
EVENT_Publishing( &eFLAG ); //Event signal
MTASK_Sleep ( 2 ); //Put of the current task in sleep
}
RTOS_Exit(); //Exit from OS
}// End of a method //
//============================================================================================
// The end of a file //
//============================================================================================
// Ōąéė : OS_PARAM.h
//##########################################################################################//
//# O S P A R A M E T E R S #//
//##########################################################################################//
//////////////////////////////////////////////////////////////////////////////////////////////
// Parameters and modes of functioning of system
//////////////////////////////////////////////////////////////////////////////////////////////
//===========================================================================================
// Modes
//===========================================================================================
//#define yDebug 1 //Debug mode
//#define Warnings 1 //Disabling of warnings
//#define ErrHandler 1 //Errors check
//#define ErrRestart 1 //Restart at exceptions
//#define yERR_in_LCD 1 //Errors on the display
//#define yTEST 1 //Test mode
//#define yNoRAW 1 //Not RAW in ISR(Usually for IAR < V4.12 )
//#define ySimForICC 1 //For compatibility with of ICC-simulation
//============================================================================================
// Parameters
//============================================================================================
#define MCU_SPEED (unsigned long)(18434000) //MCU
#define adrEND_RAM 0x10FF //The end address of RAM (for IAR, ICC & GCC)
#define sizRSTACK 16 //Default size of RETs STACK=16(8 CALLs)
#define sizDSTACK 50 //Default size of DATA STACK
#define cntTASK 4 //Process amount
#if cntTASK > 1 //If there is a multiprogramming
#define MTASK_TimerUserAgent() { } //Running of a user method into MTASK_Timer
#endif
//===========================================================================================
// The end of a file //
//===========================================================================================
// File : App.h
//##########################################################################################//
//# A P P L I C A T I O N G L O B A L S #//
//##########################################################################################//
oTASK ( 1, sizRSTACK , sizDSTACK ); //TASK 1
oTASK ( 2, sizRSTACK , sizDSTACK ); //TASK 2
oTASK ( 3, sizRSTACK , sizDSTACK ); //TASK 3
typedef struct { DWORD Data ; } TMSG ; //Structure of message
TMSG msgRX ; //RX-message
TMSG msgTX ; //TX-message
BYTE resSHARED ; //Shared resourse
TEvent eDATA ; //Event + message
TEvent eFLAG ; //Event
TEvent eISR ; //ISR-Event
TMutex Mutex ; //Mutex
//============================================================================================
// The end of a file //
//============================================================================================
// File : App.c
//##########################################################################################//
//# A P P L I C A T I O N M E T H O D S #//
//##########################################################################################//
//============================================================================================
// Prototypes of functions
//============================================================================================
#ifdef COMPL_ICCAVR //For Image CRAFT
#pragma ctask Task1WaitAndGetMessage //TASK_1 Body. To get the message
#pragma ctask Task2EventPublishingFromTASK //TASK_1 Body. To get the message
#pragma ctask Task3WaitEventFromISR //TASK_1 Body. To get the message
#endif
NUDE void Task1WaitAndGetMessage ( void ) ; //TASK_1 Body. To get the message
NUDE void Task2EventPublishingFromTASK ( void ) ; //TASK_2 Body. To get the message
NUDE void Task3WaitEventFromISR ( void ) ; //TASK_3 Body. To get the message
//============================================================================================
// Implementation
//============================================================================================
////
// TASK_1 Body. To get the message
////
NAKED void Task1WaitAndGetMessage(void)
{// Start of a method //
//Locals
TMSG * p ;
////
// Body
////
#ifdef COMPL_ICCAVR //Image CRAFT
MTASK_Tuning( 1 );
#endif
while(1) {
MTASK_ISR_Enable(); //SEI-Enable + SEI + not RAW in ISR
EVENT_Wait( &eDATA, 0 ); //Event waiting
p = ( TMSG* ) ( EVENT_GetMSG( &eDATA ) ); //To get the message
msgRX.Data = p->Data; //Save the message
//Sleeping and Event Publishing
EVENT_Publishing( &eFLAG ); //Event signal
MTASK_Sleep ( 4 ); //Put of the current task in sleep
}
}// End of a method //
////
// TASK_2 Body. Event publishing from TASK
////
NAKED void Task2EventPublishingFromTASK(void)
{// Start of a method //
#ifdef COMPL_ICCAVR //Image CRAFT
MTASK_Tuning( 2 );
#endif
while(1) {
MTASK_ISR_Enable(); //SEI-Enable + SEI + not RAW in ISR
EVENT_Wait( &eISR, 0 ); //Event waiting
msgTX.Data++; //Create to message
EVENT_PutMSG ( &eDATA, &msgTX ); //To place the message
EVENT_Publishing( &eDATA ); //Event publishing
MTASK_Sleep ( 8 ); //Put of the current task in sleep
}
}// End of a method //
////
// TASK_3 Body. ISR-Event waiting and Activate Event-interrupt
////
NAKED void Task3WaitEventFromISR(void)
{// Start of a method //
#ifdef COMPL_ICCAVR //Image CRAFT
MTASK_Tuning( 3 );
#endif
while(1) {
MTASK_ISR_Enable(); //SEI-Enable + SEI + not RAW in ISR
if ( !MTASK_IsREADY( nTASK_0 ) ) { //if TASK0 is sleep
MTASK_Activate( nTASK_0, NO ) ; //Un sleep unconditional
}
EVENT_Wait( &eFLAG, 0 ); //Event waiting
MUTEX_Lock ( &Mutex, YES ); //Lock of semaphore
resSHARED--; //Access to shared resource
MUTEX_UnLock ( &Mutex ) ; //Un Lock of semaphore
MTASK_Sleep ( 16 ); //Put of the current task in sleep
}// End of a method //
////
// Init interrupts
////
void APP_ISR_Init()
{// Start of a method //
TCCR1B Set( WGM12 ) ; //CTC-mode = YES
OCR1A = 0xFFFF ; //Value of the comparison register
TCCR1B Set( CS10 ) ; //clk/1
TIMSK Set( OCIE1A ) ; //OC interrupt enable
}// End of a method //
////
// Timer1_ISR. Event publishing from ISR
////
#pragma vector hTIM1_COMPA
procTIM1_COMPA ( nTIM1_COMPA )
{// Start of a method //
EVENT_ISR_Signal( &eISR ); //Event publishing from TASK
}// End of a method //
//============================================================================================
// The end of a file //
//============================================================================================