📄 sosos.c
字号:
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 + -