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

📄 sosos.c

📁 基于AVR平台的RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
         if(SOSOS_RUNNING_INHERIT_PRI>i){
#else
         if(SOSOS_RUNNING_TASK_PRI>i){
#endif
           set_bit(SOSOS_STATE,STATE_SCHED_REQ);
           }
         return;
         }
       }
     point++;
     tmpj<<=1;
     }
   }

}
#endif

#if SOSOS_COUNT_SEM_ENABLE == 1
void SososCreateCountSem(SOSOS_SEM *sem,SOSOS_SEM value)//创建计数型信号量
//sem为要创建的数字型信号量的指针
//value为要创建时的初始值{
 (*sem)=value;
}
#endif

#if SOSOS_QUERY_SEM_ENABLE == 1 && SOSOS_COUNT_SEM_ENABLE == 1
SOSOS_SEM SososQueryCountSem(SOSOS_SEM *sem)//查询计数型信号量
{
 return (*sem);
}
#endif

#if SOSOS_COUNT_SEM_ENABLE == 1
unsigned char SososCountSemPend(SOSOS_SEM *sem,SOSOS_TIMEOUT_TYPE timeout)//等待计数型信号量
//本函数用于等待指定的计数型信号量为有效,有效则立即返回,不能用在中断中
//sem为计数型信号量的指针
//timeout为等待时间,单位:时间间隔,0:为无限期等待
{
 unsigned char temp;

 ENTER_CRITICAL();
 if((*sem)>0){
   (*sem)--;
   }
 else{
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STATE=TASK_STATE_SEM;
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].EVENT_INDICATION=(SOSOS_ADDRESS)sem;
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_TIMEOUT=timeout;
   SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]=SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]&(~SOSOS_RUNNING_TASK_ID_INDEX);//清除任务就绪状态
   if(timeout>0)
     set_bit(SOSOS_WAIT_TASK,SOSOS_RUNNING_TASK_PRI);
   SososScheder();//重新调度
   }
 if(TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STATE==TASK_STATE_SEM_TIMEOUT)
   temp=SOSOS_TASK_TIMEOUT;
 else{
   if((*sem)>0)
     (*sem)--;
   temp=SOSOS_OK;
   }
 EXIT_CRITICAL();
 return temp;
}
#endif

#if SOSOS_COUNT_SEM_ENABLE == 1
void SososCountSemPost(SOSOS_SEM *sem)//发送计数型信号量
//将指定的计数型信号量加一,若有等待该信号量的高优先级任务,则进行任务切换
{
 ENTER_CRITICAL();

 if((*sem)<SOSOS_SEM_MAX_VALUE)
   (*sem)++;

 if((*sem)==1){
   ENABLE_INTERRUPT();

   SOSOS_SEARCH_ALL_WAIT_SIGNAL_TASK((SOSOS_ADDRESS)sem);//搜寻等待信号的任务

   if(test_1(SOSOS_STATE,STATE_SCHED_REQ)&&test_0(SOSOS_STATE,STATE_SCHED_RUN)&&(SOSOS_INT_NEST==0))
     SososScheder();
   }
 EXIT_CRITICAL();
}
#endif

#if SOSOS_LOGIC_SEM_ENABLE == 1
void SososCreateLogicSem(SOSOS_SEM *sem,SOSOS_SEM value)//创建逻辑型信号量
//sem为指向信号量的指针
//value为创建时设置的初始值{
 (*sem)=value;
}
#endif

#if SOSOS_QUERY_SEM_ENABLE == 1 && SOSOS_LOGIC_SEM_ENABLE == 1
SOSOS_SEM SososQueryLogicSem(SOSOS_SEM *sem)//查询逻辑型信号量
//sem为指向信号量的指针
//信号量空闲返回:SOSOS_SIGNAL_FREE;信号量被占有返回:SOSOS_SIGNAL_ENGROSS{
 return (*sem);
}
#endif

#if SOSOS_LOGIC_SEM_ENABLE == 1
unsigned char SososLogicSemPend(SOSOS_SEM *sem,SOSOS_TIMEOUT_TYPE timeout)//等待逻辑型信号量
//本函数用于等待指定的逻辑型信号量为有效,有效则立即返回,不能用在中断中
//sem为逻辑型信号量的指针
//timeout为等待时间,单位:时间间隔,0:为无限期等待
{
 unsigned char temp;

 ENTER_CRITICAL();
 if((*sem)==SOSOS_SIGNAL_FREE){
   (*sem)=SOSOS_SIGNAL_ENGROSS;
   }
 else{
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STATE=TASK_STATE_SEM;
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].EVENT_INDICATION=(SOSOS_ADDRESS)sem;
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_TIMEOUT=timeout;
   SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]=SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]&(~SOSOS_RUNNING_TASK_ID_INDEX);//清除任务就绪状态
   if(timeout>0)
     set_bit(SOSOS_WAIT_TASK,SOSOS_RUNNING_TASK_PRI);
   SososScheder();//重新调度
   }
 if(TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STATE==TASK_STATE_SEM_TIMEOUT)
   temp=SOSOS_TASK_TIMEOUT;
 else{
   (*sem)=SOSOS_SIGNAL_ENGROSS;
   temp=SOSOS_OK;
   }
 EXIT_CRITICAL();
 return temp;
}
#endif

#if SOSOS_LOGIC_SEM_ENABLE == 1
void SososLogicSemPost(SOSOS_SEM *sem)//发送逻辑型信号量
//将指定的逻辑型信号量置为可用,若有等待该信号量的高优先级任务,则进行任务切换
{

 ENTER_CRITICAL();
 if((*sem)==SOSOS_SIGNAL_ENGROSS){
   (*sem)=SOSOS_SIGNAL_FREE;

   ENABLE_INTERRUPT();

   SOSOS_SEARCH_ALL_WAIT_SIGNAL_TASK((SOSOS_ADDRESS)sem);//搜寻等待信号的任务

   if(test_1(SOSOS_STATE,STATE_SCHED_REQ)&&test_0(SOSOS_STATE,STATE_SCHED_RUN)&&(SOSOS_INT_NEST==0))
     SososScheder();
   }
 EXIT_CRITICAL();
}
#endif

#if SOSOS_MUTEX_ENABLE == 1
void SososCreateMutex(SOSOS_MUTEX *mutex,unsigned char value)//创建互斥型信号量//mutex为指向信号量的指针,将新加入信号量放在列表的最后
//value为创建信号量时的初始值,可为SOSOS_SIGNAL_FREE或SOSOS_SIGNAL_ENGROSS
{
 SOSOS_MUTEX *point;

 if(SOSOS_MUTEX_POINT==0)//列表为空时,作为第一个成员
   SOSOS_MUTEX_POINT=mutex;
 else{//已有成员时,添加在列表末尾
   point=SOSOS_MUTEX_POINT;
   while(1){
     if((point->NEXT_MUTEX)==0){
       point->NEXT_MUTEX=(SOSOS_ADDRESS)mutex;
       break;
       }
     point=(SOSOS_MUTEX *)point->NEXT_MUTEX;
     }
   }//已有成员时,添加在列表末尾

 mutex->NEXT_MUTEX=0;//表示为最后一个列表成员
 mutex->MUTEX_VALUE=value;
 mutex->INHERIT_PRI=SOSOS_PRI_MAX-1;
}
#endif

#if SOSOS_QUERY_MUTEX_ENABLE == 1
unsigned char SososQueryMutex(SOSOS_MUTEX *mutex)//查询互斥型信号量状态
//查询指定的互斥型信号量的状态,可用在中断函数中
{
 return (mutex->MUTEX_VALUE);
}
#endif

#if SOSOS_MUTEX_ENABLE == 1
void SososInsertMutex(SOSOS_MUTEX *mutex)//调整互斥信号量在表内的位置
//系统内部使用,用于调整互斥型信号量在链表中的位置,信号量在链表中是按
//继承后的优先级从高到低排列(优先级数值从小到大),没有被占用的信号量
//的优先级被指定为最低可用优先级
{
 SOSOS_MUTEX *mutex_point,*pre_point;

//从列表中去除指定的信号量
 if(SOSOS_MUTEX_POINT==mutex){//是第一个成员
   SOSOS_MUTEX_POINT=0;
   }//是第一个成员
 else{//不是第一个成员
   mutex_point=SOSOS_MUTEX_POINT;
   while(mutex_point!=0){
     if((mutex_point->NEXT_MUTEX)==(SOSOS_ADDRESS)mutex){
       mutex_point->NEXT_MUTEX=mutex->NEXT_MUTEX;
       break;
       }
     mutex_point=(SOSOS_MUTEX *)mutex_point->NEXT_MUTEX;
     }
   }//不是第一个成员

//按优先级插人该成员
 if(SOSOS_MUTEX_POINT==0){//队列为空
   SOSOS_MUTEX_POINT=mutex;
   mutex->NEXT_MUTEX=0;
   }//队列为空
 else{//队列不空
   if((SOSOS_MUTEX_POINT->INHERIT_PRI)>=(mutex->INHERIT_PRI)){//被插入成员是队列中的最高优先级成员
     mutex->NEXT_MUTEX=SOSOS_MUTEX_POINT->NEXT_MUTEX;
     SOSOS_MUTEX_POINT=mutex;
     }//被插入成员是队列中的最高优先级成员
   else{//其他情况
     pre_point=SOSOS_MUTEX_POINT;
     while(1){
       mutex_point=(SOSOS_MUTEX *)(pre_point->NEXT_MUTEX);
       if((mutex_point->INHERIT_PRI)>=(mutex->INHERIT_PRI)){
         pre_point->NEXT_MUTEX=(SOSOS_ADDRESS)mutex;
         mutex->NEXT_MUTEX=(SOSOS_ADDRESS)mutex_point;
         break;
         }
       pre_point=mutex_point;
       }
     }//其他情况
   }//队列不空
 }

unsigned char SososGetMutex(SOSOS_MUTEX *mutex,SOSOS_TIMEOUT_TYPE timeout)//获得互斥型信号量
//在规定的时间内等待信号量,若得到信号量返回SOSOS_OK,若超时返回SOSOS_TASK_TIMEOUT
//mutex为请求的互斥型信号量
//timeout为超时时间,单位是ticks;0为无限期等待
{
 unsigned char temp;

 ENTER_CRITICAL();
 if((mutex->MUTEX_VALUE)==SOSOS_SIGNAL_FREE){//信号量空闲
   mutex->INHERIT_PRI=SOSOS_RUNNING_INHERIT_PRI;
   mutex->OWN_TASK_PRI=SOSOS_RUNNING_TASK_PRI;
   mutex->OWN_TASK_ID=SOSOS_RUNNING_TASK_ID;
   mutex->MUTEX_VALUE=SOSOS_SIGNAL_ENGROSS;
   SososInsertMutex(mutex);//调整互斥型信号量列表
   }//信号量空闲
 else{//信号量被占用
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STATE=TASK_STATE_MUTEX;
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].EVENT_INDICATION=(SOSOS_ADDRESS)mutex;
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_TIMEOUT=timeout;
   SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]=SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]&(~SOSOS_RUNNING_TASK_ID_INDEX);//清除任务就绪状态
   if(SOSOS_RUNNING_INHERIT_PRI<(mutex->INHERIT_PRI)){
     mutex->INHERIT_PRI=SOSOS_RUNNING_INHERIT_PRI;
     SososInsertMutex(mutex);
     }
   if(timeout>0)
     set_bit(SOSOS_WAIT_TASK,SOSOS_RUNNING_TASK_PRI);
   SososScheder();//重新调度
   }//信号量被占用

 if(TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STATE==TASK_STATE_MUTEX_TIMEOUT)
   temp=SOSOS_TASK_TIMEOUT;
 else{
   mutex->INHERIT_PRI=SOSOS_RUNNING_INHERIT_PRI;
   mutex->OWN_TASK_PRI=SOSOS_RUNNING_TASK_PRI;
   mutex->OWN_TASK_ID=SOSOS_RUNNING_TASK_ID;
   mutex->MUTEX_VALUE=SOSOS_SIGNAL_ENGROSS;
   SososInsertMutex(mutex);
   temp=SOSOS_OK;
   }
 EXIT_CRITICAL();
 return temp;
}
#endif

#if SOSOS_MUTEX_ENABLE == 1
void SOSOS_MUTEX_SEARCH_ALL_PRI_TASK(SOSOS_MUTEX * POINT)//搜寻等待互斥型信号量的任务
//系统内部使用,用于在任务控制块中搜索等待指定互斥型信号量的任务
{
 unsigned char i,j;
 SOSOS_TCB *point;

 point=TCB;
 for(i=0;i<SOSOS_PRI_MAX;i++){
   for(j=0;j<SOSOS_MAX_TASK_PER_PRI;j++){
     if(point->TASK_STATE==TASK_STATE_MUTEX){
       if(point->EVENT_INDICATION==(SOSOS_ADDRESS)POINT){
         set_bit(SOSOS_TASK_READY[i],j);
         point->TASK_STATE=TASK_STATE_OK;
         if(SOSOS_RUNNING_INHERIT_PRI>i){
           set_bit(SOSOS_STATE,STATE_SCHED_REQ);
           }
//获得该互斥型信号量
         POINT->INHERIT_PRI=i;
         POINT->OWN_TASK_PRI=i;
         POINT->OWN_TASK_ID=j;
         POINT->MUTEX_VALUE=SOSOS_SIGNAL_ENGROSS;
         SososInsertMutex(POINT);//调整互斥型信号量列表
         return;
         }
       }
     point++;
     }
   }
//恢复互斥型信号量为空闲状态
 POINT->INHERIT_PRI=SOSOS_PRI_MAX-1;
 POINT->MUTEX_VALUE=SOSOS_SIGNAL_FREE;
 SososInsertMutex(POINT);//调整互斥型信号量列表
}
#endif

#if SOSOS_MUTEX_ENABLE == 1
void SososFreeMutex(SOSOS_MUTEX *mutex)//释放互斥型信号量
//释放指定的互斥型信号量
{
 ENTER_CRITICAL();

 SOSOS_MUTEX_SEARCH_ALL_PRI_TASK(mutex);//搜寻等待互斥型信号量的任务

 if(test_1(SOSOS_STATE,STATE_SCHED_REQ)&&test_0(SOSOS_STATE,STATE_SCHED_RUN)&&(SOSOS_INT_NEST==0))
   SososScheder();
 EXIT_CRITICAL();
}
#endif

#if SOSOS_FLAG_ENABLE ==1
void SososCreateFlag(SOSOS_EVENT_FLAG *FLAG,SOSOS_FLAG_TYPE *point,SOSOS_FLAG_TYPE wait,SOSOS_FLAG_TYPE msk)//创建事件标志
{
//FLAG:事件标记
//point:事件标记组的指针
//wait:事件标记等待的状态
//msk:事件标记屏蔽码
 FLAG->FLAG_POINT=point;
 FLAG->FLAG_WAIT=wait&msk;
 FLAG->FLAG_MSK=msk;
}
#endif

#if SOSOS_QUERY_FLAG_ENABLE == 1
SOSOS_FLAG_TYPE SososQueryFlag(SOSOS_EVENT_FLAG *FLAG)//查询事件标志状态
{
//FLAG:事件标记
 return ((*(FLAG->FLAG_POINT))&(FLAG->FLAG_MSK));
}
#endif

#if SOSOS_FLAG_ENABLE ==1
unsigned char SososWaitFlag(SOSOS_EVENT_FLAG *FLAG,SOSOS_FLAG_TYPE wait,SOSOS_FLAG_TYPE msk,SOSOS_TIMEOUT_TYPE timeout)//等待指定的事件
{
//FLAG:事件标记
//wait:事件标记等待的状态
//msk:事件标记屏蔽码
//timeout:等待溢出延时
 unsigned char temp;
 
 ENTER_CRITICAL();
 FLAG->FLAG_WAIT=wait&msk;
 FLAG->FLAG_MSK=msk;
 if(((*(FLAG->FLAG_POINT))&msk)!=(wait&msk)){
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STATE=TASK_STATE_FLAG;
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].EVENT_INDICATION=(SOSOS_ADDRESS)FLAG;
   TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_TIMEOUT=timeout;
   SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]=SOSOS_TASK_READY[SOSOS_RUNNING_TASK_PRI]&(~SOSOS_RUNNING_TASK_ID_INDEX);//清除任务就绪状态
   if(timeout>0)
     set_bit(SOSOS_WAIT_TASK,SOSOS_RUNNING_TASK_PRI);
   SososScheder();//重新调度
   }
 if(TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STATE==TASK_STATE_FLAG_TIMEOUT)
   temp=SOSOS_TASK_TIMEOUT;
 else
   temp=SOSOS_OK;
 EXIT_CRITICAL();
 return temp;
}
#endif

#if SOSOS_FLAG_ENABLE ==1
void SOSOS_FLAG_SEARCH_ALL_PRI_TASK(SOSOS_EVENT_FLAG *POINT)//搜寻等待事件标志的任务
{
 unsigned char i,j,tmp;
 SOSOS_TCB *point;

 point=TCB;
 DISABLE_INTERRUPT();
 tmp=*(POINT->FLAG_POINT);

 for(i=0;i<SOSOS_PRI_MAX;i++){
   for(j=0;j<SOSOS_MAX_TASK_PER_PRI;j++){
     if(point->TASK_STATE==TASK_STATE_FLAG){
       if((point->EVENT_INDICATION)==(SOSOS_ADDRESS)POINT){
         if((POINT->FLAG_WAIT)==((POINT->FLAG_MSK)&tmp)){
           set_bit(SOSOS_TASK_READY[i],j);
           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);
             }
           return;
           }
         }
       }
     point++;
     }
   }
}
#endif

#if SOSOS_FLAG_ENABLE ==1
void SososChangeFlag(SOSOS_EVENT_FLAG *FLAG,SOSOS_FLAG_TYPE flag,unsigned char opt)//改变事件标志
{
//FLAG:事件标记
//flag:要改变的标记位
//opt:进行的操作(设置 或 清除)
 ENTER_CRITICAL();
 if(opt==SOSOS_FLAG_OPT_CLR)
   *(FLAG->FLAG_POINT)&=(~flag);
 else
   *(FLAG->FLAG_POINT)|=flag;
 ENABLE_INTERRUPT();

 SOSOS_FLAG_SEARCH_ALL_PRI_TASK(FLAG);//搜寻等待事件标志的任务

 if(test_1(SOSOS_STATE,STATE_SCHED_REQ)&&test_0(SOSOS_STATE,STATE_SCHED_RUN)&&(SOSOS_INT_NEST==0))
   SososScheder();
 EXIT_CRITICAL();
}
#endif

#if SOSOS_TASK_ENALBE == 1
void SososStartOs(void)//启动SOSOS系统
{
#if SOSOS_MUTEX_ENABLE == 1
 SOSOS_RUNNING_INHERIT_PRI=SOSOS_PRI_MAX-1;
#endif
 SOSOS_RUNNING_TASK_PRI=SOSOS_PRI_MAX-1;
 SOSOS_RUNNING_TASK_ID=SOSOS_MAX_TASK_PER_PRI-1;
 SOSOS_RUNNING_TASK_ID_INDEX=1<<SOSOS_RUNNING_TASK_ID;
 SososCreateTask(SososIdleTask,SOSOS_RUNNING_TASK_PRI,SOSOS_RUNNING_TASK_ID,IDLE_TASK_STACK_SIZE,(void *)0);//创建idle任务
#if SOSOS_WDT_ENABLE == 1
//看门狗
 wdt_enable(SOSOS_WDT_PERIOD);
 SOSOS_WDT_RST();//复位看门狗
#endif
 SYS_TIMER_INIT();
 SP=TCB[SOSOS_RUNNING_TASK_PRI*SOSOS_MAX_TASK_PER_PRI+SOSOS_RUNNING_TASK_ID].TASK_STACK_POINT+SOSOS_PUSH_REGISTER_NO; 
 __asm__ __volatile__( "reti" "\n\t" );
}
#endif


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -