?? sosos.c
字號:
/*=========================================================================================
項目名稱: 小型開源實時操作系統
軟件版本: VER 1.0
目標平臺: AVR系列單片機
工具鏈 : AVR-GCC(V4.1.2) WINAVR-20070525
開發人員: 韓驍
開發時間: 2007-07-05
版權 : GPL(GNU General Public License)
文件名稱: sosos.c
文件說明:
小型開源實時操作系統的主c文件
本次測試采用ARMEL公司的MEGA8進行
=========================================================================================*/
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include "MYBIT.H"
#include "sosos.h"
#if SOSOS_TASK_ENALBE == 1
void SososInitIntSp(void) __attribute__ ((constructor));//定義中斷嵌套堆棧指針
void SososInitIntSp(void)
//本函數在main()之前運行,將系統堆棧指針保存在r15:r14中
{
__asm__ __volatile__("PUSH r16 \n\t");
__asm__ __volatile__("IN r14 ,__SP_L__ \n\t");
__asm__ __volatile__("LDI r16 ,3 \n\t");
__asm__ __volatile__("ADD r14 ,r16 \n\t");
__asm__ __volatile__("IN r15 ,__SP_H__ \n\t");
__asm__ __volatile__("CLR r16 \n\t");
__asm__ __volatile__("ADC r15 ,r16 \n\t");
__asm__ __volatile__("POP r16 \n\t");
}
#endif
#if STACK_SIZE_REPORT_ENABLE == 1
unsigned int SOSOS_TASK_STACK_CASE(unsigned char pri,unsigned char id)//堆棧情況報告
//本函數用于返回指定任務的堆棧占用情況,單位:字節
//pri和id是要報告的任務優先級和ID
{
unsigned int i;
for(i=(TCB[pri*SOSOS_MAX_TASK_PER_PRI+id].TASK_STACK_BUTTON-TCB[pri*SOSOS_MAX_TASK_PER_PRI+id].TASK_STACK_SIZE+1);i<TCB[pri*SOSOS_MAX_TASK_PER_PRI+id].TASK_STACK_BUTTON;i++){
if(*((unsigned char *)i)!=INIT_STACK_FILL_BYTES)
break;
}
i=TCB[pri*SOSOS_MAX_TASK_PER_PRI+id].TASK_STACK_BUTTON-1-i;
return i;
}
#endif
#if SOSOS_TASK_ENALBE == 1
void SososInitOs(void)//初始化SOSOS系統
//本函數用于初始化SOSOS系統,應在調用任何系統函數前調用一次
{
#if ERROR_DETECT_ENABLE == 1
unsigned char i;
SOSOS_WAIT_TASK=0;
SOSOS_TIMESLICE=0;
SOSOS_INT_NEST=0;
SOSOS_TICKS=0;
SOSOS_STATE=0;
#if SOSOS_MUTEX_ENABLE == 1
SOSOS_MUTEX_POINT=0;
#endif
for(i=0;i<SOSOS_PRI_MAX;i++){
SOSOS_TASK_READY[i]=0;
}
for(i=0;i<SOSOS_PRI_MAX*SOSOS_MAX_TASK_PER_PRI;i++){
TCB[i].TASK_STACK_POINT=0;
}
#endif
#if STACK_SIZE_REPORT_ENABLE == 1
unsigned int fill;
for(fill=0;fill<SOSOS_TASK_STACK_SIZE;fill++)
SOSOS_TASK_STACK[fill]=INIT_STACK_FILL_BYTES;
#endif
SOSOS_TASK_STACK_TOP=(SOSOS_ADDRESS)SOSOS_TASK_STACK+SOSOS_TASK_STACK_SIZE-1;
}
#endif
#if SOSOS_TASK_ENALBE == 1
void SososTimer0(void)//延時和超時處理
//本函數在定時器0的中斷函數中調用,調用時中斷時開著的
//用于出來處理時間片輪換和所有的延時操作
{
unsigned char i,j,tmpi,tmpj;
SOSOS_TCB *point;
//超時處理
point=TCB;
tmpi=1;
DISABLE_INTERRUPT();
for(i=0;i<SOSOS_PRI_MAX;i++){
if((SOSOS_WAIT_TASK&tmpi)==0){
point=point+SOSOS_MAX_TASK_PER_PRI;//指向下一優先級
tmpi=tmpi<<1;
continue;
}
tmpj=1;
SOSOS_WAIT_TASK=SOSOS_WAIT_TASK&(~tmpi);
for(j=0;j<SOSOS_MAX_TASK_PER_PRI;j++){
if((point->TASK_STATE>=TASK_STATE_DELAY)&&(point->TASK_STATE<TASK_STATE_SEM_TIMEOUT)){
if(point->TASK_TIMEOUT>0){
point->TASK_TIMEOUT--;
if(point->TASK_TIMEOUT==0){
SOSOS_TASK_READY[i]=SOSOS_TASK_READY[i]|tmpj;
if(point->TASK_STATE>TASK_STATE_DELAY)
point->TASK_STATE=point->TASK_STATE+TASK_STATE_TIMEOUT_OFFSET;
else
point->TASK_STATE=TASK_STATE_OK;
#if SOSOS_MUTEX_ENABLE == 1
if(SOSOS_RUNNING_INHERIT_PRI>i){
#else
if(SOSOS_RUNNING_TASK_PRI>i){
#endif
set_bit(SOSOS_STATE,STATE_SCHED_REQ);
}
}
else
SOSOS_WAIT_TASK=SOSOS_WAIT_TASK|tmpi;
}
}
tmpj=tmpj<<1;
point++;
}
tmpi=tmpi<<1;
}
//時間片輪換處理
if((++SOSOS_TIMESLICE)>=SYS_TIMESLICE){
SOSOS_TIMESLICE=0;
#if SOSOS_MUTEX_ENABLE == 1
if((SOSOS_RUNNING_INHERIT_PRI==SOSOS_RUNNING_TASK_PRI)&&(SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]!=SOSOS_RUNNING_TASK_ID_INDEX))
#else
if(SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]!=SOSOS_RUNNING_TASK_ID_INDEX)
#endif
set_bit(SOSOS_STATE,STATE_SCHED_REQ);
}
}
#endif
#if SOSOS_TASK_ENALBE == 1
void SososSched (void) __attribute__ ((naked));//任務調度
void SososSched(void)//任務調度
//本函數是任務調度的核心函數,提供優先級繼承的調度支持,進入時中斷應該是關閉的
{
__asm__ __volatile__("POP __tmp_reg__ \n\t");
__asm__ __volatile__("POP __tmp_reg__ \n\t");
set_bit(SOSOS_STATE,STATE_SCHED_RUN);
ENABLE_INTERRUPT();
#if SOSOS_WDT_ENABLE == 1
//看門狗
SOSOS_WDT_RST();//復位看門狗
#else
__asm__ __volatile__("NOP \n\t");
#endif
DISABLE_INTERRUPT();
SOSOS_STATE=SOSOS_STATE&(~((1<<STATE_SCHED_RUN)|(1<<STATE_SCHED_REQ)));
unsigned char i,j,SOSOS_TMP;
//任務調度
for(i=0;i<SOSOS_PRI_MAX;i++){
if(SOSOS_TASK_READY[i]==0)
continue;
if(SOSOS_RUNNING_TASK_PRI==i){
SOSOS_TMP=SOSOS_TASK_READY[i]&(~SOSOS_RUNNING_TASK_ID_INDEX);
if(SOSOS_TMP==0)
goto SososSchedEnd;
if(SOSOS_TMP>SOSOS_RUNNING_TASK_ID_INDEX){
SOSOS_TMP=SOSOS_RUNNING_TASK_ID+1;
SOSOS_RUNNING_TASK_ID_INDEX=SOSOS_RUNNING_TASK_ID_INDEX<<1;
}
else{
SOSOS_TMP=0;
SOSOS_RUNNING_TASK_ID_INDEX=1;
}
}
else{
SOSOS_RUNNING_TASK_PRI=i;
SOSOS_TMP=0;
SOSOS_RUNNING_TASK_ID_INDEX=1;
}
for(j=SOSOS_TMP;j<SOSOS_MAX_TASK_PER_PRI;j++){
if((SOSOS_TASK_READY[i]&SOSOS_RUNNING_TASK_ID_INDEX)!=0){
SOSOS_RUNNING_TASK_ID=j;
goto SososSchedEnd;
}
else
SOSOS_RUNNING_TASK_ID_INDEX=SOSOS_RUNNING_TASK_ID_INDEX<<1;
}
}
SososSchedEnd:
#if SOSOS_MUTEX_ENABLE == 1
SOSOS_RUNNING_INHERIT_PRI=SOSOS_RUNNING_TASK_PRI;
if(SOSOS_MUTEX_POINT!=0){//互斥型信號量隊列有成員
SOSOS_MUTEX * mutex;
mutex=SOSOS_MUTEX_POINT;
while(mutex!=0){
if((mutex->INHERIT_PRI)>SOSOS_RUNNING_TASK_PRI){
break;
}
else{
if(test_1(SOSOS_TASK_READY[mutex->OWN_TASK_PRI],mutex->OWN_TASK_ID)){
SOSOS_RUNNING_INHERIT_PRI=mutex->INHERIT_PRI;
SOSOS_RUNNING_TASK_PRI=mutex->OWN_TASK_PRI;
SOSOS_RUNNING_TASK_ID=mutex->OWN_TASK_ID;
SOSOS_RUNNING_TASK_ID_INDEX=1<<SOSOS_RUNNING_TASK_ID;
}
}
mutex=(SOSOS_MUTEX *)(mutex->NEXT_MUTEX);
}
}//互斥型信號量隊列有成員
#endif
SP=TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STACK_POINT;//切換堆棧指針
//寄存器出棧
SOSOS_POP_REGISTER();
__asm__ __volatile__("RET \n\t");
}
#endif
#if SOSOS_TASK_ENALBE == 1
void SososScheder(void) __attribute__ ((naked));//任務調度器
void SososScheder(void)//任務調度器
//本函數只在系統內部使用,進入時中斷是關閉的
{
//寄存器入棧
SOSOS_PUSH_REGISTER();
TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STACK_POINT=SP;//保存正在運行任務的棧指針
SososSched();
}
#endif
#if SOSOS_TASK_ENALBE == 1
SOSOS_ISR(SIG_OVERFLOW0)//定時器0溢出中斷處理
//提供系統的時間基準,中間開了下中斷,以允許響應其他中斷
{
//進入中斷
SOSOS_ENTER_INTERRUPT();
TCNT0=SYS_TIMER_VALUE;
SOSOS_TICKS++;
ENABLE_INTERRUPT();
SososTimer0();
//離開中斷
SOSOS_EXIT_INTERRUPT();
}
#endif
#if SOSOS_TASK_ENALBE == 1
void SososIdleTask(void *ptr)//系統空閑任務
//本任務運行在定義的最低優先級的最后一個ID上
//系統提供的定時器部件,是在本任務中處理的,處理時中斷時關閉的
//不允許任何掛起本任務的操作
//提供一個名為SososIdleHook()的鉤子函數,允許用戶,在其中添加一些順序執行的語句序列,不能有死循環
{
DISABLE_INTERRUPT();
if(test_0(SOSOS_STATE,STATE_SCHED_RUN)&&(SOSOS_INT_NEST==0))
SososScheder();//任務調度器
ENABLE_INTERRUPT();
while(1){
//計時處理
unsigned char i;
#if SOSOS_WDT_ENABLE == 1
//看門狗
SOSOS_WDT_RST();//復位看門狗
#endif
//定時器部件
DISABLE_INTERRUPT();
if(SOSOS_TICKS>0){
#if SOSOS_TIMER_ENABLE == 1
for(i=0;i<SOSOS_TIMER_NO;i++){
if(SOSOS_TIMER[i]>SOSOS_TICKS){
SOSOS_TIMER[i]-=SOSOS_TICKS;
}
else{
SOSOS_TIMER[i]=0;
}
}
#endif
SOSOS_TICKS=0;
}
ENABLE_INTERRUPT();
SososIdleHook();
}
}
#endif
#if SOSOS_TASK_ENALBE == 1
unsigned char SososCreateTask(void (*task)(void *),unsigned char pri,unsigned char id,unsigned int stack_size,void *ptr)//創建任務
//本函數用于創建任務
//task:任務函數
//pri:優先級
//id:任務在本優先級的表示號
//stack_size:堆棧的字節大小
//ptr:傳遞給任務的一個數據指針
{
unsigned char *stack;
#if ERROR_DETECT_ENABLE == 1
if(pri>=SOSOS_PRI_MAX)
return SOSOS_PRI_LIMITED;
if(id>=SOSOS_MAX_TASK_PER_PRI)
return SOSOS_ID_LIMITED;
if((pri==SOSOS_PRI_MAX-1)&&(id==SOSOS_MAX_TASK_PER_PRI-1)&&(task!=SososIdleTask))
return SOSOS_TASK_EXIST;
if(TCB[pri*SOSOS_MAX_TASK_PER_PRI+id].TASK_STACK_POINT!=0)
return SOSOS_TASK_EXIST;
if(SOSOS_TASK_STACK_TOP<((SOSOS_ADDRESS)SOSOS_TASK_STACK+(SOSOS_ADDRESS)stack_size-1))
return SOSOS_TASK_STACK_LIMITED;
#endif
//設置堆棧指針
DISABLE_INTERRUPT();
stack=(unsigned char *)SOSOS_TASK_STACK_TOP;
#if STACK_SIZE_REPORT_ENABLE == 1
TCB[pri*SOSOS_MAX_TASK_PER_PRI+id].TASK_STACK_BUTTON=SOSOS_TASK_STACK_TOP;
TCB[pri*SOSOS_MAX_TASK_PER_PRI+id].TASK_STACK_SIZE=stack_size;
#endif
SOSOS_TASK_STACK_TOP-=stack_size;
//任務地址入棧
*stack--=(SOSOS_ADDRESS)task;
*stack--=(SOSOS_ADDRESS)task>>8;
//寄存器入棧
*stack--=0;//R1 zero register
*stack--=0;//R0 temp register
*stack--=0x10;//R16
*stack--=0x80;//SREG 開啟全局中斷
*stack--=0x12;//R18
*stack--=0x13;//R19
*stack--=0x14;//R20
*stack--=0x15;//R21
*stack--=0x16;//R22
*stack--=0x17;//R23
*stack--=(SOSOS_ADDRESS)ptr;//R24
*stack--=(SOSOS_ADDRESS)ptr>>8;//R25
*stack--=0x1a;//R26
*stack--=0x1b;//R27
*stack--=0x1e;//R30
*stack--=0x1f;//R31
*stack--=0x1c;//R28
*stack--=0x1d;//R29
//保存棧頂
TCB[pri*SOSOS_MAX_TASK_PER_PRI+id].TASK_STACK_POINT=(SOSOS_ADDRESS)stack;
set_bit(SOSOS_TASK_READY[pri],id);//設置任務就緒狀態
TCB[pri*SOSOS_MAX_TASK_PER_PRI+id].TASK_STATE=TASK_STATE_OK;
ENABLE_INTERRUPT();
return SOSOS_OK;
}
#endif
#if SOSOS_GET_TASK_ID_ENABLE == 1
unsigned char SososGetTaskId(void)//獲得當前任務ID
//返回值的高半字節是任務優先級,低半字節是任務在該優先級的ID
{
return((SOSOS_RUNNING_TASK_PRI<<4)+SOSOS_RUNNING_TASK_ID);
}
#endif
#if SOSOS_SUSPEND_TASK_ENABLE == 1
void SososSuspendTask(unsigned char pri,unsigned char id)//掛起任務
//掛起指定的任務,不要在中斷中調用該函數
//pri:優先級
//id:任務在本優先級的表示號
{
ENTER_CRITICAL();
clr_bit(SOSOS_TASK_READY[pri],id);//清除任務就緒狀態
if((pri==SOSOS_RUNNING_TASK_PRI)&&(id==SOSOS_RUNNING_TASK_ID)){
SososScheder();//掛起的是當前任務,重新調度
}
EXIT_CRITICAL();
}
#endif
#if SOSOS_RESUME_TASK_ENABLE == 1
void SososResumeTask(unsigned char pri,unsigned char id)//恢復任務
//恢復指定的任務,不要在中斷中調用該函數
//pri:優先級
//id:任務在本優先級的表示號
{
ENTER_CRITICAL();
set_bit(SOSOS_TASK_READY[pri],id);//設置任務就緒狀態
#if SOSOS_MUTEX_ENABLE == 1
if(SOSOS_RUNNING_INHERIT_PRI>pri){
#else
if(SOSOS_RUNNING_TASK_PRI>pri){
#endif
SososScheder();//恢復的任務優先級更高,重新調度
}
EXIT_CRITICAL();
}
#endif
#if SOSOS_DELAY_TASK_ENABLE == 1
void SososDelay(unsigned int ticks)//任務延時
//將任務延時指定的時間間隔,不要在中斷中調用該函數
//ticks:延時值,為0就立即返回
{
if(ticks>0){
ENTER_CRITICAL();
set_bit(SOSOS_WAIT_TASK,SOSOS_RUNNING_TASK_PRI);
SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]=SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]&(~SOSOS_RUNNING_TASK_ID_INDEX);//清除任務就緒狀態
TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STATE=TASK_STATE_DELAY;
TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_TIMEOUT=ticks;
SososScheder();//重新調度
EXIT_CRITICAL();
}
}
#endif
#if SOSOS_TIMER_ENABLE == 1
SOSOS_TIMEER_TYPE SososGetTimer(unsigned char no)//獲得指定定時器的定時值
//本函數返回指定編號的定時器部件的當前值
//no:定時器編號,從0開始
{
return SOSOS_TIMER[no];
}
#endif
#if SOSOS_TIMER_ENABLE == 1
void SososSetTimer(unsigned char no,SOSOS_TIMEER_TYPE value)//設定指定定時器的定時值
//本函數設置指定定時器部件的起始值
//no:定時器編號,從0開始
//value:定時值,定時器從該值減到0停止,間隔為:ticks
{
ENTER_CRITICAL();
SOSOS_TIMER[no]=value;
EXIT_CRITICAL();
}
#endif
#if SOSOS_SEM_ENABLE == 1
void SOSOS_SEARCH_ALL_WAIT_SIGNAL_TASK(SOSOS_ADDRESS POINT)//搜尋等待信號的任務
//本函數用在邏輯型信號量和數字型信號量的發送函數中,進入時中斷時開著的
{
unsigned char i,j,tmpj;
SOSOS_TCB *point;
point=TCB;
DISABLE_INTERRUPT();
for(i=0;i<SOSOS_PRI_MAX;i++){
tmpj=1;
for(j=0;j<SOSOS_MAX_TASK_PER_PRI;j++){
if(point->TASK_STATE==TASK_STATE_SEM){
if(point->EVENT_INDICATION==POINT){
SOSOS_TASK_READY[i]=SOSOS_TASK_READY[i]|tmpj;
point->TASK_STATE=TASK_STATE_OK;
#if SOSOS_MUTEX_ENABLE == 1
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -