⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sosos.c

📁 基于AVR平台的RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
/*=========================================================================================
项目名称: 小型开源实时操作系统
软件版本: 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 + -