UCOSIIIの基礎知識の説明

特徴

  • 初心者がUCOSIIIを知るのを手伝ってください
  • タスクの作成と削除、タスクの一時停止と再開、ソフトウェアタイマー、セマフォと相互排除セマフォ、メッセージ送信など、UCOSIIIの基本的な知識を把握します。

1.はじめに

  μC/ OS-IIはMicriumによって提供され、ポータブルで、硬化可能で、調整可能で、プリエンプティブなマルチタスクリアルタイムカーネルです。さまざまなマイクロプロセッサ、マイクロコントローラ、およびデジタル処理チップ(100種類以上に移植されています)に適しています。マイクロプロセッサアプリケーションの)。同時に、システムのソースコードはオープンでクリーンで一貫性があり、詳細なコメントが付いており、システム開発に適しています。μC/ OS-IIは、連邦航空局(FAA)の民間航空機認証に合格し、航空無線技術委員会(RTCA)のDO-178B規格に準拠しています。最新バージョンはμC/ OS-IIIです。
  μC/ OS-IIは、コア、タスク処理、時間処理、タスクの同期と通信、CPU移植の5つの部分に大別できます。

  1. コア部分(OSCore.c)
    は、オペレーティングシステムの初期化、オペレーティングシステムの操作、割り込みのリードインとアウト、クロックティック、タスクスケジューリング、イベント処理などを含む、オペレーティングシステムの処理コアです。システムの基本的な作業を維持できる部品はこちらです。
  2. タスク処理部分(OSTask.c)の内容は、タスク
    の操作と密接に関連しています。タスクの作成、削除、一時停止、回復などを含みます。μC/ OS-IIはタスクに基づいてスケジュールされるため、コンテンツのこの部分も非常に重要です。
  3. クロック部分(OSTime.c)
    μC/ OS-IIの最小クロック単位はタイムティック(クロックティック)です。タスク遅延などの操作はここで完了します。
  4. タスクの同期と通信の部分
    は、セマフォ、メールボックス、メールボックスキュー、イベントフラグなどを含むイベント処理部分であり、主にタスク間の相互接続と重要なリソースへのアクセスに使用されます。
  5. CPU
    のインターフェース部分は、使用するCPUのμC/ OS-IIの移植部分を指します。μC/ OS-IIはユニバーサルオペレーティングシステムであるため、特定のCPUの特定のコンテンツと要件に応じて、重要な問題の実現を移植する必要があります。コンテンツのこの部分にはSPなどのシステムポインタが含まれているため、通常はアセンブリ言語で記述されています。これには主に、割り込みレベルのタスク切り替えの低レベルの実装、タスクレベルのタスク切り替えの最下位の実装、クロックビートの生成と処理、および関連する割り込みの処理が含まれます。

2.基礎知識

1.タスクの作成

①関連するパラメータを定義する

//任务优先级
#define LED1_TASK_PRIO		5
//任务堆栈大小	
#define LED1_STK_SIZE 		128
//任务控制块
OS_TCB Led1TaskTCB;
//任务堆栈	
CPU_STK LED1_TASK_STK[LED1_STK_SIZE];
//任务函数
void led1_task(void *p_arg);

②タスクを作成する

//创建LED1任务
OSTaskCreate((OS_TCB 	* )&Led1TaskTCB,		
			 (CPU_CHAR	* )"led1 task", 		
                (OS_TASK_PTR )led1_task, 			
                (void		* )0,					
                (OS_PRIO	  )LED1_TASK_PRIO,     	
                (CPU_STK   * )&LED1_TASK_STK[0],	
                (CPU_STK_SIZE)LED1_STK_SIZE/10,	
                (CPU_STK_SIZE)LED1_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);

③タスク機能の書き込み

//led1任务函数
void led1_task(void *p_arg)
{
    
    
	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
    
    
		LED1=~LED1;
		OSTimeDlyHMSM(0,0,0,200,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
	}
}

2.タスクを一時停止および再開します

在这里插入代码片//task1任务函数
void task1_task(void *p_arg)
{
    
    
	u8 task1_num=0;
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg = p_arg;
	
	POINT_COLOR = BLACK;
	OS_CRITICAL_ENTER();
	LCD_DrawRectangle(5,110,115,314); 	//画一个矩形	
	LCD_DrawLine(5,130,115,130);		//画线
	POINT_COLOR = BLUE;
	LCD_ShowString(6,111,110,16,16,"Task1 Run:000");
	OS_CRITICAL_EXIT();
	while(1)
	{
    
    
		task1_num++;	//任务1执行次数加1 注意task1_num1加到255的时候会清零!!
		LED0= ~LED0;
		printf("任务1已经执行:%d次\r\n",task1_num);
		if(task1_num==5) 
		{
    
    
			OSTaskSuspend((OS_TCB*)&Task2_TaskTCB,&err);//任务1执行5次后挂起任务2
			printf("任务1挂起了任务2!\r\n");
		}
		if(task1_num==10) 
		{
    
    
			OSTaskResume((OS_TCB*)&Task2_TaskTCB,&err);	//任务1运行10次后恢复任务2
			printf("任务1恢复了任务2!\r\n");
		}
		LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域
		LCD_ShowxNum(86,111,task1_num,3,16,0x80);	//显示任务执行次数
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s
		
	}
}

3.タスクの同期

①セマフォを定義する

OS_SEM	MY_SEM;		           				 //定义一个信号量,用于访问共享资源

②開始タスクでセマフォを作成する

OSSemCreate ((OS_SEM*	)&MY_SEM,			//创建一个信号量
                (CPU_CHAR*	)"MY_SEM",
                (OS_SEM_CTR)1,		
                (OS_ERR*	)&err);

③セマフォを使う

//led0任务函数
void led0_task(void *p_arg)
{
    
    
	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
    
    
		OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); 	//请求信号量
		LED0=~LED0;
		
//		share_resource=share_resource+1;
//		printf("任务1执行次数:%d\r\n",share_resource);
//		delay_ms(1000);
//		OSSemPost (&MY_SEM,OS_OPT_POST_1,&err);				//发送信号量
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
	}
}

//led1任务函数
void led1_task(void *p_arg)
{
    
    
	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
    
    
		LED1=~LED1;
		OSSemPost (&MY_SEM,OS_OPT_POST_1,&err);
//		OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); 	//请求信号量
//		share_resource=share_resource+1;
//		printf("任务2执行次数:%d\r\n",share_resource);
		//delay_ms(2000);
						//发送信号量
		OSTimeDlyHMSM(0,0,2,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时500ms
	}
}

4.メッセージ配信

①メッセージキューを定義する

#define KEYMSG_Q_NUM	1	//按键消息队列的数量
#define DATAMSG_Q_NUM	4	//发送数据的消息队列的数量
OS_Q KEY_Msg;				//定义一个消息队列,用于按键消息传递,模拟消息邮箱
OS_Q DATA_Msg;				//定义一个消息队列,用于发送数据

②メッセージキューを作成する

//创建消息队列KEY_Msg
OSQCreate ((OS_Q*		)&KEY_Msg,	//消息队列
               (CPU_CHAR*	)"KEY Msg",	//消息队列名称
               (OS_MSG_QTY	)KEYMSG_Q_NUM,	//消息队列长度,这里设置为1
               (OS_ERR*	)&err);		//错误码
//创建消息队列DATA_Msg
OSQCreate ((OS_Q*		)&DATA_Msg,	
               (CPU_CHAR*	)"DATA Msg",	
               (OS_MSG_QTY	)DATAMSG_Q_NUM,	
               (OS_ERR*	)&err);	

③タスク機能

//定时器1的回调函数
void tmr1_callback(void *p_tmr,void *p_arg)
{
    
    
	u8 *pbuf;
	static u8 msg_num;
	OS_ERR err;
	pbuf = mymalloc(SRAMIN,10);	//申请10个字节
	if(pbuf)	//申请内存成功
	{
    
    
		msg_num++;
		sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
		//发送消息
		OSQPost((OS_Q*		)&DATA_Msg,		
				(void*		)pbuf,
				(OS_MSG_SIZE)10,
				(OS_OPT		)OS_OPT_POST_FIFO,
				(OS_ERR*	)&err);
		if(err != OS_ERR_NONE)
		{
    
    
			myfree(SRAMIN,pbuf);	//释放内存
			OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
			tmr1sta = !tmr1sta;
			LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
		}
	}	
}

//主任务的任务函数
void main_task(void *p_arg)
{
    
    
	u8 key,num;
	OS_ERR err;
	u8 *p;
	while(1)
	{
    
    
		key = KEY_Scan(0);  //扫描按键
		if(key)
		{
    
    
			//发送消息
			OSQPost((OS_Q*		)&KEY_Msg,		
					(void*		)&key,
					(OS_MSG_SIZE)1,
					(OS_OPT		)OS_OPT_POST_FIFO,
					(OS_ERR*	)&err);
		}
		num++;
		if(num%10==0) check_msg_queue(p);//检查DATA_Msg消息队列的容量
		if(num==50)
		{
    
    
			num=0;
			LED0 = ~LED0;
		}
		OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err);   //延时10ms
	}
}

//按键处理任务的任务函数
void Keyprocess_task(void *p_arg)
{
    
    	
	u8 num;
	u8 *key;
	OS_MSG_SIZE size;
	OS_ERR err;
	while(1)
	{
    
    
		//请求消息KEY_Msg
		key=OSQPend((OS_Q*			)&KEY_Msg,   
					(OS_TICK		)0,
                    (OS_OPT			)OS_OPT_PEND_BLOCKING,
                    (OS_MSG_SIZE*	)&size,		
                    (CPU_TS*		)0,
                    (OS_ERR*		)&err);
		switch(*key)
		{
    
    
			case WKUP_PRES:		//KEY_UP控制LED1
				LED1 = ~LED1;
				break;
			case KEY2_PRES:		//KEY2控制蜂鸣器
				BEEP = ~BEEP;
				break;
			case KEY0_PRES:		//KEY0刷新LCD背景
				num++;
				LCD_Fill(126,111,233,313,lcd_discolor[num%14]);
				break;
			case KEY1_PRES:		//KEY1控制定时器1
				tmr1sta = !tmr1sta;
				if(tmr1sta) 
				{
    
    
					OSTmrStart(&tmr1,&err);
					LCD_ShowString(10,150,100,16,16,"TMR1 START!");
				}
				else
				{
    
    
					OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
					LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
				}
				break;
		}
	}
}

//显示消息队列中的消息
void msgdis_task(void *p_arg)
{
    
    
	u8 *p;
	OS_MSG_SIZE size;
	OS_ERR err; 
	while(1)
	{
    
    
		//请求消息
		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);
		myfree(SRAMIN,p);	//释放内存
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
	}
}

おすすめ

転載: blog.csdn.net/qq_37120496/article/details/115279089