//浮点测试任务 void float_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); static float float_num = 0.01; //uint32_t temp = &float_num; while(1) { float_num+=0.01f; OS_CRITICAL_ENTER(); //进入临界区 //printf("float_num的值为: %.4f\r\n",float_num); OS_CRITICAL_EXIT(); //退出临界区 if(float_num > 0.901f && float_num < 0.919f) { OSTaskSuspend((OS_TCB*)&Led0TaskTCB,&err); printf("挂起LED任务\n\r"); } if(float_num > 1.991f && float_num < 2.001f) { OSTaskResume((OS_TCB*)&Led0TaskTCB,&err); printf("恢复LED任务\n\r"); float_num = 0.0f; } OSTimeDlyHMSM(0,0,0,300,OS_OPT_TIME_HMSM_STRICT,&err); //延时300ms } }
//主函数 int main(void) { OS_ERR err; CPU_SR_ALLOC(); delay_init(168); //时钟初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组配置 uart_init(115200); //串口初始化 LED_Init(); //LED初始化 LCD_Init(); //LCD初始化 KEY_Init(); //按键初始化 BEEP_Init(); //初始化蜂鸣器 FSMC_SRAM_Init(); //初始化SRAM my_mem_init(SRAMIN);//初始化内部RAM ucos_load_main_ui();//加载主UI OSInit(&err); //初始化UCOSIII OS_CRITICAL_ENTER(); //进入临界区 //创建开始任务 OSTaskCreate((OS_TCB * )&StartTaskTCB, //任务控制块 (CPU_CHAR * )"start task", //任务名字 (OS_TASK_PTR )start_task, //任务函数 (void * )0, //传递给任务函数的参数 (OS_PRIO )START_TASK_PRIO, //任务优先级 (CPU_STK * )&START_TASK_STK[0], //任务堆栈基地址 (CPU_STK_SIZE)START_STK_SIZE/10, //任务堆栈深度限位 (CPU_STK_SIZE)START_STK_SIZE, //任务堆栈大小 (OS_MSG_QTY )0, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息 (OS_TICK )0, //当使能时间片轮转时的时间片长度,为0时为默认长度, (void * )0, //用户补充的存储区 (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项 (OS_ERR * )&err); //存放该函数错误时的返回值 OS_CRITICAL_EXIT(); //退出临界区 OSStart(&err); //开启UCOSIII }
/********************************************************************* * * PngGetData * * Function description * This routine is called by GUI_PNG_DrawEx(). The routine is responsible * for setting the data pointer to a valid data location with at least * one valid byte. * * Parameters: * p - Pointer to application defined data. * NumBytesReq - Number of bytes requested. * ppData - Pointer to data pointer. This pointer should be set to * a valid location. * StartOfFile - If this flag is 1, the data pointer should be set to the * beginning of the data stream. * * Return value: * Number of data bytes available. */ static int PngGetData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off) { static int readaddress=0; FIL * phFile; U8 *pData; UINT NumBytesRead; #if SYSTEM_SUPPORT_OS CPU_SR_ALLOC(); #endif pData = (U8*)*ppData; phFile = (FIL *)p; //移动指针到应该读取的位置 if(Off == 1) readaddress = 0; else readaddress=Off; #if SYSTEM_SUPPORT_OS OS_CRITICAL_ENTER(); //临界区 #endif f_lseek(phFile,readaddress); //读取数据到缓冲区中 f_read(phFile,pData,NumBytesReq,&NumBytesRead); #if SYSTEM_SUPPORT_OS OS_CRITICAL_EXIT();//退出临界区 #endif return NumBytesRead;//返回读取到的字节数 }
void OS_TickTask (void *p_arg) { OS_ERR err; CPU_TS ts_delta; CPU_TS ts_delta_dly; CPU_TS ts_delta_timeout; CPU_SR_ALLOC(); (void)&p_arg; /* Prevent compiler warning */ while (DEF_ON) { (void)OSTaskSemPend((OS_TICK )0, (OS_OPT )OS_OPT_PEND_BLOCKING, (CPU_TS *)0, (OS_ERR *)&err); /* Wait for signal from tick interrupt */ if (err == OS_ERR_NONE) { OS_CRITICAL_ENTER(); OSTickCtr++; /* Keep track of the number of ticks */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_TICK_INCREMENT(OSTickCtr); /* Record the event. */ #endif OS_CRITICAL_EXIT(); ts_delta_dly = OS_TickListUpdateDly(); ts_delta_timeout = OS_TickListUpdateTimeout(); ts_delta = ts_delta_dly + ts_delta_timeout; /* Compute total execution time of list updates */ if (OSTickTaskTimeMax < ts_delta) { OSTickTaskTimeMax = ts_delta; } } } }
//led0任务函数 void led0_task(void *p_arg) { OS_ERR err; u8 test[20]; u8 times = 0; CPU_SR_ALLOC(); u8 temp; p_arg = p_arg; while(1) { OS_CRITICAL_ENTER(); temp = FloatTaskTCB.MsgQ.NbrEntriesSize - FloatTaskTCB.MsgQ.NbrEntries; printf("que remain %d.\r\n",temp); OS_CRITICAL_EXIT(); sprintf((char *)test,"led_send_que %d",times++); printf("led0 task send que.\r\n"); OSTaskQPost((OS_TCB* )&FloatTaskTCB, //向任务Msgdis发送消息 (void* )test, (OS_MSG_SIZE)20, (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR* )&err); OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s } }
void OS_QPost (OS_Q *p_q, void *p_void, OS_MSG_SIZE msg_size, OS_OPT opt, CPU_TS ts, OS_ERR *p_err) { OS_OBJ_QTY cnt; OS_OPT post_type; OS_PEND_LIST *p_pend_list; OS_PEND_DATA *p_pend_data; OS_PEND_DATA *p_pend_data_next; OS_TCB *p_tcb; CPU_SR_ALLOC(); OS_CRITICAL_ENTER(); p_pend_list = &p_q->PendList; if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0) { /* Any task waiting on message queue? */ if ((opt & OS_OPT_POST_LIFO) == (OS_OPT)0) { /* Determine whether we post FIFO or LIFO */ post_type = OS_OPT_POST_FIFO; } else { post_type = OS_OPT_POST_LIFO; } OS_MsgQPut(&p_q->MsgQ, /* Place message in the message queue */ p_void, msg_size, post_type, ts, p_err); OS_CRITICAL_EXIT(); return; } if ((opt & OS_OPT_POST_ALL) != (OS_OPT)0) { /* Post message to all tasks waiting? */ cnt = p_pend_list->NbrEntries; /* Yes */ } else { cnt = (OS_OBJ_QTY)1; /* No */ } p_pend_data = p_pend_list->HeadPtr; while (cnt > 0u) { p_tcb = p_pend_data->TCBPtr; p_pend_data_next = p_pend_data->NextPtr; OS_Post((OS_PEND_OBJ *)((void *)p_q), p_tcb, p_void, msg_size, ts); p_pend_data = p_pend_data_next; cnt--; } OS_CRITICAL_EXIT_NO_SCHED(); if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) { OSSched(); /* Run the scheduler */ } *p_err = OS_ERR_NONE; }
void OSQCreate (OS_Q *p_q, CPU_CHAR *p_name, OS_MSG_QTY max_qty, OS_ERR *p_err) { CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #ifdef OS_SAFETY_CRITICAL_IEC61508 if (OSSafetyCriticalStartFlag == DEF_TRUE) { *p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME; return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to be called from an ISR */ *p_err = OS_ERR_CREATE_ISR; return; } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_q == (OS_Q *)0) { /* Validate arguments */ *p_err = OS_ERR_OBJ_PTR_NULL; return; } if (max_qty == (OS_MSG_QTY)0) { /* Cannot specify a zero size queue */ *p_err = OS_ERR_Q_SIZE; return; } #endif OS_CRITICAL_ENTER(); p_q->Type = OS_OBJ_TYPE_Q; /* Mark the data structure as a message queue */ p_q->NamePtr = p_name; OS_MsgQInit(&p_q->MsgQ, /* Initialize the queue */ max_qty); OS_PendListInit(&p_q->PendList); /* Initialize the waiting list */ #if OS_CFG_DBG_EN > 0u OS_QDbgListAdd(p_q); #endif OSQQty++; /* One more queue created */ OS_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; }
static CPU_TS OS_TickListUpdateDly (void) { OS_TCB *p_tcb; OS_TICK_LIST *p_list; CPU_TS ts_start; CPU_TS ts_delta_dly; #if OS_CFG_DBG_EN > 0u OS_OBJ_QTY nbr_updated; #endif CPU_SR_ALLOC(); OS_CRITICAL_ENTER(); ts_start = OS_TS_GET(); #if OS_CFG_DBG_EN > 0u nbr_updated = (OS_OBJ_QTY)0u; #endif p_list = &OSTickListDly; p_tcb = p_list->TCB_Ptr; if (p_tcb != (OS_TCB *)0) { p_tcb->TickRemain--; while (p_tcb->TickRemain == 0u) { #if OS_CFG_DBG_EN > 0u nbr_updated++; /* Keep track of the number of TCBs updated */ #endif if (p_tcb->TaskState == OS_TASK_STATE_DLY) { p_tcb->TaskState = OS_TASK_STATE_RDY; OS_RdyListInsert(p_tcb); /* Insert the task in the ready list */ } else if (p_tcb->TaskState == OS_TASK_STATE_DLY_SUSPENDED) { p_tcb->TaskState = OS_TASK_STATE_SUSPENDED; } p_list->TCB_Ptr = p_tcb->TickNextPtr; p_tcb = p_list->TCB_Ptr; /* Get 'p_tcb' again for loop */ if (p_tcb == (OS_TCB *)0) { #if OS_CFG_DBG_EN > 0u p_list->NbrEntries = (OS_OBJ_QTY)0u; #endif break; } else { #if OS_CFG_DBG_EN > 0u p_list->NbrEntries--; #endif p_tcb->TickPrevPtr = (OS_TCB *)0; } } } #if OS_CFG_DBG_EN > 0u p_list->NbrUpdated = nbr_updated; #endif ts_delta_dly = OS_TS_GET() - ts_start; /* Measure execution time of the update */ OS_CRITICAL_EXIT(); return (ts_delta_dly); }
void bus_send_string(char *buf) { u16 i; CPU_SR_ALLOC(); OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT(); for (i = 0; buf[i] != '\0'; i++) bus_send(&buf[i], 1); OS_CRITICAL_EXIT(); }
//查询DATA_Msg消息队列中的总队列数量和剩余队列数量 void check_msg_queue(u8 *p) { CPU_SR_ALLOC(); u8 msgq_remain_size; //消息队列剩余大小 OS_CRITICAL_ENTER(); //进入临界段 msgq_remain_size =Msgdis_TaskTCB.MsgQ.NbrEntriesSize-Msgdis_TaskTCB.MsgQ.NbrEntries; p = mymalloc(SRAMIN,20); //申请内存 sprintf((char*)p,"Total Size:%d",Msgdis_TaskTCB.MsgQ.NbrEntriesSize); //显示DATA_Msg消息队列总的大小 LCD_ShowString(40,190,100,16,16,p); sprintf((char*)p,"Remain Size:%d",msgq_remain_size); //显示DATA_Msg剩余大小 LCD_ShowString(40,230,100,16,16,p); myfree(SRAMIN,p); //释放内存 OS_CRITICAL_EXIT(); //退出临界段 }
/*-------------------- B f r A d d B y t e ( ) ------------------------------------- Purpose: Add a byte to a buffer at position “in” and increment “in” by 1. Parameters: buffer address, byte to be added Return Value: Success - Byte that has been added, unless buffer is full Failure - Buffer is full, return -1 */ CPU_INT16S BfrAddByte(CircBfr *bfr, CPU_INT16S theByte){ CPU_SR_ALLOC(); //CPU_INT32U sr = 0; Necessary to disable/enable interrupts in uC/OSIII if (BfrFull(bfr)) return -1; *(bfr->bfr+bfr->in) = theByte; bfr->in = (bfr->in + 1) % bfr->size; //Disable interrupts to avoid data hazards OS_CRITICAL_ENTER(); bfr->numBytes++; OS_CRITICAL_EXIT(); return theByte; }
FS_PRIVATE void fs_inode_WaitOn(FS_INODE_EXT* pstInode_in) { CPU_SR_ALLOC(); if (0 == pstInode_in) { CPUExt_CorePanic("[fs_inode_WaitOn][invalid parameter]"); } OS_CRITICAL_ENTER(); while (pstInode_in->i_lock) { drv_lock_SleepOn(&(pstInode_in->i_wait)); } OS_CRITICAL_EXIT(); }
/*-------------------- B f r R e m B y t e ( ) ------------------------------------- Purpose: Return the byte from position “out” and increment “out” by 1 Parameters: buffer address Return Value: Success - Returns the byte from position 'out' unless empty Failure - If empty return -1 */ CPU_INT16S BfrRemByte(CircBfr *bfr){ CPU_SR_ALLOC(); //CPU_INT32U sr = 0; Necessary to disable/enable interrupts in uC/OSIII if (BfrEmpty(bfr)) return -1; CPU_INT16S tempByte = *(bfr->bfr+(bfr->out)); bfr->out = (bfr->out + 1) % bfr->size; //Disable interrupts to avoid data hazards OS_CRITICAL_ENTER(); bfr->numBytes--; OS_CRITICAL_EXIT(); return tempByte; }
//led0任务函数 void led0_task(void *p_arg) { OS_ERR err; u8 test[20]; u8 test1[20] = "abcde"; u8 test2[20] = "12345"; u8 test3[20] = "45678"; u8 times = 0; CPU_SR_ALLOC(); u8 temp; p_arg = p_arg; while(1) { OS_CRITICAL_ENTER(); temp = FloatTaskTCB.MsgQ.NbrEntriesSize - FloatTaskTCB.MsgQ.NbrEntries; printf("que remain %d.\r\n",temp); OS_CRITICAL_EXIT(); sprintf((char *)test,"led_send_que %d",times++); printf("led0 task send que.\r\n"); //消息队列传送的是地址 且不会进行数据拷贝 //同一地址传输速度比处理任务快 会导致数据被覆盖 造成数据丢失 //消息队列传送的是需要读取某个地址的次数 OSTaskQPost((OS_TCB* )&FloatTaskTCB, //向任务Msgdis发送消息 (void* )test, (OS_MSG_SIZE)20, (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR* )&err); OSTaskQPost((OS_TCB* )&FloatTaskTCB, //向任务Msgdis发送消息 (void* )&test1, (OS_MSG_SIZE)20, (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR* )&err); OSTaskQPost((OS_TCB* )&FloatTaskTCB, //向任务Msgdis发送消息 (void* )&test2, (OS_MSG_SIZE)20, (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR* )&err); OSTaskQPost((OS_TCB* )&FloatTaskTCB, //向任务Msgdis发送消息 (void* )&test3, (OS_MSG_SIZE)20, (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR* )&err); OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s } }
//主函数 int main(void) { OS_ERR err; CPU_SR_ALLOC(); delay_init(168); //时钟初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组配置 uart_init(115200); //串口初始化 LED_Init(); //LED初始化 LCD_Init(); //LCD初始化 KEY_Init(); //按键初始化 FSMC_SRAM_Init(); //初始化SRAM my_mem_init(SRAMIN);//初始化内部RAM POINT_COLOR = RED; LCD_ShowString(30,10,200,16,16,"Explorer STM32F4"); LCD_ShowString(30,30,200,16,16,"UCOSIII Examp 13-1"); LCD_ShowString(30,50,200,16,16,"Pend Multi"); LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK"); LCD_ShowString(30,90,200,16,16,"2015/5/20"); POINT_COLOR = BLACK; LCD_DrawRectangle(5,110,234,314); LCD_DrawLine(5,130,234,130); POINT_COLOR = RED; LCD_ShowString(50,111,200,16,16,"ObjRdy_NUM: 0"); POINT_COLOR = BLUE; OSInit(&err); //初始化UCOSIII OS_CRITICAL_ENTER(); //进入临界区 //创建开始任务 OSTaskCreate((OS_TCB * )&StartTaskTCB, //任务控制块 (CPU_CHAR * )"start task", //任务名字 (OS_TASK_PTR )start_task, //任务函数 (void * )0, //传递给任务函数的参数 (OS_PRIO )START_TASK_PRIO, //任务优先级 (CPU_STK * )&START_TASK_STK[0], //任务堆栈基地址 (CPU_STK_SIZE)START_STK_SIZE/10, //任务堆栈深度限位 (CPU_STK_SIZE)START_STK_SIZE, //任务堆栈大小 (OS_MSG_QTY )0, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息 (OS_TICK )0, //当使能时间片轮转时的时间片长度,为0时为默认长度, (void * )0, //用户补充的存储区 (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项 (OS_ERR * )&err); //存放该函数错误时的返回值 OS_CRITICAL_EXIT(); //退出临界区 OSStart(&err); //开启UCOSIII }
//在指定位置显示加载到RAM中的PNG图片(PNG图片不能缩放!) //PNGFileName:图片在SD卡或者其他存储设备中的路径(需文件系统支持!) //mode:显示模式 // 0 在指定位置显示,有参数x,y确定显示位置 // 1 在LCD中间显示图片,当选择此模式的时候参数x,y无效。 //x:图片左上角在LCD中的x轴位置(当参数mode为1时,此参数无效) //y:图片左上角在LCD中的y轴位置(当参数mode为1时,此参数无效) //返回值:0 显示正常,其他 失败 int displaypng(char *PNGFileName,U8 mode,U32 x,U32 y) { U16 bread; char *pngbuffer; char result; int XSize,YSize; #if SYSTEM_SUPPORT_OS CPU_SR_ALLOC(); #endif result = f_open(&PNGFile,(const TCHAR*)PNGFileName,FA_READ); //打开文件 //文件打开错误或者文件大于JPEGMEMORYSIZE if((result != FR_OK) || (PNGFile.fsize>PNGMEMORYSIZE)) return 1; pngbuffer=mymalloc(SRAMEX,PNGFile.fsize); if(pngbuffer == NULL) return 2; #if SYSTEM_SUPPORT_OS OS_CRITICAL_ENTER(); //临界区 #endif result = f_read(&PNGFile,pngbuffer,PNGFile.fsize,(UINT *)&bread); //读取数据 f_close(&PNGFile); //关闭PNGFile文件 if(result != FR_OK) return 3; #if SYSTEM_SUPPORT_OS OS_CRITICAL_EXIT(); //退出临界区 #endif XSize = GUI_PNG_GetXSize(pngbuffer,PNGFile.fsize); //获取PNG图片的X轴大小 YSize = GUI_PNG_GetYSize(pngbuffer,PNGFile.fsize); //获取PNG图片的Y轴大小 switch(mode) { case 0: //在指定位置显示图片 GUI_PNG_Draw(pngbuffer,PNGFile.fsize,x,y);//显示PNG图片 break; case 1: //在LCD中间显示图片 GUI_PNG_Draw(pngbuffer,PNGFile.fsize,(LCD_GetXSize()-XSize)/2-1,(LCD_GetYSize()-YSize)/2-1); break; } myfree(SRAMEX,pngbuffer); return 0; }
//浮点测试任务 void float_task(void *p_arg) { OS_ERR err; uint32_t temp = 0; uint8_t i = 0; CPU_SR_ALLOC(); while(1) { OS_CRITICAL_ENTER(); //进入临界区 printf("float run %d times\r\n",temp++); OS_CRITICAL_EXIT(); //进入临界区 for( i = 0;i < 5; i++ ) printf("float : 67890 \r\n"); OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); } }
OS_MSG_QTY OSQFlush (OS_Q *p_q, OS_ERR *p_err) { OS_MSG_QTY entries; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_MSG_QTY)0); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Can't flush a message queue from an ISR */ *p_err = OS_ERR_FLUSH_ISR; return ((OS_MSG_QTY)0); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_q == (OS_Q *)0) { /* Validate arguments */ *p_err = OS_ERR_OBJ_PTR_NULL; return ((OS_MSG_QTY)0); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure message queue was created */ *p_err = OS_ERR_OBJ_TYPE; return ((OS_MSG_QTY)0); } #endif OS_CRITICAL_ENTER(); entries = OS_MsgQFreeAll(&p_q->MsgQ); /* Return all OS_MSGs to the OS_MSG pool */ OS_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; return ((OS_MSG_QTY)entries); }
/*-------------------- S e r _ I S R ( ) ------------------------------------- Purpose: Call ServiceRx() to handle Rx interrupts and then call ServiceTx() to handle Tx interrupts. [Added the prologue and epilogue to make this ISR compatible with uC/OS-III.] */ CPU_VOID Ser_ISR(CPU_VOID){ //OS_ERR osErr; /* O/S Error code */ /*---------------------- Prologue ----------------*/ /*Disable Interrupts*/ CPU_SR_ALLOC(); OS_CRITICAL_ENTER(); /*Tell the kernel we are in an ISR*/ OSIntEnter(); /* Enable Interrupts */ OS_CRITICAL_EXIT(); /*---------------------- ISR -------------------*/ ServiceRx(); ServiceTx(); /*---------------------- Epilogue ----------------*/ /*Give the O/S a chance to swap tasks. */ OSIntExit(); }
//开始任务函数 void start_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; CPU_Init(); #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); //统计任务 #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间 CPU_IntDisMeasMaxCurReset(); #endif #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif OS_CRITICAL_ENTER(); //进入临界区 OSTaskCreate((OS_TCB * )&Led0TaskTCB, (CPU_CHAR * )"led0 task", (OS_TASK_PTR )led0_task, (void * )0, (OS_PRIO )LED0_TASK_PRIO, (CPU_STK * )&LED0_TASK_STK[0], (CPU_STK_SIZE)LED0_STK_SIZE/10, (CPU_STK_SIZE)LED0_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err); //挂起开始任务 OS_CRITICAL_EXIT(); //进入临界区 }
void OSMutexPost (OS_MUTEX *p_mutex, OS_OPT opt, OS_ERR *p_err) { OS_PEND_LIST *p_pend_list; OS_TCB *p_tcb; CPU_TS ts; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_POST_ISR; return; } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_mutex == (OS_MUTEX *)0) { /* Validate 'p_mutex' */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_PTR_NULL; return; } switch (opt) { /* Validate 'opt' */ case OS_OPT_POST_NONE: case OS_OPT_POST_NO_SCHED: break; default: #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OPT_INVALID; return; } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) { /* Make sure mutex was created */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_TYPE; return; } #endif CPU_CRITICAL_ENTER(); if (OSTCBCurPtr != p_mutex->OwnerTCBPtr) { /* Make sure the mutex owner is releasing the mutex */ CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_MUTEX_NOT_OWNER; return; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST(p_mutex); /* Record the event. */ #endif OS_CRITICAL_ENTER_CPU_EXIT(); ts = OS_TS_GET(); /* Get timestamp */ p_mutex->TS = ts; p_mutex->OwnerNestingCtr--; /* Decrement owner's nesting counter */ if (p_mutex->OwnerNestingCtr > (OS_NESTING_CTR)0) { /* Are we done with all nestings? */ OS_CRITICAL_EXIT(); /* No */ *p_err = OS_ERR_MUTEX_NESTING; return; } p_pend_list = &p_mutex->PendList; if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0) { /* Any task waiting on mutex? */ p_mutex->OwnerTCBPtr = (OS_TCB *)0; /* No */ p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)0; OS_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; return; } /* Yes */ if (OSTCBCurPtr->Prio != p_mutex->OwnerOriginalPrio) { OS_RdyListRemove(OSTCBCurPtr); OSTCBCurPtr->Prio = p_mutex->OwnerOriginalPrio; /* Lower owner's priority back to its original one */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_DISINHERIT(OSTCBCurPtr, OSTCBCurPtr->Prio); #endif OS_PrioInsert(OSTCBCurPtr->Prio); OS_RdyListInsertTail(OSTCBCurPtr); /* Insert owner in ready list at new priority */ OSPrioCur = OSTCBCurPtr->Prio; } /* Get TCB from head of pend list */ p_tcb = p_pend_list->HeadPtr->TCBPtr; p_mutex->OwnerTCBPtr = p_tcb; /* Give mutex to new owner */ p_mutex->OwnerOriginalPrio = p_tcb->Prio; p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)1; /* Post to mutex */ OS_Post((OS_PEND_OBJ *)((void *)p_mutex), (OS_TCB *)p_tcb, (void *)0, (OS_MSG_SIZE )0, (CPU_TS )ts); OS_CRITICAL_EXIT_NO_SCHED(); if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) { OSSched(); /* Run the scheduler */ } *p_err = OS_ERR_NONE; }
static CPU_TS OS_TickListUpdateTimeout (void) { OS_TCB *p_tcb; OS_TICK_LIST *p_list; CPU_TS ts_start; CPU_TS ts_delta_timeout; #if OS_CFG_DBG_EN > 0u OS_OBJ_QTY nbr_updated; #endif CPU_SR_ALLOC(); OS_CRITICAL_ENTER(); /* ======= UPDATE TASKS WAITING WITH TIMEOUT ======= */ ts_start = OS_TS_GET(); #if OS_CFG_DBG_EN > 0u nbr_updated = (OS_OBJ_QTY)0u; #endif p_list = &OSTickListTimeout; p_tcb = p_list->TCB_Ptr; if (p_tcb != (OS_TCB *)0) { p_tcb->TickRemain--; while (p_tcb->TickRemain == 0u) { #if OS_CFG_DBG_EN > 0u nbr_updated++; #endif if (p_tcb->TaskState == OS_TASK_STATE_PEND_TIMEOUT) { #if (OS_MSG_EN > 0u) p_tcb->MsgPtr = (void *)0; p_tcb->MsgSize = (OS_MSG_SIZE)0u; #endif p_tcb->TS = OS_TS_GET(); OS_PendListRemove(p_tcb); /* Remove from wait list */ OS_RdyListInsert(p_tcb); /* Insert the task in the ready list */ p_tcb->TaskState = OS_TASK_STATE_RDY; p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */ p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */ } else if (p_tcb->TaskState == OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED) { #if (OS_MSG_EN > 0u) p_tcb->MsgPtr = (void *)0; p_tcb->MsgSize = (OS_MSG_SIZE)0u; #endif p_tcb->TS = OS_TS_GET(); OS_PendListRemove(p_tcb); /* Remove from wait list */ p_tcb->TaskState = OS_TASK_STATE_SUSPENDED; p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */ p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */ } p_list->TCB_Ptr = p_tcb->TickNextPtr; p_tcb = p_list->TCB_Ptr; /* Get 'p_tcb' again for loop */ if (p_tcb == (OS_TCB *)0) { #if OS_CFG_DBG_EN > 0u p_list->NbrEntries = (OS_OBJ_QTY)0u; #endif break; } else { #if OS_CFG_DBG_EN > 0u p_list->NbrEntries--; #endif p_tcb->TickPrevPtr = (OS_TCB *)0; } } } #if OS_CFG_DBG_EN > 0u p_list->NbrUpdated = nbr_updated; #endif ts_delta_timeout = OS_TS_GET() - ts_start; /* Measure execution time of the update */ OS_CRITICAL_EXIT(); /* ------------------------------------------------- */ return (ts_delta_timeout); }
OS_OBJ_QTY OSMutexDel (OS_MUTEX *p_mutex, OS_OPT opt, OS_ERR *p_err) { OS_OBJ_QTY cnt; OS_OBJ_QTY nbr_tasks; OS_PEND_DATA *p_pend_data; OS_PEND_LIST *p_pend_list; OS_TCB *p_tcb; OS_TCB *p_tcb_owner; CPU_TS ts; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to delete a mutex from an ISR */ *p_err = OS_ERR_DEL_ISR; return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_mutex == (OS_MUTEX *)0) { /* Validate 'p_mutex' */ *p_err = OS_ERR_OBJ_PTR_NULL; return ((OS_OBJ_QTY)0); } switch (opt) { /* Validate 'opt' */ case OS_OPT_DEL_NO_PEND: case OS_OPT_DEL_ALWAYS: break; default: *p_err = OS_ERR_OPT_INVALID; return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) { /* Make sure mutex was created */ *p_err = OS_ERR_OBJ_TYPE; return ((OS_OBJ_QTY)0); } #endif OS_CRITICAL_ENTER(); p_pend_list = &p_mutex->PendList; cnt = p_pend_list->NbrEntries; nbr_tasks = cnt; switch (opt) { case OS_OPT_DEL_NO_PEND: /* Delete mutex only if no task waiting */ if (nbr_tasks == (OS_OBJ_QTY)0) { #if OS_CFG_DBG_EN > 0u OS_MutexDbgListRemove(p_mutex); #endif OSMutexQty--; #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_DEL(p_mutex); /* Record the event. */ #endif OS_MutexClr(p_mutex); OS_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; } else { OS_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_WAITING; } break; case OS_OPT_DEL_ALWAYS: /* Always delete the mutex */ p_tcb_owner = p_mutex->OwnerTCBPtr; /* Did we had to change the prio of owner? */ if ((p_tcb_owner != (OS_TCB *)0) && (p_tcb_owner->Prio != p_mutex->OwnerOriginalPrio)) { switch (p_tcb_owner->TaskState) { /* yes */ case OS_TASK_STATE_RDY: OS_RdyListRemove(p_tcb_owner); p_tcb_owner->Prio = p_mutex->OwnerOriginalPrio; /* Lower owner's prio back */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio) #endif OS_PrioInsert(p_tcb_owner->Prio); OS_RdyListInsertTail(p_tcb_owner); /* Insert owner in ready list at new prio */ break; case OS_TASK_STATE_DLY: case OS_TASK_STATE_SUSPENDED: case OS_TASK_STATE_DLY_SUSPENDED: p_tcb_owner->Prio = p_mutex->OwnerOriginalPrio; /* Not in any pend list, change the prio */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio) #endif break; case OS_TASK_STATE_PEND: case OS_TASK_STATE_PEND_TIMEOUT: case OS_TASK_STATE_PEND_SUSPENDED: case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED: OS_PendListChangePrio(p_tcb_owner, /* Owner is pending on another object */ p_mutex->OwnerOriginalPrio); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio) #endif break; default: OS_CRITICAL_EXIT(); *p_err = OS_ERR_STATE_INVALID; return ((OS_OBJ_QTY)0); } } ts = OS_TS_GET(); /* Get timestamp */ while (cnt > 0u) { /* Remove all tasks from the pend list */ p_pend_data = p_pend_list->HeadPtr; p_tcb = p_pend_data->TCBPtr; OS_PendObjDel((OS_PEND_OBJ *)((void *)p_mutex), p_tcb, ts); cnt--; } #if OS_CFG_DBG_EN > 0u OS_MutexDbgListRemove(p_mutex); #endif OSMutexQty--; #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_DEL(p_mutex); /* Record the event. */ #endif OS_MutexClr(p_mutex); OS_CRITICAL_EXIT_NO_SCHED(); OSSched(); /* Find highest priority task ready to run */ *p_err = OS_ERR_NONE; break; default: OS_CRITICAL_EXIT(); *p_err = OS_ERR_OPT_INVALID; break; } return (nbr_tasks); }
void OS_TickListUpdate (void) { CPU_BOOLEAN done; OS_TICK_SPOKE *p_spoke; OS_TCB *p_tcb; OS_TCB *p_tcb_next; OS_TICK_SPOKE_IX spoke; CPU_TS ts_start; CPU_TS ts_end; CPU_SR_ALLOC(); OS_CRITICAL_ENTER(); ts_start = OS_TS_GET(); OSTickCtr++; /* Keep track of the number of ticks */ spoke = (OS_TICK_SPOKE_IX)(OSTickCtr % OSCfg_TickWheelSize); p_spoke = &OSCfg_TickWheel[spoke]; p_tcb = p_spoke->FirstPtr; done = DEF_FALSE; while (done == DEF_FALSE) { if (p_tcb != (OS_TCB *)0) { p_tcb_next = p_tcb->TickNextPtr; /* Point to next TCB to update */ switch (p_tcb->TaskState) { case OS_TASK_STATE_RDY: case OS_TASK_STATE_PEND: case OS_TASK_STATE_SUSPENDED: case OS_TASK_STATE_PEND_SUSPENDED: break; case OS_TASK_STATE_DLY: p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */ - OSTickCtr; if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */ p_tcb->TaskState = OS_TASK_STATE_RDY; OS_TaskRdy(p_tcb); /* Make task ready to run */ } else { done = DEF_TRUE; /* Don't find a match, we're done! */ } break; case OS_TASK_STATE_PEND_TIMEOUT: p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */ - OSTickCtr; if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */ #if (OS_MSG_EN > 0u) p_tcb->MsgPtr = (void *)0; p_tcb->MsgSize = (OS_MSG_SIZE)0u; #endif p_tcb->TS = OS_TS_GET(); OS_PendListRemove(p_tcb); /* Remove from wait list */ OS_TaskRdy(p_tcb); p_tcb->TaskState = OS_TASK_STATE_RDY; p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */ p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */ } else { done = DEF_TRUE; /* Don't find a match, we're done! */ } break; case OS_TASK_STATE_DLY_SUSPENDED: p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */ - OSTickCtr; if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */ p_tcb->TaskState = OS_TASK_STATE_SUSPENDED; OS_TickListRemove(p_tcb); /* Remove from current wheel spoke */ } else { done = DEF_TRUE; /* Don't find a match, we're done! */ } break; case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED: p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */ - OSTickCtr; if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */ #if (OS_MSG_EN > 0u) p_tcb->MsgPtr = (void *)0; p_tcb->MsgSize = (OS_MSG_SIZE)0u; #endif p_tcb->TS = OS_TS_GET(); OS_PendListRemove(p_tcb); /* Remove from wait list */ OS_TickListRemove(p_tcb); /* Remove from current wheel spoke */ p_tcb->TaskState = OS_TASK_STATE_SUSPENDED; p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */ p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */ } else { done = DEF_TRUE; /* Don't find a match, we're done! */ } break; default: break; } p_tcb = p_tcb_next; } else { done = DEF_TRUE; } } ts_end = OS_TS_GET() - ts_start; /* Measure execution time of tick task */ if (ts_end > OSTickTaskTimeMax) { OSTickTaskTimeMax = ts_end; } OS_CRITICAL_EXIT(); }
void OSMutexPend (OS_MUTEX *p_mutex, OS_TICK timeout, OS_OPT opt, CPU_TS *p_ts, OS_ERR *p_err) { OS_PEND_DATA pend_data; OS_TCB *p_tcb; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_PEND_ISR; return; } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_mutex == (OS_MUTEX *)0) { /* Validate arguments */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_PTR_NULL; return; } switch (opt) { /* Validate 'opt' */ case OS_OPT_PEND_BLOCKING: case OS_OPT_PEND_NON_BLOCKING: break; default: #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OPT_INVALID; return; } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) { /* Make sure mutex was created */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_TYPE; return; } #endif if (p_ts != (CPU_TS *)0) { *p_ts = (CPU_TS )0; /* Initialize the returned timestamp */ } CPU_CRITICAL_ENTER(); if (p_mutex->OwnerNestingCtr == (OS_NESTING_CTR)0) { /* Resource available? */ p_mutex->OwnerTCBPtr = OSTCBCurPtr; /* Yes, caller may proceed */ p_mutex->OwnerOriginalPrio = OSTCBCurPtr->Prio; p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)1; if (p_ts != (CPU_TS *)0) { *p_ts = p_mutex->TS; } CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_NONE; return; } if (OSTCBCurPtr == p_mutex->OwnerTCBPtr) { /* See if current task is already the owner of the mutex */ p_mutex->OwnerNestingCtr++; if (p_ts != (CPU_TS *)0) { *p_ts = p_mutex->TS; } CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_MUTEX_OWNER; /* Indicate that current task already owns the mutex */ return; } if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */ CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_PEND_WOULD_BLOCK; /* No */ return; } else { if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */ CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_SCHED_LOCKED; return; } } /* Lock the scheduler/re-enable interrupts */ OS_CRITICAL_ENTER_CPU_EXIT(); p_tcb = p_mutex->OwnerTCBPtr; /* Point to the TCB of the Mutex owner */ if (p_tcb->Prio > OSTCBCurPtr->Prio) { /* See if mutex owner has a lower priority than current */ switch (p_tcb->TaskState) { case OS_TASK_STATE_RDY: OS_RdyListRemove(p_tcb); /* Remove from ready list at current priority */ p_tcb->Prio = OSTCBCurPtr->Prio; /* Raise owner's priority */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_INHERIT(p_tcb, p_tcb->Prio); #endif OS_PrioInsert(p_tcb->Prio); OS_RdyListInsertHead(p_tcb); /* Insert in ready list at new priority */ break; case OS_TASK_STATE_DLY: case OS_TASK_STATE_DLY_SUSPENDED: case OS_TASK_STATE_SUSPENDED: p_tcb->Prio = OSTCBCurPtr->Prio; /* Only need to raise the owner's priority */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_INHERIT(p_tcb, p_tcb->Prio); #endif break; case OS_TASK_STATE_PEND: /* Change the position of the task in the wait list */ case OS_TASK_STATE_PEND_TIMEOUT: case OS_TASK_STATE_PEND_SUSPENDED: case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED: OS_PendListChangePrio(p_tcb, OSTCBCurPtr->Prio); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_INHERIT(p_tcb, p_tcb->Prio); #endif break; default: OS_CRITICAL_EXIT(); *p_err = OS_ERR_STATE_INVALID; return; } } OS_Pend(&pend_data, /* Block task pending on Mutex */ (OS_PEND_OBJ *)((void *)p_mutex), OS_TASK_PEND_ON_MUTEX, timeout); OS_CRITICAL_EXIT_NO_SCHED(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_BLOCK(p_mutex); /* Record the event. */ #endif OSSched(); /* Find the next highest priority task ready to run */ CPU_CRITICAL_ENTER(); switch (OSTCBCurPtr->PendStatus) { case OS_STATUS_PEND_OK: /* We got the mutex */ if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_NONE; break; case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */ if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_PEND_ABORT; break; case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get mutex within timeout */ if (p_ts != (CPU_TS *)0) { *p_ts = (CPU_TS )0; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_TIMEOUT; break; case OS_STATUS_PEND_DEL: /* Indicate that object pended on has been deleted */ if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_DEL; break; default: #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_STATUS_INVALID; break; } CPU_CRITICAL_EXIT(); }
//开始任务函数 void start_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; CPU_Init(); #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); //统计任务 #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间 CPU_IntDisMeasMaxCurReset(); #endif #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif OS_CRITICAL_ENTER(); //进入临界区 //创建定时器1 OSTmrCreate((OS_TMR *)&tmr1, //定时器1 (CPU_CHAR *)"tmr1", //定时器名字 (OS_TICK )0, //0ms (OS_TICK )50, //50*10=500ms (OS_OPT )OS_OPT_TMR_PERIODIC, //周期模式 (OS_TMR_CALLBACK_PTR)tmr1_callback,//定时器1回调函数 (void *)0, //参数为0 (OS_ERR *)&err); //返回的错误码 //创建主任务 OSTaskCreate((OS_TCB * )&Main_TaskTCB, (CPU_CHAR * )"Main task", (OS_TASK_PTR )main_task, (void * )0, (OS_PRIO )MAIN_TASK_PRIO, (CPU_STK * )&MAIN_TASK_STK[0], (CPU_STK_SIZE)MAIN_STK_SIZE/10, (CPU_STK_SIZE)MAIN_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建MSGDIS任务 OSTaskCreate((OS_TCB * )&Msgdis_TaskTCB, (CPU_CHAR * )"Msgdis task", (OS_TASK_PTR )msgdis_task, (void * )0, (OS_PRIO )MSGDIS_TASK_PRIO, (CPU_STK * )&MSGDIS_TASK_STK[0], (CPU_STK_SIZE)MSGDIS_STK_SIZE/10, (CPU_STK_SIZE)MSGDIS_STK_SIZE, (OS_MSG_QTY )TASK_Q_NUM, //任务Msgdis_task需要使用内建消息队列,消息队列长度为4 (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); OS_CRITICAL_EXIT(); //退出临界区 OSTaskDel((OS_TCB*)0,&err); //删除start_task任务自身 }
//开始任务函数 void start_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; CPU_Init(); #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); //统计任务 #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间 CPU_IntDisMeasMaxCurReset(); #endif #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif OS_CRITICAL_ENTER(); //进入临界区 //创建信号量Test_Sem1 OSSemCreate ((OS_SEM* )&Test_Sem1, (CPU_CHAR* )"Test_Sem1", (OS_SEM_CTR)0, (OS_ERR* )&err); //创建信号量Test_Sem2 OSSemCreate ((OS_SEM* )&Test_Sem2, (CPU_CHAR* )"Test_Sem2", (OS_SEM_CTR)0, (OS_ERR* )&err); //创建消息队列 OSQCreate ((OS_Q* )&Test_Q, //消息队列 (CPU_CHAR* )"KEY Msg", //消息队列名称 (OS_MSG_QTY )QUEUE_NUM, //消息队列长度 (OS_ERR* )&err); //错误码 //创建TASK1任务 OSTaskCreate((OS_TCB * )&Task1_TaskTCB, (CPU_CHAR * )"Task1 task", (OS_TASK_PTR )task1_task, (void * )0, (OS_PRIO )TASK1_TASK_PRIO, (CPU_STK * )&TASK1_TASK_STK[0], (CPU_STK_SIZE)TASK1_STK_SIZE/10, (CPU_STK_SIZE)TASK1_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建MULTI测试任务 OSTaskCreate((OS_TCB * )&Multi_TaskTCB, (CPU_CHAR * )"Multi task", (OS_TASK_PTR )multi_task, (void * )0, (OS_PRIO )MULTI_TASK_PRIO, (CPU_STK * )&MULTI_TASK_STK[0], (CPU_STK_SIZE)MULTI_STK_SIZE/10, (CPU_STK_SIZE)MULTI_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); OS_CRITICAL_EXIT(); //退出临界区 OSTaskDel((OS_TCB*)0,&err); //删除start_task任务自身 }
void OS_StatTask (void *p_arg) { #if OS_CFG_DBG_EN > 0u #if OS_CFG_TASK_PROFILE_EN > 0u OS_CPU_USAGE usage; OS_CYCLES cycles_total; #endif OS_TCB *p_tcb; #endif OS_ERR err; OS_TICK dly; CPU_TS ts_start; CPU_TS ts_end; CPU_SR_ALLOC(); p_arg = p_arg; /* Prevent compiler warning for not using 'p_arg' */ while (OSStatTaskRdy != DEF_TRUE) { OSTimeDly(2u * OSCfg_StatTaskRate_Hz, /* Wait until statistic task is ready */ OS_OPT_TIME_DLY, &err); } OSStatReset(&err); /* Reset statistics */ dly = (OS_TICK)0; /* Compute statistic task sleep delay */ if (OSCfg_TickRate_Hz > OSCfg_StatTaskRate_Hz) { dly = (OS_TICK)(OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz); } if (dly == (OS_TICK)0) { dly = (OS_TICK)(OSCfg_TickRate_Hz / (OS_RATE_HZ)10); } while (DEF_ON) { ts_start = OS_TS_GET(); #ifdef CPU_CFG_INT_DIS_MEAS_EN OSIntDisTimeMax = CPU_IntDisMeasMaxGet(); #endif CPU_CRITICAL_ENTER(); /* ----------------- OVERALL CPU USAGE ------------------ */ OSStatTaskCtrRun = OSStatTaskCtr; /* Obtain the of the stat counter for the past .1 second */ OSStatTaskCtr = (OS_TICK)0; /* Reset the stat counter for the next .1 second */ CPU_CRITICAL_EXIT(); if (OSStatTaskCtrMax > OSStatTaskCtrRun) { if (OSStatTaskCtrMax > (OS_TICK)0) { OSStatTaskCPUUsage = (OS_CPU_USAGE)((OS_TICK)100u - 100u * OSStatTaskCtrRun / OSStatTaskCtrMax); } else { OSStatTaskCPUUsage = (OS_CPU_USAGE)100; } } else { OSStatTaskCPUUsage = (OS_CPU_USAGE)100; } OSStatTaskHook(); /* Invoke user definable hook */ #if OS_CFG_DBG_EN > 0u #if OS_CFG_TASK_PROFILE_EN > 0u cycles_total = (OS_CYCLES)0; p_tcb = OSTaskDbgListPtr; while (p_tcb != (OS_TCB *)0) { /* ----------------- TOTAL CYCLES COUNT ----------------- */ OS_CRITICAL_ENTER(); p_tcb->CyclesTotalPrev = p_tcb->CyclesTotal; /* Save accumulated # cycles into a temp variable */ p_tcb->CyclesTotal = (OS_CYCLES)0; /* Reset total cycles for task for next run */ OS_CRITICAL_EXIT(); cycles_total += p_tcb->CyclesTotalPrev;/* Perform sum of all task # cycles */ p_tcb = p_tcb->DbgNextPtr; } #endif #if OS_CFG_TASK_PROFILE_EN > 0u cycles_total /= 100; /* ------------- INDIVIDUAL TASK CPU USAGE -------------- */ #endif p_tcb = OSTaskDbgListPtr; while (p_tcb != (OS_TCB *)0) { #if OS_CFG_TASK_PROFILE_EN > 0u /* Compute execution time of each task */ if (cycles_total > (OS_CYCLES)0) { usage = (OS_CPU_USAGE)(p_tcb->CyclesTotalPrev / cycles_total); if (usage > 100u) { usage = 100u; } } else { usage = 0u; } p_tcb->CPUUsage = usage; #endif #if OS_CFG_STAT_TASK_STK_CHK_EN > 0u OSTaskStkChk( p_tcb, /* Compute stack usage of active tasks only */ &p_tcb->StkFree, &p_tcb->StkUsed, &err); #endif p_tcb = p_tcb->DbgNextPtr; } #endif if (OSStatResetFlag == DEF_TRUE) { /* Check if need to reset statistics */ OSStatResetFlag = DEF_FALSE; OSStatReset(&err); } ts_end = OS_TS_GET() - ts_start; /* Measure execution time of statistic task */ if (ts_end > OSStatTaskTimeMax) { OSStatTaskTimeMax = ts_end; } OSTimeDly(dly, OS_OPT_TIME_DLY, &err); } }
void OSMemCreate (OS_MEM *p_mem, CPU_CHAR *p_name, void *p_addr, OS_MEM_QTY n_blks, OS_MEM_SIZE blk_size, OS_ERR *p_err) { #if OS_CFG_ARG_CHK_EN > 0u CPU_DATA align_msk; #endif OS_MEM_QTY i; OS_MEM_QTY loops; CPU_INT08U *p_blk; void **p_link; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #ifdef OS_SAFETY_CRITICAL_IEC61508 if (OSSafetyCriticalStartFlag == DEF_TRUE) { *p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME; return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */ *p_err = OS_ERR_MEM_CREATE_ISR; return; } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_addr == (void *)0) { /* Must pass a valid address for the memory part. */ *p_err = OS_ERR_MEM_INVALID_P_ADDR; return; } if (n_blks < (OS_MEM_QTY)2) { /* Must have at least 2 blocks per partition */ *p_err = OS_ERR_MEM_INVALID_BLKS; return; } if (blk_size < sizeof(void *)) { /* Must contain space for at least a pointer */ *p_err = OS_ERR_MEM_INVALID_SIZE; return; } align_msk = sizeof(void *) - 1u; if (align_msk > 0) { if (((CPU_ADDR)p_addr & align_msk) != 0u){ /* Must be pointer size aligned */ *p_err = OS_ERR_MEM_INVALID_P_ADDR; return; } if ((blk_size & align_msk) != 0u) { /* Block size must be a multiple address size */ *p_err = OS_ERR_MEM_INVALID_SIZE; } } #endif p_link = (void **)p_addr; /* Create linked list of free memory blocks */ p_blk = p_addr; loops = n_blks - 1u; for (i = 0u; i < loops; i++) { p_blk += blk_size; *p_link = (void *)p_blk; /* Save pointer to NEXT block in CURRENT block */ p_link = (void **)(void *)p_blk; /* Position to NEXT block */ } *p_link = (void *)0; /* Last memory block points to NULL */ OS_CRITICAL_ENTER(); p_mem->Type = OS_OBJ_TYPE_MEM; /* Set the type of object */ p_mem->NamePtr = p_name; /* Save name of memory partition */ p_mem->AddrPtr = p_addr; /* Store start address of memory partition */ p_mem->FreeListPtr = p_addr; /* Initialize pointer to pool of free blocks */ p_mem->NbrFree = n_blks; /* Store number of free blocks in MCB */ p_mem->NbrMax = n_blks; p_mem->BlkSize = blk_size; /* Store block size of each memory blocks */ #if OS_CFG_DBG_EN > 0u OS_MemDbgListAdd(p_mem); #endif OSMemQty++; OS_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; }
//开始任务函数 void start_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; CPU_Init(); #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); //统计任务 #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间 CPU_IntDisMeasMaxCurReset(); #endif #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif OS_CRITICAL_ENTER(); //进入临界区 OSFlagCreate((OS_FLAG_GRP *)&event_flag, (CPU_CHAR *)"event flag", (OS_FLAGS)0x00, (OS_ERR *)&err ); OSTaskCreate((OS_TCB * )&Led0TaskTCB, (CPU_CHAR * )"led0 task", (OS_TASK_PTR )led0_task, (void * )0, (OS_PRIO )LED0_TASK_PRIO, (CPU_STK * )&LED0_TASK_STK[0], (CPU_STK_SIZE)LED0_STK_SIZE/10, (CPU_STK_SIZE)LED0_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建浮点测试任务 OSTaskCreate((OS_TCB * )&FloatTaskTCB, (CPU_CHAR * )"float test task", (OS_TASK_PTR )float_task, (void * )0, (OS_PRIO )FLOAT_TASK_PRIO, (CPU_STK * )&FLOAT_TASK_STK[0], (CPU_STK_SIZE)FLOAT_STK_SIZE/10, (CPU_STK_SIZE)FLOAT_STK_SIZE, (OS_MSG_QTY )5, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建协议处理任务 OSTaskCreate((OS_TCB * )&ProtocolTaskTCB, (CPU_CHAR * )"protocol task", (OS_TASK_PTR )protocol_task, (void * )0, (OS_PRIO )Protocol_TASK_PRIO, (CPU_STK * )&Protocol_TASK_STK[0], (CPU_STK_SIZE)Protocol_STK_SIZE/10, (CPU_STK_SIZE)Protocol_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); OS_CRITICAL_EXIT(); //进入临界区 OSTaskDel(NULL,&err); }