当前位置:网站首页>Ucosiii transplantation and use, reference punctual atom

Ucosiii transplantation and use, reference punctual atom

2022-04-23 18:19:00 Things will turn when they reach the extreme 1024

1 task management

1.1 System files

delay

delay_ms Will initiate task scheduling , Minimum initiator delay >5ms, from 5ms Start not using task scheduling

delay_us Do not initiate task scheduling .

Usart The difference between files is that the interrupt service function

void USART1_IRQHandler(void)
{
    
	u8 res;	
#if SYSTEM_SUPPORT_OS // If SYSTEM_SUPPORT_OS It's true , Support is needed OS.
	OSIntEnter();    // Enter interrupt 
#endif
...
#if SYSTEM_SUPPORT_OS // If SYSTEM_SUPPORT_OS It's true , Support is needed OS.
	OSIntExit();  			// Exit interrupt  
#endif
} 

os System delay function

​ //OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); // Time delay 1s

OSTimeDlyHMSM( when , branch , second , millisecond ,OS_OPT_TIME_HMSM_STRICT,&err)

1.2 The basic concept of mission

UCOSIII It's a deprivable multitasking system

A task is a program entity .

UCOSIII The task in consists of three parts : Task stack 、 Task control block and task function .
Task stack : The working environment used to save the task during context switching , Namely STM32 Internal register value of .
Task control block : The task control block is used to record each attribute of the task .
Task function : Task processing code written by the user , It's really working , The general notation is as follows :

The task stack is an array , Task control is a OS_TCB Variable

1.2.1 UCOSII System tasks

UCOSIII The default is 5 A system task :
1、 Idle tasks :UCOSIII The first task created ,UCOSIII Tasks that must be created , This task has UCoSIII Automatically create , There is no need for users to manually create .
2、 Clock beat task : This task must also be created .
3、 Statistical tasks : Optional tasks , Used for statistical CPU Usage and stack usage per task . This task is optional , You Hong 0S_CFG_STAT_TASK_EN Controls whether this task is used .
4、 Timing task : Used to provide timing services to users , It's also an optional task , You Hong 0S_CFG_TVMR_E Controls whether this task is used .
5、 Interrupt service management tasks : Optional tasks , You Hong 0S_CFG_ISR_POST_DEFERRED_EN Controls whether this task is used .

1.2.2 UCOSIII Task status

From the perspective of users ,UCOSIII There are a total of 5 States :
1、 Dormant state : The task is already CPU Of flash It's in , But not yet UCOSIII management .
2、 The ready state : The task control block is assigned to the system , And the task has been registered in the ready form , At this time, the task has the conditions to run , At this time, the status of the task is ready .
3、 Running state : The mission is achieved CPU Right to use , Running .
4、 Waiting state : The running task needs to wait for some time , Or wait for an event , This task enters the waiting state , At this point, the system will CPU The right of use is transferred to other tasks .
5、 Interrupt service status : When sending is interrupted , The currently running task will be suspended ,cPU Instead, execute the interrupt service function , At this time, the task state of the task is called interrupted service state .

1.3 Task stack

The task stack is RAM In accordance with the first in first out principle , It is used to save the running state of the previous task during task switching CPU Register contents .

1.3.1 establish

#define STAR_STK_SIZE 512 // Stack size 512*4=2048 Bytes

CPU_STK STAR_TASK_STK[STAR_STK_SIZE ]; // Define an array of tasks as a stack

CPU_STK yes CPU_INT32U Unsigned integer unsigned int

1.3.2 initialization

When creating a task , You need to start this task first CPU The register value is stored in the task stack first , The mission is achieved CPU The use right is to copy the contents of the task stack into each register and run smoothly , That is, the initialization of the task stack .

Initialization function OSTaskStkInit, This function will not be called by the user ,

from OSTaskCreate() call .

1.3.3 Using stack

OSTaskCreate(...
             (CPU_STK   * )&START_TASK_STK[0],	// Task stack base address 
             (CPU_STK_SIZE)START_STK_SIZE/10,	// Task stack depth limit 
             (CPU_STK_SIZE)START_STK_SIZE,		// Task stack size 
              ...
             (OS_ERR 	* )&err);				// Store the return value when the function is wrong 

1.4 Task control block structure

Task control block is a data structure used to record task related information , Each task should have its own task control block . The task control block is created by the user , The following code creates a task control block for :

0S_TCB StartTaskTCB;// Create a task control block 

0S_TCB As a structure , Describes the task control block , The member variables in the task control block cannot be accessed directly by the user , Even less likely to change them .
0S_TCB As a structure , Some of them use conditional compilation to determine

1.4.1 initialization

Same stack , Is to give the initial value to the structure , Basic it is 0

OSTaskCreate((OS_TCB 	* )&Led0TaskTCB,		
			....
             (OS_ERR 	* )&err);	

1.5 UCOSIII Mission readiness table

1.5.1 priority

The smaller the value, the higher the priority .

The lowest available priority is OS_CFG_PRIO_MAX-1

OS_CFG_PRIO_MAX Is the total number of available tasks , It's defined in os_cfg.h Under the document

1.5.2 In table

UCOSIII The ready table in is composed of 2 Part of it is made up of :
1、 Priority bit mapping table 0SPrioTbl[]: It is used to record which priority has task ready .
2、 Ready task list 0SRdyList[]: Used to record all ready tasks under each priority .

CPU_DATA 0SPrioTbl[OS_PRIO_TBL_SIZE]

0SPrioTbl The data type of is uint 32 position , Each bit corresponds to a priority , When the system has 64 When there are two priorities OS_PRIO_TBL_SIZE=((64-1)/(4*8)+1)=2.

1.6 Task scheduling

1.6.1 Deprivable task scheduling

Task scheduling is to abort the currently running task and execute other tasks .

The deprivation type : When a high priority task is ready , And task scheduling occurs , High priority tasks will be executed .

Task scheduler : Task level scheduler and interrupt level scheduler .

Mission :OSSched(). In the delay function

OSTimeDlyHMSM(0,0,0,200,OS_OPT_TIME_HMSM_STRICT,&err); // Time delay 200ms

interrupt : OSInitExit(). Interrupt level task scheduling is used when introducing external interrupt service functions .

1.6.2 Task scheduling point

1、 Release semaphores or send messages , You can also configure corresponding parameters to avoid task scheduling .
2、 Use the delay function OSTimeDly() perhaps OSTimeDlylMSM().(delay_ms)
3、 The task waiting hasn't happened yet ( Wait for the semaphore , Message queuing, etc ).
4、 Task cancel wait .
5、 Create tasks .
6、 Delete task .
7、 Delete a kernel object .
8、 The task changes its own priority or the priority of other tasks .
9、 The task is executed by calling 0STaskSuspend0 Suspend yourself .
10、 Task uncoupling a pending task .
11、 Exit all nested interrupts .
12、 adopt OSSchedUnlock() Unlock the scheduler .
13、 Task call OSSchedRoundRobinYield) Abandon its execution time slice .
14、 Call... With production OSSched().

1.6.3 The scheduler is locked and unlocked

OSSchedLock() Lock the scheduler

OSSchedUnlock() Unlock

1.6.4 Time slice rotation scheduling

UCOSIII Allow multiple tasks under one priority , Each task can be executed for a specified time ( Time slice ), Then it's the next task , This process is called time slice rotation scheduling , The task can no longer be run after the time slice .

Time slice rotation scheduler : OS_SchedRoundRobin();

1.6.5 Task switching

UCOSIII When you need to switch to another task i, Save the scene of the current task to the stack of the current task , Then restore the new site and perform new tasks .

Task level switching function OSCtxSw().

Interrupt level switching function OSIntCtSw().

1.7 UCOSIII System initialization and startup

1.7.1 initialization

OSInit() Function complete initialization

int main(void)
{
	OS_ERR err;
	CPU_SR_ALLOC();
	Stm32_Clock_Init(9);	// System clock settings 
	delay_init(72);	  		// Delay initialization 
	MY_NVIC_PriorityGroupConfig(2); // Interrupt packet configuration 
	uart_init(72,115200);    // Serial port baud rate setting 
	......
	OSInit(&err);		// initialization UCOSIII
OS_CRITICAL_ENTER();// Enter the critical area 
// Create start task 
OSTaskCreate((OS_TCB 	* )&StartTaskTCB,		// Task control block 
			 (CPU_CHAR	* )"start task", 		// Task name 
             (OS_TASK_PTR )start_task, 			// Task function 
             (void		* )0,					// Parameters passed to the task function 
             (OS_PRIO	  )START_TASK_PRIO,     // Task priority 
             (CPU_STK   * )&START_TASK_STK[0],	// Task stack base address 
             (CPU_STK_SIZE)START_STK_SIZE/10,	// Task stack depth limit 
             (CPU_STK_SIZE)START_STK_SIZE,		// Task stack size 
             (OS_MSG_QTY  )0,					// The maximum number of messages that the task internal message queue can receive , by 0 Prohibit receiving messages when 
             (OS_TICK	  )0,					// The length of the time slice when the time slice rotation is enabled , by 0 Is the default length ,
             (void   	* )0,					// User supplementary storage 
             (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, // Task options 
             (OS_ERR 	* )&err);				// Store the return value when the function is wrong 
OS_CRITICAL_EXIT();	// Exit critical region 	 
OSStart(&err);  // Turn on UCOSIII
while(1);
}

2 Task creation and deletion

2.1 establish

void  OSTaskCreate (OS_TCB        *p_tcb,    // Task control block 
                    CPU_CHAR      *p_name,   // The name of the task 
                    OS_TASK_PTR    p_task,   // Point to the task function 
                    void          *p_arg,    // Optional data area 
                    OS_PRIO        prio,     // Task priority 
                    CPU_STK       *p_stk_base, // Task stack base address 
                    CPU_STK_SIZE   stk_limit,  // Stack depth 
                    CPU_STK_SIZE   stk_size,   // Stack size 
                    OS_MSG_QTY     q_size,     // The length of the built-in message queue 
                    OS_TICK        time_quanta,// The length of the time wheel 
                    void          *p_ext,      // Point to the storage area supplemented by the user 
                    OS_OPT         opt,        // Options   Commonly used two or three options 
   //OS OPT TASK NONE  Indicates that there are no options 
   //OS_OPT_TASK_STK_CHK  Specifies whether to allow detection of the task's stack 
   //OSOPT_TASK_STK_CLR  Specifies whether to clear the stack of the task 
   //OS_OPT_TASK_SAVE_F P Specifies whether to store floating-point registers ,CPU Need to have floating-point operation hardware and special code to save floating-point registers .
                    OS_ERR        *p_err)     // Save the failure value caused by the creation task failure 

Register version template :

Macro definition :

// Task priority 
#define START_TASK_PRIO 3
// Task stack size 
#define START_STK_SIZE 128
// Task control block 
OS_TCB StartTaskTCB;
// Task stack 
CPU_STK START_TASK_STK[START_STK_SIZE];
// Task function 
void start_task(void *p_arg);

// Task priority 
#define TASK1_TASK_PRIO 5
// Task stack size 
#define TASK1_STK_SIZE 128
// Task control block 
OS_TCB Task1TaskTCB;
// Task stack 
CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE];
// Task function 
void task1_task(void *p_arg);
// Task priority 
#define TASK2_TASK_PRIO 6
// Task stack size 
#define TASK2_STK_SIZE 128
// Task control block 
OS_TCB Task2TaskTCB;
// Task stack 
CPU_STK TASK2_TASK_STK[START_STK_SIZE];
// Task function 
void task2_task(void *p_arg);

The main function :

/
int main(void)
{
    
	OS_ERR err;
	CPU_SR_ALLOC();
	Stm32_Clock_Init(9);	// System clock settings 
	delay_init(72);
	MY_NVIC_PriorityGroupConfig(2);
	/
	uart_init(72,115200);
	LED_Init();
	/
	OSInit(&err);  //Ucos initialization 
	OS_CRITICAL_ENTER();  // Enter the critical area 
  OSTaskCreate((OS_TCB*			)&StartTaskTCB,    // Task control block 
              (CPU_CHAR*		)"start_task",    // The name of the task 
              (OS_TASK_PTR	)start_task,   // Task function 
              (void *				)0,    // When declaring a task name void *p_arg
              (OS_PRIO			)START_TASK_PRIO,  // Task priority 
              (CPU_STK *		)&START_TASK_STK[0],   // The base address of the task stack 
              (CPU_STK_SIZE	)START_STK_SIZE/10,  // Stack depth 
              (CPU_STK_SIZE	)START_STK_SIZE,  // Task stack size 
              (OS_MSG_QTY		)0,// Task built-in message queue 
              (OS_TICK			)0,// The length of the time slice when the time slice rotation is enabled , by 0 Is the default length ,
              (void*				)0,// User supplementary storage 
              (OS_OPT				)OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, // Task options 
              (OS_ERR*			)&err);
			
	OS_CRITICAL_EXIT();// Exit critical region 
	OSStart(&err);
	while(1);
}

Start task :

///
// Task function 
void start_task(void *p_arg)
{
    
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg=p_arg;// eliminate p_arg Warning not used 
		CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
   OSStatTaskCPUUsageInit(&err);  	// Statistical tasks  
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN // If enabled, measure the interrupt off time 
    CPU_IntDisMeasMaxCurReset();	
#endif
#if OS_CFG_SCHED_ROUND_ROBIN_EN // When using time slice rotation 
	 // Enable the time slice rotation scheduling function , The length of the time slice is 1 A system clock beat , Both 1*5=5ms
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif 
	OS_CRITICAL_ENTER();	// Enter the critical area 
			printf(" Enter the critical area \r\n");		
	  OSTaskCreate((OS_TCB*			)&Task1TaskTCB,    // Task control block 
              (CPU_CHAR*		)"task1_task",    // The name of the task 
              (OS_TASK_PTR	)task1_task,   // Task function 
              (void *				)0,    // When declaring a task name void *p_arg
              (OS_PRIO			)TASK1_TASK_PRIO,  // Task priority 
              (CPU_STK *		)&TASK1_TASK_STK[0],   // The base address of the task stack 
              (CPU_STK_SIZE	)TASK1_STK_SIZE/10,  // Stack depth 
              (CPU_STK_SIZE	)TASK1_STK_SIZE,  // Task stack size 
              (OS_MSG_QTY		)0,// Task built-in message queue 
              (OS_TICK			)0,// Time programming 
              (void*				)0,//
              (OS_OPT				)OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, // Task options 
              (OS_ERR*			)&err);						
	  OSTaskCreate((OS_TCB*			)&Task2TaskTCB,    // Task control block 
              (CPU_CHAR*		)"task2_task",    // The name of the task 
              (OS_TASK_PTR	)task2_task,   // Task function 
              (void *				)0,    // When declaring a task name void *p_arg
              (OS_PRIO			)TASK2_TASK_PRIO,  // Task priority 
              (CPU_STK *		)&TASK2_TASK_STK[0],   // The base address of the task stack 
              (CPU_STK_SIZE	)TASK2_STK_SIZE/10,  // Stack depth 
              (CPU_STK_SIZE	)TASK2_STK_SIZE,  // Task stack size 
              (OS_MSG_QTY		)0,// Task built-in message queue 
              (OS_TICK			)0,// Time programming 
              (void*				)0,//
              (OS_OPT				)OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, // Task options 
              (OS_ERR*			)&err);					
	OS_CRITICAL_EXIT();// Exit critical region 
    printf(" Creation completed \n");
	OSTaskDel((OS_TCB*)0,&err);	// Delete start_task The task itself 
}

Other tasks :

void task1_task(void *p_arg)
{
    
	u8 task1_num=0;
	OS_ERR err;
	p_arg = p_arg;

	while(1)
	{
    
		LED_G_T;
		task1_num++;
		printf(" Mission 1 Run the %d Time \n",task1_num);
		if(task1_num==5)
		{
    
			OSTaskDel((OS_TCB *)&Task2TaskTCB,&err);
			printf(" Mission 1 Task deleted 2-------------\n");
		}
		OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err); // Time delay 500ms
	}
}
void task2_task(void *p_arg)
{
    
	u8 task2_num=0;
	OS_ERR err;
	p_arg = p_arg;

		while(1)
	{
    
		LED_R_T;
		task2_num++;
		
		printf(" Mission 2 function D%d Time \n",task2_num);
		
		OSTimeDlyHMSM(0,0,0,200,OS_OPT_TIME_HMSM_STRICT,&err); // Time delay 500ms
	}
}

2.2 Task delete

void OSTaskDel(OS_TCB *p_tcb    // Task control block 
               OS_ERR *p_err);  // error message 

OSTaskDel((OS_TCB*)&Task2_TaskTCB,&err);

Because resources may be shared between tasks , So try not to delete tasks .

3 Task suspend and resume

3.1 Task suspended

void OSTaskSuspend( OS_TCB *p_tcb,
OS_ERR *p_err);

3.2 Mission recovery

void OSTaskResume(OS_TCB *p_tcb,

​ OS_ERR *p_err);

Task program instance

void task1_task(void *p_arg)
{
    
	u8 task1_num=0;
	OS_ERR err;
	p_arg = p_arg;
	while(1)
	{
    
		LED_G_T;
		task1_num++;
		printf(" Mission 1 Run the %d Time \n",task1_num);
		if(task1_num==5)
		{
    
			OSTaskSuspend((OS_TCB *)&Task2TaskTCB,&err);
			printf(" Mission 1 Task suspended 2-------------\n");
		}
		if(task1_num==30)
		{
    
			OSTaskResume((OS_TCB *)&Task2TaskTCB,&err);
			printf(" Mission 1 The mission was restored 2-------------\n");
		}		
		OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err); // Time delay 500ms
	}
}

4 Time slice rotation scheduling

1. Macro definition CPU_CFG_INT_DIS_MEAS_EN Set to 1

2. function CPU_IntDisMeasMaxCurReset(); Put it in the start task , Before opening all tasks

3. Open the function that needs time slice rotation scheduling to allocate time slice in the task function , The length of each task time slice can be different , But you need to pay attention to the length of time each task needs to run , Don't let the set time slice length be less than the running time , The previous task has not been completed during time slice scheduling , Will be forcibly interrupted , Execute the new function , When the time slice turns back to the first function , Will continue the last unfinished program .

Set time slice :

  OSTaskCreate(...
              (OS_TICK			)2,// The length of the time slice when the time slice rotation is enabled , by 0 Is the default length ,2=10ms
              ...
              (OS_ERR*			)&err);

Program output instance : Mission 1 Print

123456789 Time **
123456789 Time
123456789 Time
123456789 Time –

wait for 1s,

Mission 2 Print

ABCDEFG Time **
ABCDEFG Time
ABCDEFG Time
ABCDEFG Time –

wait for 1s

When the time slice setting is normal : Each interval 1s

123456789 Time **
123456789 Time
123456789 Time
123456789 Time –
ABCDEFG Time **
ABCDEFG Time
ABCDEFG Time
ABCDEFG Time –

The time slice setting is too short

123456789 Time **
123456789 Time
1ABCDEFG Time **
ABCDEFG Time
ABCDEFG Time
ABCDEFG Time –
23456789 Time
123456789 Time –

5 Internal system tasks

5.1 Idle tasks

The first task created , You have to create , The lowest priority , The total number is 64 Time , The priority for 63,OS_CFG_PRIO_MAX-1, Idle tasks cannot enter the waiting state .

There are parameters of statistical tasks , The more idle tasks are executed , The larger the parameters of the statistical task , It means that the more idle the system is .

5.2 Clock beat task

Used to track task delay and task waiting timeout , Task function OS_TickTask. The system must contain , Task priorities are defined using macros OS_CFG_TICK_TASK_PRIO Definition , Set the priority to higher , Set to 1 ;

5.3 Statistical tasks

Used for statistical CPU Usage rate , It's not necessary .

1. Macro definition OS_CFG_STAT_TASK_EN Set up 1 Turn on

2. stay main The only application function in the function uses , namely start_task in

#if OS_CFG_STAT_TASK_EN > 0u
   OSStatTaskCPUUsageInit(&err);  	// Statistical tasks  
#endif

3. Priority macro definition OS_CFG_STAT_TASK_PRIO , It is generally set to be only one level higher than idle tasks 64 Set to... When there are two tasks 62

OS_CFG_PRIO_MAX-2 , The penultimate priority .

4. You can view the usage of the task stack OSTaskStkChk

5. see CPU Usage rate OSStatTaskCPUUsage CPU The utilization rate of is calculated with a 0~10000 The integer between represents ( Corresponding 0.00~100.00%),

5.4 Timing task

1. Software timer , Optional

2. Macro definition OS_CFG_TMR_EN ,OSInit() The function... Will be called OS_TmeInit() To create a scheduled task

3. Priority passes OS_CFG_TMR_TASK_PRIO Definition , The default setting is 2;

5.5 Interrupt service management tasks

1. Enable macro definition OS_CFG_ISR_POST_DEFERRED_EN

2. priority : For ever 0, Non modifiable

3. Working mechanism : Remove some functions in the interrupt from the interrupt , The data and destination are stored in a queue .

5.6 Hook function

Hook functions are generally used to extend other functions ( Mission ) Functional , Hook functions are as follows :

​ 1、OSIdleTaskHook(), Idle tasks call this function , Can be used to make CPU Enter low power mode

​ 2、OSInitHook(), System initialization function OSInit() Call this function .

​ 3、OSStatTaskHook(), This function is called every second in the statistics task , This function allows you to add your own application function to the statistical task .

​ 4、OSTaskCreateHook(), Hook function created by task .

​ 5、OSTaskDelHook(), Task delete hook function .

​ 6、OSTaskReturnHook(), Hook function called when the task returns unexpectedly , For example, delete a task

​ 7、OSTaskSwHook(), Hook function called during task switching .

​ 8、OSTimeTickHook(), The hook function called by the tick timer .

Hook function will point to a function , If you need to change the hook function, change the function pointed to

6 Interruption and time management

6.1 interrupt

interrupt : Aborts the current task at the request of an internal or external asynchronous event , The process of handling the tasks required by asynchronous events is called interrupt .

Interrupt service function :

void USART1_IRQHandler(void)
{
    
    OSIntEnter();
    // Interrupt service routine 
    OSIntExit();
}

void  OSIntEnter (void)
{
    
      if (OSRunning != OS_STATE_OS_RUNNING) {
    
	  return
      }
      if (OSIntNestingCtr >= (OS_NESTING_CTR)250u) {
    
            return; 
      }
     OSIntNestingCtr++;
}
OSIntNestingCtr To record the number of interrupt nesting ,UCOSIII Most support 250 Level interrupt nesting . Call the function when exiting the interrupt service function OSIntExit().

6.2 Critical segment code protection

1. Means that a piece of code must run completely , Not interruptible in the middle .

2. When macro OS_CFG_ISR_POST_DEFERRED_EN by 0 when ,UCOSIII Use off interrupt to protect critical segment code ,

​ When set to 1 It will lock the scheduler to protect the critical code .

3. Enter the macro of critical section code :OS_CRITICAL_ENTER()

Exit the macro of critical code :OS_CRITICAL_EXIT and OS_CRITICAL_EXIT_NO_SCHED().

OS_CRITICAL_EXIT There is task switching

OS_CRITICAL_EXIT_NO_SCHED No task switching

4. If critical code area protection is required , Function must be added CPU_SR_ALLOC(); .

6.3 time management

6.3.1 Task delay

UCOSIII The task of is infinite loop and is a preemptive kernel , Each task must call the task switch in the appropriate position .

The time delay function :OSTimeDly() and OSTimeDlyHMSM()

OSTimeDly() There are three working modes : The relative pattern 、 Periodic mode and absolute mode .

OSTimeDlyHMSM() Only relative mode

OSTimeDly( Parameters 1 Number of time slices , Parameters 2 Working mode , Parameters 3 Error code )

The relative pattern :OS_OPT_TIME_DLY When the system load is heavy, the delay may be less than one beat , Even sometimes there are many beats missing , In cycle
In mode , The task may still be postponed , But it will always be as expected “ Match the value ” Sync . therefore , Recommended “ Zhou
Period mode ” To realize the periodic delay of long-time operation

Cycle mode :OS_OPT_TIME_PERIODIC

Absolute mode :OS_OPT_TIME_MATCH It can be used to perform specific actions at a specified time after power on , For example, it can be stipulated that , Access to electricity N Seconds later
Turn off a peripheral

void OSTimeDlyHMSM (CPU_INT16U hours, // Number of hours to delay 
                    CPU_INT16U minutes, // Number of minutes to delay 
                    CPU_INT16U seconds, // Number of seconds to delay 
                    CPU_INT32U milli, // Number of milliseconds to delay 
                    OS_OPT opt, // Options 
                    OS_ERR *p_err)

comparison OSTimeDly() Function has two more options OS_OPT_TIME_HMSM_STRICT and OS_OPT_TIME_HMSM_NON_STRICT, The other four options are the same .

Use OS_OPT_TIME_HMSM_STRICT Option will check the delay parameter ,hours The scope of should be 0~99, minutes The scope of should be 0~59, seconds For the range of 0~59,milli For the range of 0~999.

Use OS_OPT_TIME_HMSM_NON_STRICT If it's an option , hours For the range of 0~999,<minutes For the range of 0~9999, seconds For the range of 0~65535, mili For the range of 0~4294967259.

7 Software timer

7.1 brief introduction

The essence is to decrement the counter , Reduced to 0 Can start some kind of action , The action content is in the callback function .

The quantity can be any .

The resolution consists of a macro OS_CFG_TMR_TASK_RATE_HZ, Unit is HZ, The default is 100Hz,10ms.

Be careful : Be sure to avoid using blocking calls in callback functions or functions that can block or delete timer tasks

Macro definition enables OS_CFG_TMR_EN 1u

Callback function :

A(&B){} B(){}, be B be called A Callback function for .B The function is passed as a pointer to the function A

The callback function is not directly called by the implementation method of the function , It's called by another party when a particular event or condition occurs , Used to respond to the event or condition .

7.2 function

Function name effect
OSTmrCreate() Create a timer and set the operation mode
OSTmrDel() Delete timer
OSTmrRemainGet() Get the remaining time of the timer
OSTmrStart() Start timer count
OSTmrStateGet() Get the current timer status
OSTmrStop() Stop counter countdown

Create timer

void  OSTmrCreate (OS_TMR               *p_tmr,// Pointer to timer , macro  OS_TMR  It's a structure  
                   CPU_CHAR             *p_name,// Timer name  
                   OS_TICK               dly,// Delay value of initialization timer  
                   OS_TICK               period,// Repetition period 
                   OS_OPT                opt,/// Timer run options  
                                             //OS_OPT_TMR_ONE_SHOT   Single timer 
                                             //OS_OPT_TMR_PERIODIC   Cycle timer  
                   OS_TMR_CALLBACK_PTR   p_callback,// Point to the name of the callback function . 
                   void                 *p_callback_arg,// The parameters of the callback function . 
                   OS_ERR               *p_err)// The error code returned after calling this function  

OS_TMR 	tmr1;		// Timer 1
void tmr1_callback(void *p_tmr, void *p_arg); 	// Timer 1 Callback function 
	// Create timer 1
	OSTmrCreate((OS_TMR		*)&tmr1,		// Timer 1
                (CPU_CHAR	*)"tmr1",		// The name of the timer 
                (OS_TICK	 )200,			//200*10=2000ms    dly
                (OS_TICK	 )50,          //50*10=500ms
                (OS_OPT		 )OS_OPT_TMR_PERIODIC, // Cycle mode 
                (OS_TMR_CALLBACK_PTR)tmr1_callback,// Timer 1 Callback function 
                (void	    *)0,			// Parameter is 0
                (OS_ERR	    *)&err);		// Error code returned 

Stop register

CPU_BOOLEAN  OSTmrStop (OS_TMR  *p_tmr,   // Timer 
                        OS_OPT   opt,// Options 
                        //OS_OPT_TMR_NONE  Direct stop , No operation 
                        //OS_OPT_TMR_CALLBACK  After stopping, call the callback function again 
                        //OS_OPT_TMR_CALLBACK_ARG  Give the callback a new parameter 
                        void    *p_callback_arg,
                        OS_ERR  *p_err)    // error 
///
    OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err);

Single timer Create timer , function OSTmrStart() Then start timing , When the timing is over, it remains 0,OSTmrStart() Each call will cause the timer value to return dly.

Cycle timer Run after timer is created OSTmrStart() Then start timing , Every time I arrive 0 The post timer value changes to period

The cycle timer has an initialization delay (dly ), In the cycle timer dly Only valid for the first cycle .

technological process :

1. Create timer and callback functions :

OS_TMR 	tmr1;		// Timer 1
void tmr1_callback(void *p_tmr, void *p_arg); 	// Timer 1 Callback function 

void tmr1_callback(void *p_tmr, void *p_arg) 	// Timer 1 Callback function 
{
    
	OS_ERR err;
	static u8 tmr1_num=0;
	printf(" Timer 1 function %d Time \r\n",tmr1_num);
	tmr1_num++;		// Timer 1 Number of executions plus 1
}

2. Create timer , This is a task

void start_task(void *p_arg)
{
    
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg=p_arg;// eliminate p_arg Warning not used 
		CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
   OSStatTaskCPUUsageInit(&err);  	// Statistical tasks  
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN // If enabled, measure the interrupt off time 
    CPU_IntDisMeasMaxCurReset();	
#endif
#if OS_CFG_SCHED_ROUND_ROBIN_EN // When using time slice rotation 
	 // Enable the time slice rotation scheduling function , The length of the time slice is 1 A system clock beat , Both 1*5=5ms
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif 
	OS_CRITICAL_ENTER();	// Enter the critical area 
...
	// Create timer 1
	OSTmrCreate((OS_TMR		*)&tmr1,		// Timer 1
                (CPU_CHAR	*)"tmr1",		// The name of the timer 
                (OS_TICK	 )200,			//200*10=2000ms dly
                (OS_TICK	 )50,          //50*10=500ms
                (OS_OPT		 )OS_OPT_TMR_PERIODIC, // Cycle mode 
                (OS_TMR_CALLBACK_PTR)tmr1_callback,// Timer 1 Callback function 
                (void	    *)0,			// Parameter is 0
                (OS_ERR	    *)&err);		// Error code returned 
...
		OS_CRITICAL_EXIT();// Exit critical region 
	OSTaskDel((OS_TCB*)0,&err);	// Delete start_task The task itself 
}

3. Start timer

OSTmrStart(&tmr1,&err);	// Turn on timer 

4. off timer

OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err);

8 Semaphores and mutually exclusive semaphores

8.1 Introduction to semaphores

Semaphores are like a locking mechanism , The code must obtain the corresponding key to continue execution , The task waits until the locked code segment is executed .

Semaphores are used to control the protection of shared resources , Now it is basically used for task synchronization .

There is supermarket time to wait for semaphores , Set to 0 Then wait all the time , After other values timeout, the task enters the ready state .

classification : Binary semaphores and counting semaphores

The binary semaphore can only take 0 and 1 Two values , The range of counter semaphores is defined by macros OS_SEM_CTR decision ,8 position :0255;16 position :065535;32 position :0~4294967295.OS_SEM_CTR Default 32 position . Binary signals are used for resources that can only be used by one task at a time .

8.2 Semaphore function

OS_SEM XX Define semaphore variables

OSSemCreate() Create semaphores

OS_SEM_CTR OSSemPost() Release or send out a semaphore

OS_SEM_CTR OSSemPend () Wait for the semaphore

OS_OBJ_QTY OSSemPendAbort() Cancel waiting

OS_OBJ_QTY OSSemDel() Delete semaphores

void OSSemSet() Force the setting of a semaphore value

/--------------------------------------OSSemCreate ------------------------------------------------/

Detailed explanation

void OSSemCreate (OS_SEM *p_sem, // Semaphore
CPU_CHAR *p_name, // Semaphore name
OS_SEM_CTR cnt, // Initial value of semaphore
OS_ERR *p_err); // error

OS_OBJ_QTY OSSemDel (OS_SEM *p_sem, // Semaphore
OS_OPT opt, // Options
OS_ERR *p_err); // error

​ Options :OS_OPT_DEL_NO_PEND When there is no task request semaphore

​ OS_OPT_DEL_ALWAYS Delete... Unconditionally

/------------------------------------OSSemPend -----------------------------------------------------/

OS_SEM_CTR OSSemPend (OS_SEM *p_sem, // Semaphore
OS_TICK timeout, // Timeout time ( The beat of the clock )
OS_OPT opt, // Options
CPU_TS *p_ts, // Time stamp Write 0 Identification does not require a timestamp
OS_ERR *p_err) // error

​ Options : OS_OPT_PEND_BLOCKING // When the semaphore is invalid, the task hangs

​ OS_OPT_PEND_NON_BLOCKING // When the semaphore is invalid, the task returns directly

/--------------------------------------OSSemPendAbort -------------------------------------------/

OS_OBJ_QTY OSSemPendAbort (OS_SEM *p_sem, // Semaphore
OS_OPT opt, // Options
OS_ERR *p_err) // error

​ Options :OS_OPT_PEND_ABORT_1 // Only the task waiting for the highest priority of the semaphore is terminated

​ OS_OPT_PEND_ABORT_ALL // Terminate all tasks waiting for the semaphore

​ OS_OPT_POST_NO_SCHED // Prohibit the execution of task scheduling within this function

/--------------------------------------OSSemPost -------------------------------------------/

OS_SEM_CTR OSSemPost (OS_SEM *p_sem,// Semaphore
OS_OPT opt, // Options
OS_ERR *p_err) // error

​ Options :OS_OPT_POST_1 // It is only sent to the task waiting for the highest priority of the semaphore

​ OS_OPT_POST_ALL // Sent to all tasks waiting for the semaphore

​ OS_OPT_POST_NO_SCHED // Prohibit the execution of task scheduling within this function

Example :

1. Create semaphore variables

OS_SEM MY_SEM;

Create semaphore in start task

	OSSemCreate((OS_SEM*    )&MY_SEM,       // Semaphore 
           (CPU_CHAR*   )"MY_SEM",   // Semaphore name 
           (OS_SEM_CTR  )1,           // Initial value of semaphore 
           (OS_ERR*     )&err);         // error 

Wait for the semaphore in the task and release the semaphore

void task2_task(void *p_arg)
{
    
	OS_ERR err;
    ...
	while(1)
	{
    
		OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);// Wait for the semaphore 
		...
		OSSemPost(&MY_SEM,OS_OPT_POST_1,&err);   // Release semaphore 
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); // Time delay 1s 
	}
}

8.3 Mutex semaphore

The priority reversal phenomenon in the deprivable kernel :

The lowest priority task L The semaphore is obtained during operation and , The highest priority task H deprive , Run to H Switch back to task while waiting for semaphore L, Run unfinished, slightly advanced tasks M Get run ,M After running, return to the task L, Value task H Get the signal quantity before running the task H, Mission H From requesting semaphores to getting semaphores, there are tasks M Operation takes precedence over tasks H, During this time, there has been a priority reversal .

H ------- ---------------

M --------

L ------- — —

Use mutually exclusive semaphores to solve the priority inversion problem , The solution is to raise the priority of the lowest running task to the level consistent with the priority of the waiting semaphore when waiting for the semaphore at the highest level , Prevent lower priority from interrupting running tasks . The switching time is at the highest H The moment when you start waiting for the semaphore .

H ------- ---------------

M --------

L ------- ------

8.4 Mutually exclusive semaphore function

The parameters are the same as those of ordinary semaphores

void OSMutexCreate (OS_MUTEX *p_mutex,
CPU_CHAR *p_name,
OS_ERR *p_err);

OS_OBJ_QTY OSMutexDel (OS_MUTEX *p_mutex,
OS_OPT opt,
OS_ERR *p_err);

void OSMutexPend (OS_MUTEX *p_mutex,
OS_TICK timeout,
OS_OPT opt,
CPU_TS *p_ts,
OS_ERR *p_err);

OS_OBJ_QTY OSMutexPendAbort (OS_MUTEX *p_mutex,
OS_OPT opt,
OS_ERR *p_err);

void OSMutexPost (OS_MUTEX *p_mutex,
OS_OPT opt,
OS_ERR *p_err);

Example : Same as semaphore , Pay attention to the substitution function , In addition, parameter initialization is not required to create mutually exclusive semaphores .

Note that low priority tasks using mutex semaphores should not run too long .

8.5 Task embedded semaphore

Each task has its own embedded semaphore , In a task, you can only wait for the semaphore of this task, but you can't wait for the semaphore of other tasks , There is no limit to the number of task semaphores released .

function :

OS_SEM_CTR OSTaskSemPend (OS_TICK timeout, // Timeout time
OS_OPT opt,// Options
CPU_TS *p_ts,// Time stamp
OS_ERR *p_err);// error

​ Options : OS_OPT_PEND_BLOCKING // When the semaphore is invalid, the task hangs

​ OS_OPT_PEND_NON_BLOCKING // When the semaphore is invalid, the task returns directly

CPU_BOOLEAN OSTaskSemPendAbort (OS_TCB *p_tcb,// Task control block
OS_OPT opt, // Options
OS_ERR *p_err);// error
Options : OS_OPT_POST_NONE // Unconditionally cancel

​ OS_OPT_POST_NO_SCHED // No request task

OS_SEM_CTR OSTaskSemPost (OS_TCB *p_tcb,// Task control block
OS_OPT opt, // Options
OS_ERR *p_err);// error

​ Options : OS_OPT_POST_NONE // Unconditional

​ OS_OPT_POST_NO_SCHED // No request task

OS_SEM_CTR OSTaskSemSet (OS_TCB *p_tcb,// Task control block
OS_SEM_CTR cnt,
OS_ERR *p_err);

example :

There is no need to create and variables when using task embedded semaphores , Can be used directly

OSTaskSemPend() Wait for the semaphore // You can only wait for your own semaphore

void task1_task(void *p_arg)
{
    
	OS_ERR err;
	while(1)
	{
    
		OSTaskSemPend(0,OS_OPT_PEND_BLOCKING,0,&err);// You can only wait for your own semaphore 
		printf(" Task a \r\n");
	}
}

OSTaskSemPendAbort() Cancel waiting task semaphore

OSTaskSemPost() Release task semaphore // Except that parameters are the same as normal usage

void task2_task(void *p_arg)
{
    		
	OS_ERR err;
	while(1)
	{
    
		if(KEY_Scan()==3)
		{
    
			printf(" Task 2 \r\n");
			OSTaskSemPost(&Task1TaskTCB,OS_OPT_POST_NONE,&err);
		}
	}
}

OSTaskSemSet() Force the task semaphore count

OSTaskSemSet(&Task1TaskTCB,10,&err);// The set value 

9 Message queue

struct os_q {
OS_OBJ_TYPE Type;
CPU_CHAR *NamePtr;
OS_PEND_LIST PendList;
OS_Q *DbgPrevPtr;
OS_Q *DbgNextPtr;
CPU_CHAR *DbgNamePtr;
OS_MSG_Q MsgQ;
};

function :

Function name effect
OSQCreate() Create a message queue
OSQDel() Delete a message queue
OSQFlush() Empty message queue
OSQPend() Waiting for news
OSQPendAbort() Cancel waiting for message
OSQPost() Publish a message to the message queue

1.void OSQCreate (OS_Q *p_q,// Define a message queue variable
CPU_CHAR *p_name,// name
OS_MSG_QTY max_qty,// Message queue size
OS_ERR *p_err); // Error code

2.OS_OBJ_QTY OSQDel (OS_Q *p_q, // Message queue variables
OS_OPT opt, // Options
OS_ERR *p_err); // Error code

​ Options :OS_OPT_DEL_NO_PEND // No waiting tasks

​ OS_OPT_DEL_ALWAYS // Delete directly

3.OS_MSG_QTY OSQFlush (OS_Q *p_q, // Message queue variables
OS_ERR *p_err);// Error code

4.void *OSQPend (OS_Q *p_q,// Message queue variables
OS_TICK timeout,// Timeout time
OS_OPT opt,// Options
OS_MSG_SIZE *p_msg_size,// What is the size of the received message
CPU_TS *p_ts,// Time stamp
OS_ERR *p_err);// Error code

​ Options : OS_OPT_PEND_BLOCKING // When the semaphore is invalid, the task hangs

​ OS_OPT_PEND_NON_BLOCKING // When the semaphore is invalid, the task returns directly

5.OS_OBJ_QTY OSQPendAbort (OS_Q *p_q,// Message queue variables
OS_OPT opt,// Options
OS_ERR *p_err);// Error code

​ Options :OS_OPT_PEND_ABORT_1 // Only the task waiting for the highest priority of the semaphore is terminated

​ OS_OPT_PEND_ABORT_ALL // Terminate all tasks waiting for the semaphore

​ OS_OPT_POST_NO_SCHED // Prohibit the execution of task scheduling within this function

6.void OSQPost (OS_Q *p_q,// Message queue variables
void *p_void,// The message content
OS_MSG_SIZE msg_size,// The size of the message sent ( byte )
OS_OPT opt, // Options , Use a combination of
OS_ERR *p_err);// Error code

​ Options :OS_OPT_POST_ALL // Send the message to all tasks waiting for the message queue

​ OS_OPT_POST_FIFO // Save the message at the end of the message queue

​ OS_OPT_POST_LIFO // Save the message at the beginning of the message queue

​ OS_OPT_POST_NO_SCHED // No task switching

9.1 Message queuing application instance

1. Create variables

OS_Q Q_DATA; // Data queue

#define Q_DATA_MAX 5 // Data queue length

2. Create a message queue

// Start the task 
OSQCreate    ((OS_Q*     )&Q_DATA,// Define a message queue variable 
            (CPU_CHAR* )"Q_DATA",// name 
            (OS_MSG_QTY)Q_DATA_MAX,// Message queue size 
            (OS_ERR*   )&err);   // Error code  

3. Sending queue

	static char Uchars[]="msg_num=0\r\n";
	sprintf(Uchars,"msg_num=%d\r\n",msg_num);
	msg_num++;
	OSQPost((OS_Q*		)&Q_DATA,		
				(void*		)Uchars,
				(OS_MSG_SIZE)12,
				(OS_OPT		)OS_OPT_POST_FIFO,
				(OS_ERR*	)&err);
	if(err!=OS_ERR_NONE)// It's possible that the message queue is full 
		{
    
			OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); // Stop timer 1  Here let this program not run again 
			printf("TMR1 STOP!\r\n");
		}

4. Request message queue

		u8 *p;
	OS_MSG_SIZE size;
		OS_ERR err;
	while(1)
	{
		p=OSQPend((OS_Q*		)&Q_DATA,   
             (OS_TICK		)0,
             (OS_OPT		)OS_OPT_PEND_BLOCKING,
             (OS_MSG_SIZE*	)&size,	
             (CPU_TS*		)0,
             (OS_ERR*		)&err);
		printf(" news :%s",p);
		printf(" Message queue remaining %d, Message queue length :%d\r\n",Q_DATA.MsgQ.NbrEntriesSize-Q_DATA.MsgQ.NbrEntries,Q_DATA.MsgQ.NbrEntriesSize);
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); // Time delay  
	}

9.2 Task built-in message queue

Enable macro definition OS_CFG_TASK_Q_EN Can make

function

Function name effect
OSTaskQPend() Waiting for news
OSTaskQPendAbort() Cancel waiting for message
OSTaskQPost() Post a message to the task
OSTaskQFlush() Clear the message queue of the task

example :

1. Define the message queue size

#define TASK_Q_NUM 4 // The length of the built-in message queue of the sending task

2. Length of message queue added when creating a task

	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,		// Mission Msgdis_task You need to use a built-in message queue , The message queue length is 4 
                 (OS_TICK	  )0,  					
                 (void   	* )0,					
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                 (OS_ERR 	* )&err);	

3. Send message queue

No longer send to the queue , Send... To the task .

	u8 *pbuf;	
	OSTaskQPost((OS_TCB*	)&Msgdis_TaskTCB,	// To task Msgdis Send a message 
                (void*		)pbuf,
                (OS_MSG_SIZE)10,
                (OS_OPT		)OS_OPT_POST_FIFO,
				(OS_ERR*	)&err);

4. Wait for message queue

	u8 *p;
	OS_MSG_SIZE size;
// The request message 
	p=OSTaskQPend((OS_TICK		)0,    // Self built message queue 
                  (OS_OPT		)OS_OPT_PEND_BLOCKING,   // Options , No message pending 
                  (OS_MSG_SIZE*	)&size,// How many bytes have been received 
                  (CPU_TS*		)0,   // Time stamp 
                  (OS_ERR*      )&err );// error 

5. Message queue with memory management

void USART1_IDLE_task(void *p_arg)
{
    
		OS_ERR err;
		u8 *pbuf;
	OS_MSG_SIZE size;
	while(1)
	{
    	
		pbuf = mymalloc(SRAMIN,USART1_RX_STA);	// apply   byte 
		// The request message 
	  pbuf=OSTaskQPend((OS_TICK		)0,   // Self built message queue 
                  (OS_OPT		)OS_OPT_PEND_BLOCKING,  // Options , No message pending 
                  (OS_MSG_SIZE*	)&size,// How many bytes have been received 
                  (CPU_TS*		)0,// Time stamp 
                  (OS_ERR*      )&err );// error 
		USART1_Send_Len(pbuf,USART1_RX_STA);
		printf("size%d",size);
		myfree(SRAMIN,pbuf);	// Free memory 
		OSTimeDlyHMSM(0,0,0,20,OS_OPT_TIME_HMSM_STRICT,&err); // Time delay  
	}
}

10 Event flag set

​ Sometimes a task needs to be synchronized with multiple events , At this time, you need to use the event flag group . There are two synchronization mechanisms between event flag groups and tasks :“ or ” Synchronization and “ And ” Sync .

​ “ or ” Sync : Waiting for multiple events , Any event happens , Tasks are synchronized , This is called “ or ” Sync .

​ “ And ” Sync : When all events occur, the task is synchronized , This mechanism is called synchronization “ And ” Sync .

​ stay UCOSIII The event flag group in is OS_FLAG_GRP, If you need to use the event flag group, you need to set the macro OS_CFG_FLAG_EN Set up 1,

function :

Function name effect
OSFlagCreate() Create event flag group
OSFlagDel() Delete event flag group
OSFlagPend() Wait for event flag group
OSFlagPendAbort() Cancel waiting event flag
OSFlagPendGetFlagsRdy() Get the event flag that makes the task ready
OSFlagPost() Issue flag to event flag group

Function details :

1.void OSFlagCreate (OS_FLAG_GRP *p_grp,// Point to the event flag group
CPU_CHAR *p_name,// The name of the event flag group
OS_FLAGS flags,// Define the initial value of the event flag group
OS_ERR *p_err);// Error code

2.OS_FLAGS OSFlagPend (OS_FLAG_GRP *p_grp,// Point to the event flag group
OS_FLAGS flags,//bit Sequence , The task needs to wait for which bit of the event flag group will put the corresponding position of this sequence 1, bit0 and bit1 when ( Whether it's waiting to be set or cleared ), flag Yes, the value is 0X03.
OS_TICK timeout,// Timeout time ( Clock beats )
OS_OPT opt, Determine the conditions for the task to wait
CPU_TS *p_ts,// Time stamp
OS_ERR *p_err);// Error code

The conditions for waiting :

OS_OPT_PEND_FLAG_CLR_ALL        // Wait for all bits of the event flag group to be cleared 
OS_OPT_PEND_FLAG_CLR_ANY       // Wait for any flag in the event flag group to be cleared 
OS_OPT_PEND_FLAG_SET_ALL         // Wait for all position bits in the event flag group 
OS_OPT_PEND_FLAG_SET_ANY        // Wait for any flag in the event flag group to be set 
 When calling the above four options, you can also match the following three options 
OS_OPT_PEND_FLAG_CONSUME // Used to set whether to keep the status of the event flag . After the conditions are met, the corresponding bit is cleared 
OS_OPT_PEND_NON_BLOCKING // Do not suspend the task when the flag group does not meet the conditions .
OS_OPT_PEND_BLOCKING     // Suspend the task when the flag group does not meet the conditions .


3.OS_FLAGS OSFlagPost (OS_FLAG_GRP *p_grp,// Point to the event flag group
OS_FLAGS flags,// Decide which bits to clear and set
OS_OPT opt,// Determines the operation of the flag bit
OS_ERR *p_err);// Error code

operation

OS_OPT_POST_FLAG_SET  Set the flag bit 
OS_OPT_POST_FLAG_CLR  Clear the flag bit 

10.1 Event flag bit program instance

1. Define the event flag bit variable

OS_FLAG_GRP FLAG_KEY;

2. Create event flag bit

OSFlagCreate((OS_FLAG_GRP*  )&FLAG_KEY,// Point to the event flag group  
           (CPU_CHAR*     )"FLAG_KEY",// The name of the event flag group  
           (OS_FLAGS      )0,// Define the initial value of the event flag group  
           (OS_ERR*       )&err);// Error code 

3. Issue flag to event flag group

		OSFlagPost ((OS_FLAG_GRP*)&FLAG_KEY,// Point to the event flag group  
              (OS_FLAGS    )key,// Decide which bits to clear and set  
              (OS_OPT      )OS_OPT_POST_FLAG_SET,// Determines the operation of the flag bit  
              (OS_ERR*     )&err);// Error code  

4. Wait for event flag group

	OSFlagPend((OS_FLAG_GRP* )&FLAG_KEY,// Point to the event flag group  
           (OS_FLAGS     )0x03,//bit  Sequence , The task needs to wait for which bit of the event flag group will put the corresponding position of this sequence  1, bit0 and  bit1  when ( Whether it's waiting to be set or cleared ), flag  Yes, the value is  0X03. 
           (OS_TICK      )100,// Timeout time ( Clock beats ) 
           (OS_OPT       )OS_OPT_PEND_FLAG_SET_ALL+OS_OPT_PEND_FLAG_CONSUME,// Determine the conditions for the task to wait   Wait for all position bits in the event flag group + After the conditions are met, the corresponding bit is cleared 
           (CPU_TS*      )0,// Time stamp  
           (OS_ERR*      )&err);// Error code  
	if(err==OS_ERR_TIMEOUT) /// Report errors 
	{
    
		printf(" Overtime  %X\r\n",FLAG_KEY.Flags);
	}
	else
	{
    
		printf("OK %X\r\n",FLAG_KEY.Flags);		
	}

10.2 Wait for multiple event flags

Wait for a single kernel object , Include : Semaphore 、 Mutex semaphore 、 Message queue and event flag group .

stay UCOSIII Allow tasks to wait for multiple at the same time Semaphore And multiple Message queue , in other words ,UCOSIII It is not supported to wait for multiple event flag groups or mutually exclusive semaphores at the same time .

A task can wait for any number of semaphores and message queues , first The release of semaphore or message queue causes the task to enter the ready state .

Enable macro definition OS_CFG_PEND_MULTI_EN

function :

OS_OBJ_QTY	OSPendMulti	(OS_PEND_DATA*p_pend_data_tbl,// Point to  OS_PEND_DATA  Pointer to table  
                   OS_OBJ_QTY tbl_size,// surface  p_pend_data_tbl  Size , That is, the number of kernel objects waiting  
                         OS_TICK timeout,// Timeout value ( Clock beats ) 
                         OS_OPT opt,// Whether to use blocking mode  
                         OS_ERR *p_err);// Error code  
opt:
OS_OPT_PEND_BLOCKING // If no message exists, block the task , Have been waiting for , Until you receive a message .
OS_OPT_PEND_NON_BLOCKING // If there is no message in the message queue, the task returns directly .

p_pend_data_tbl :
 When calling this function, you must first initialize  OS_PEND_DATA  Of each element in the table PendObjPtr, Make each pointer point to the waiting object . 

10.3 Waiting for multiple event flag instances

Equivalent to only one function used OSPendMulti Just call this function in the right place , Pay attention to initializing the array first (OS_PEND_DATA* )pend_multi_tbl

1. Enable macro definition OS_CFG_PEND_MULTI_EN

2. Define the number of kernel objects

#define CORE_OBJ_NUM 3

3. Define a OS_PEND_DATA Array , Array elements are events

	OS_PEND_DATA pend_multi_tbl[CORE_OBJ_NUM];	
	
	pend_multi_tbl[0].PendObjPtr=(OS_PEND_OBJ*)&Sem1;
	pend_multi_tbl[1].PendObjPtr=(OS_PEND_OBJ*)&Sem2;
	pend_multi_tbl[2].PendObjPtr=(OS_PEND_OBJ*)&Test_Q;

4. wait for

OS_OBJ_QTY index;
index=OSPendMulti((OS_PEND_DATA*	)pend_multi_tbl,	
						  (OS_OBJ_QTY		)CORE_OBJ_NUM,	// Number of cores 
						  (OS_TICK		   	)20,		
						  (OS_OPT         	)OS_OPT_PEND_BLOCKING,
						  (OS_ERR*			)&err);

5. Complete functions

void task2_task(void *p_arg)
{
    		
	OS_ERR err;
	OS_OBJ_QTY index;
	OS_PEND_DATA pend_multi_tbl[CORE_OBJ_NUM];	
	
	pend_multi_tbl[0].PendObjPtr=(OS_PEND_OBJ*)&Sem1;
	pend_multi_tbl[1].PendObjPtr=(OS_PEND_OBJ*)&Sem2;
	pend_multi_tbl[2].PendObjPtr=(OS_PEND_OBJ*)&Test_Q;
	while(1)
	{
    
				index=OSPendMulti((OS_PEND_DATA*	)pend_multi_tbl,	
						  (OS_OBJ_QTY		)CORE_OBJ_NUM,	// Number of cores 
						  (OS_TICK		   	)20,		
						  (OS_OPT         	)OS_OPT_PEND_BLOCKING,
						  (OS_ERR*			)&err);
		if(err==OS_ERR_TIMEOUT)
		{
    
			printf(" Overtime  index=%d\r\n",index);
		}
		else
		{
    
					printf("%d A kernel is ready \r\n",index);
		}
		OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); // Time delay  
	}
}

11 memory management

版权声明
本文为[Things will turn when they reach the extreme 1024]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210610057464.html