📄 rtos_services.h
字号:
/*
** Copyright (C) 2006 Tamir Michael
**
** 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 2 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, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// this header file contains macros required to define tasks and other RTOS primitives
#ifndef _RTOS_SERVICES
#define _RTOS_SERVICES
#include <intrins.h>
#include "queue.h"
// constants
#define DEFUALT_STACK_SIZE 256
#define MAXIMUM_STACK_SIZE 512
#define MINIMUM_STACK_SIZE 32
#define MAX_TASKS 20
#define MAX_MUTEXES 20
#define MAX_SEMAPHORES 20
#define MAX_TIMERS 40
#define IDLE_TASK_PRIORITY PRIORITY_7 // the lowest priority
#define MAX_PRIORITY_LEVELS (PRIORITY_7+1) // given 8 priority levels, 8 bits will be needed to represent them. see 'prio_array'.
#define DEFAULT_TASK_PRIORITY PRIORITY_4 // scale is 0-7, 0 is critical
#define NUM_INTERRUPTS 80
typedef enum
{
PRIORITY_0 = 0,
PRIORITY_1,
PRIORITY_2,
PRIORITY_3,
PRIORITY_4,
PRIORITY_5,
PRIORITY_6,
PRIORITY_7
} task_priorities ;
typedef enum // execution time in units of 100us
{
TIME_SLICE_0 = 200,// critical
TIME_SLICE_1 = 170,
TIME_SLICE_2 = 160,
TIME_SLICE_3 = 140,
TIME_SLICE_4 = 130,
TIME_SLICE_5 = 120,
TIME_SLICE_6 = 110,
TIME_SLICE_7 = 50 // lowest priority (execution time 5[ms])
} task_time_slices ;
// top of system stack - must be as defined in the START167.A66 file!
#ifdef _DEBUG
#define SYSTEM_STACK_TOP 0xFC00
#else
#define SYSTEM_STACK_TOP 0xF800
#endif
#define SYSTEM_STACK_SIZE 0x200
// WAR STORY
// "L" converts integers to 'long' (32 bit). otherwise, 'int' (16 bit) is used by default, causing overflows.
#define HUNDREDTH_MICROSECONDS(x) (x)
#define MILLISECONDS(x) (x*10L) // GPT1 Core Timer 3 ticks at 100[祍] just as GPT2 Core Timer 6
#define SECONDS(x) (MILLISECONDS(x)*1000L)
#define MINUTES(x) (SECONDS(x)*60L)
#define HOURS(x) (MINUTES(x)*60L)
typedef void (* far taskptr) (void) ; // a pointer to a task callback (two words)
typedef void (* far callback_ptr) (int32s) ; // a pointer to a task callback (two words)
typedef int16u stacktype ; // each stack element is a word
typedef enum
{
eRoundRobin = 0,
eEarliestDeadlineNext,
ePriorityBased
} schedule_policy ;
typedef enum
{
eTimerNotAllocated = 0,
eTimerAllocated,
eTimerTicking,
eTimerSuspended
} timer_state ;
typedef enum
{
ePeriod = 0, // periodical timer
eOneShot, // timer is deallocated after elapsing once
eOneShotNonRelease,
eFlag
} timer_type ;
// WAR STORY
// preferably, if not too expensive to complete, all structures should have a size that is a power of 2 so that looping
// through an array of structures, for example, will not incur an expensive 'MUL' instruction to calculate the offset
// of elements - but a 'SHL' instruction instead.
typedef struct
{
int32s id ;
timer_state state ;
callback_ptr callback ;
int16s owner ;
timer_type type ;
int32u period ;
int32u deadline ;
int32s parameter ;
int32u *missed_deadline_counter ;
int32s power2patch1 ; // a patch for 2^3 = 8 bytes. see war story.
} timer_info ;
typedef enum
{
eTaskNotAllocated = 0,
eTaskReady, // operational, can be scheduled for execution
eTaskSuspended, // suspended
eTaskWaiting, // wating on a wait function
eTaskWaitingForMessage, // task waiting for a message
eTaskBlockedMutex, // on a synchronization primitive
eTaskBlockedSemaphore,
eTaskWaitingForInterrupt // task waiting for an interrupt to occur
} task_state ;
typedef struct
{
int16s id ; // allocated task id
stacktype *stack ; // pointer to user provided stack
stacktype *sp ;
stacktype *r0 ;
stacktype **r0_ptr ; // sp for user section of stack
int16u stack_size ; // should be the sum of SSTSZ and USTSZ
int8u priority ; // task priority
taskptr callback ;
task_state status ;
queue_info incoming_msg ;
int16s wait_timer ; // the handle of the timer started for a task once it calls 'scheduler_task_wait'
int16s msg_wait_timer ; // the handle of the timer started for a task once it calls 'rtos_wait_msg'
int16s time_slice ;
int8u lock_ref_counter ;
int32u exe_start ;
int32u last_schedule_session ;
taskptr prior_to_context_switch_callback_when_interrupted ;
int8u immediate_switch_to_waiting_task_when_interrupted ;
int16u blocked_on_primitive ; // indicates on which synchronization element the task is blocked
} task_info ;
typedef struct
{
int8u priority_bitmap ; // reserve one bit per priority level
queue_info priority_queues[MAX_PRIORITY_LEVELS] ; // each priority has a queue of tasks
} prio_array ;
// stack level check
#define VERIFY_STACK(warning_threshold, error_threshold)\
if ( (SYSTEM_STACK_TOP - SP) > SYSTEM_STACK_SIZE - warning_threshold) \
{\
software_warning("%s %s %d", resolve_system_message(ERR_STACK_SPACE_LOW), __FILE__, __LINE__ ) ;\
} else if ( (SYSTEM_STACK_TOP - SP) > SYSTEM_STACK_SIZE - error_threshold) \
{\
software_error("%s %s %d", resolve_system_message(ERR_STACK_SPACE_OUT), __FILE__, __LINE__ ) ;\
}
// module interface starts here
// interrupt control
void rtos_enable_interrupts() ;
void rtos_disable_interrupts() ;
void rtos_save_and_disable_interrupts(int8u*) ;
void rtos_restore_interrupts(int8u) ;
// interrupt safe assignments
void interrupt_safe_assign_ulong(unsigned long*, const unsigned long*) ;
void interrupt_safe_assign_uint(unsigned int*, const unsigned int*) ;
void interrupt_safe_assign_uchar(unsigned char*, const unsigned char*) ;
// task wait function for interrupts
void rtos_interrupt_wait(int8u, taskptr, int8u) ;
// time services
int16s rtos_allocate_timer() ;
int16s rtos_deallocate_timer(int16s) ;
int16s rtos_callback_timer_inform_every(int16s, int32u, callback_ptr, int32s) ;
int16s rtos_callback_timer_inform_in(int16s, int32u, callback_ptr, int32s) ;
int16s rtos_flag_timer_inform_in(int16s, int32u, int32u*) ;
int16s rtos_timer_suspend(int16s) ;
int16s rtos_timer_resume(int16s) ;
int32s rtos_timer_ticks_left_to_go(int16s) ;
// scheduler routines
void rtos_enable_scheduler() ;
void rtos_disable_scheduler() ;
int16s scheduler_create_task(taskptr, int8u, stacktype*, int16u, task_state) ;
int16s scheduler_set_task_priority(int16s, int8u) ;
int16s scheduler_delete_task(int16s) ;
int16s scheduler_get_current_task_id() ;
int16s scheduler_get_number_tasks() ;
task_state scheduler_get_task_state(int16s) ;
int16s scheduler_set_policy(schedule_policy) ;
void scheduler_start() ;
void scheduler_reschedule() ;
int16s scheduler_task_wait(int32u) ;
int16s scheduler_task_resume(int16s) ;
int16s scheduler_task_suspend(int16s) ;
void scheduler_pause_all_timers() ;
void scheduler_resume_all_timers() ;
int16s scheduler_wake_up_task(int16s) ;
void scheduler_register_idle_hook(callback_ptr, int32s) ;
void scheduler_unregister_idle_hook() ;
// task backup and recovery
int16s rtos_take_task_snapshot() ;
int32s rtos_restore_task_snapshot() ;
int32s rtos_snapshot_task_id() ;
// intertask communication
int16s rtos_post_task_msg(int16s, int32s) ;
int16s rtos_msg_wait(int32s*, int32u) ;
// general system routines
int32s rtos_system_time(int16u *, int16u *, int32u *, int32u *) ;
void rtos_init(callback_ptr) ;
int8u eos_version_major() ;
int8u eos_version_minor() ;
#endif // _RTOS_SERVICES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -