FreeRTOS使用示例
UCOS使用示例
信號量使用
信號量訪問共享資源區/
OS_SEMMY_SEM; //定義一個信號量,用于訪問共享資源OSSemCreate ((OS_SEM* )&MY_SEM, //創建信號量,指向信號量(CPU_CHAR* )"MY_SEM", //信號量名字(OS_SEM_CTR )1, //信號量值為1,可以理解開始有個任務就可以請求到信號量(OS_ERR* )&err);//錯誤碼void task1_task(void *p_arg)
{OS_ERR err;u8 task1_str[]="First task Running!";//請求信號量,參數2:0為死等;參數3:表示信號量無效任務掛起等待信號量;參數4:時間戳OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);memcpy(share_resource,task1_str,sizeof(task1_str));//向共享資源區拷貝數據delay_ms(200);printf("%s\r\n",share_resource); //串口輸出共享資源區數據OSSemPost(&MY_SEM,OS_OPT_POST_1,&err); //發送信號量
}
void task2_task(void *p_arg)
{OS_ERR err;u8 task2_str[]="Second task Running!";OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //請求信號量(3)memcpy(share_resource,task2_str,sizeof(task2_str));//向共享資源區拷貝數據delay_ms(200);printf("%s\r\n",share_resource); //串口輸出共享資源區數據//OS_OPT_POST_1表示向信號量優先級高的任務發送信號量OSSemPost(&MY_SEM,OS_OPT_POST_1,&err);//發送信號量
}
/信號量用于任務同步實驗
OS_SEM SYNC_SEM; //定義一個信號量,用于任務同步
OSSemCreate ((OS_SEM* )&SYNC_SEM,//創建信號量,指向信號量(CPU_CHAR* )"SYNC_SEM",//信號量名字(OS_SEM_CTR )0, //信號量值為0(OS_ERR* )&err); //錯誤碼void task1_task(void *p_arg)
{OS_ERR err;if(KEY_Scan(0)==WKUP_PRES){OSSemPost(&SYNC_SEM,OS_OPT_POST_1,&err);//發送信號量LCD_ShowxNum(150,111,SYNC_SEM.Ctr,3,16,0); //顯示信號量值 }
}void task2_task(void *p_arg)
{OS_ERR err;//OS_OPT_PEND_BLOCKING:表示信號量無效任務掛起等待信號量//如是OS_OPT_POST_ALL 向等待該信號量的所有任務發送信號量。OSSemPend(&SYNC_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //請求信號量LCD_ShowxNum(150,111,SYNC_SEM.Ctr,3,16,0); //顯示信號量值OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);//延時1s
}
?內建信號量
//內建信號量///
void task1_task(void *p_arg)
{OS_ERR err;if(KEY_Scan(0) == WKUP_PRES){//OS_OPT_POST_NONE:不指定特定的選項OSTaskSemPost(&Task2_TaskTCB,OS_OPT_POST_NONE,&err);//使用系統內建信號量向任務task2發送信號量LCD_ShowxNum(150,111,Task2_TaskTCB.SemCtr,3,16,0); //顯示信號量值}
}void task2_task(void *p_arg)
{OS_ERR err; //參數1:超時時間,0為一直等待信號量;2:信號量被占用則掛起等待;3:時間戳OSTaskSemPend(0,OS_OPT_PEND_BLOCKING, 0,&err);//請求任務內建的信號量LCD_ShowxNum(150,111,Task2_TaskTCB.SemCtr,3,16,0);//顯示任務內建信號量值
}
消息傳遞
消息隊列相關函數
消息隊列//
#define KEYMSG_Q_NUM 1 //按鍵消息隊列的數量
#define DATAMSG_Q_NUM 4 //發送數據的消息隊列的數量
OS_Q KEY_Msg; //定義一個消息隊列,用于按鍵消息傳遞,模擬消息郵箱
OS_Q DATA_Msg; //定義一個消息隊列,用于發送數據void start_task(void *p_arg)
{//......OSQCreate ( (OS_Q* )&KEY_Msg,//指向一個消息隊列(CPU_CHAR* )"KEY Msg",//消息隊列名稱(OS_MSG_QTY )KEYMSG_Q_NUM, //消息隊列長度,這里設置為 1(OS_ERR* )&err); //錯誤碼
//創建消息隊列 DATA_MsgOSQCreate ( (OS_Q* )&DATA_Msg, //指向一個消息隊列(CPU_CHAR* )"DATA Msg",//消息隊列的名稱(OS_MSG_QTY )DATAMSG_Q_NUM,//消息隊列的個數這里是4(OS_ERR* )&err);//錯誤碼
}void tmr1_callback(void *p_tmr,void *p_arg)
{//......sprintf((char*)pbuf,"ALIENTEK %d",msg_num);//發送消息OSQPost((OS_Q* )&DATA_Msg,//指向一個消息隊列(void* )pbuf, //指向要發送的內容void指針(OS_MSG_SIZE )10, //要發送的消息大小,單位字節(OS_OPT )OS_OPT_POST_FIFO,//發送消息操作類型,這里表示發送消息報錯隊列尾部(OS_ERR* )&err); //錯誤碼
}void main_task(void *p_arg)
{u8 key = KEY_Scan(0); //掃描按鍵//發送消息OSQPost((OS_Q* )&KEY_Msg,(void* )&key,(OS_MSG_SIZE )1,(OS_OPT )OS_OPT_POST_FIFO,(OS_ERR* &err);u8 msgq_remain_size = DATA_Msg.MsgQ.NbrEntriesSize-DATA_Msg.MsgQ.NbrEntries;//消息隊列剩余大小sprintf((char*)p,"Total Size:%d",DATA_Msg.MsgQ.NbrEntriesSize);//顯示 DATA_Msg 消息隊列總的大小
}void Keyprocess_task(void *p_arg)
{u8 num;u8 *key;OS_MSG_SIZE size;OS_ERR err;key=OSQPend((OS_Q* )&KEY_Msg, //指向一個消息隊列,整個函數反回的是指針消息數據(OS_TICK )0, //指定時間沒有接收到數據任務就被喚醒,0一直等(OS_OPT )OS_OPT_PEND_BLOCKING,//一直等,直到接收到消息(OS_MSG_SIZE* )&size,//接收消息的字節長度(CPU_TS* )0,//指向一個時間戳(OS_ERR* )&err);//錯誤碼
}
void msgdis_task(void *p_arg)
{u8 *p;OS_MSG_SIZE size;OS_ERR err; p=OSQPend( (OS_Q* )&DATA_Msg, (OS_TICK )0,(OS_OPT )OS_OPT_PEND_BLOCKING,(OS_MSG_SIZE* )&size;(CPU_TS* )0,(OS_ERR* )&err);LCD_ShowString(5,270,100,16,16,p);
}
?任務內建消息隊列
#define TASK_Q_NUM 4 //任務內建消息隊列的長度void tmr1_callback(void *p_tmr,void *p_arg)
{//......sprintf((char*)pbuf,"ALIENTEK %d",msg_num);OSTaskQPost((OS_TCB* )&Msgdis_TaskTCB, //向任務msgdis_task發送消息(void* )pbuf, //指向要發送的內容void指針(OS_MSG_SIZE )10, //指定要發送消息的大小(OS_OPT )OS_OPT_POST_FIFO,//發送消息報錯在隊列末尾(OS_ERR* )&err);//錯誤碼
}void msgdis_task(void *p_arg)
{//......u8 *p;OS_MSG_SIZE size;OS_ERR err; p=OSTaskQPend((OS_TICK )0, //超時時間沒有接收到數據任務就被喚醒(OS_OPT )OS_OPT_PEND_BLOCKING, //一直等待,直到接收到消息(OS_MSG_SIZE* )&size, //消息的大小(CPU_TS* )0, //時間戳(OS_ERR* )&err ); //錯誤碼LCD_ShowString(40,270,100,16,16,p);//P為接收到的數據指針
}
事件標志組
事件標志組//
#define KEY0_FLAG 0x01
#define KEY1_FLAG 0x02
#define KEYFLAGS_VALUE 0X00
OS_FLAG_GRP EventFlags; //定義一個事件標志組void start_task(void *p_arg)
{//......OSFlagCreate((OS_FLAG_GRP* )&EventFlags, //指向事件標志組(CPU_CHAR* )"Event Flags", //名字(OS_FLAGS )KEYFLAGS_VALUE, //事件標志組初始值(OS_ERR* )&err); //錯誤碼
}//向事件標志組 EventFlags 發送標志
void main_task(void *p_arg)
{//......//按下按鍵1發送flags_num=OSFlagPost((OS_FLAG_GRP*)&EventFlags,//指向事件標志組(OS_FLAGS )KEY0_FLAG,//決定哪些位清零和置位(OS_OPT )OS_OPT_POST_FLAG_SET,//對位進行置位操作,也可清零(OS_ERR* )&err);//返回錯誤碼//按下按鍵2發送
//向事件標志組 EventFlags 發送標志flags_num=OSFlagPost((OS_FLAG_GRP*)&EventFlags,(OS_FLAGS )KEY1_FLAG,(OS_OPT )OS_OPT_POST_FLAG_SET,(OS_ERR* )&err);
}
void flagsprocess_task(void *p_arg)
{//......OS_ERR err; //等待事件標志組OSFlagPend((OS_FLAG_GRP* )&EventFlags, //指向事件標準組(OS_FLAGS )KEY0_FLAG+KEY1_FLAG,//等待 bit0和bit1時,值就為 0X03。(OS_TICK )0,//等待超時時間,為0則一直等待下去(OS_OPT )OS_OPT_PEND_FLAG_SET_ALL+\//多種配置模式:當前配置為等待所有位OS_OPT_PEND_FLAG_CONSUME,//保留事件標志的狀態(CPU_TS* )0,//時間戳(OS_ERR* )&err);//返回錯誤碼printf("事件標志組 EventFlags 的值:%d\r\n",EventFlags.Flags);
}
?