/*******************************************************************************
* Function Name : main
* Description : Main function, initialize the system and hardware, establish the main function and start the system
* Input : None
* Output : None
* Return : None
*******************************************************************************/
int main(void)
{
CPU_IntDis(); // Disable CPU interrupt connection to assembly
OSInit(); // uCOS system initialization
BSP_Init(); // Hardware initialization
OSTaskCreate // Establish the main task, the highest priority Another purpose of establishing this task is to use the statistical task later
(
(void (*) (void *)) App_TaskStart, // Pointer to the task code
(void *) 0, // Pointer to the parameters passed to the task when the task starts executing
(OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1], // The top pointer of the stack allocated to the task, from (INT8U) APP_TASK_START_PRIO //The priority assigned to the task
);
OSTimeSet(0);
OSStart();
return(0);
}
Before starting the scheduling of uC/OS_II, we need to call the function OSInit(), which is responsible for establishing data structures such as the task control block list and the ready task list, and then initializing global variables. Then initialize the external devices needed, mainly clock initialization, interrupt nesting initialization, port initialization, and call the function BSP_Init(). uC/OS_II stipulates that at least one task has been established before the task scheduling begins, so we establish a task APP_TaskStart and assign priority and stack resources to this task. This is necessary. Then we use the OSTimeSet(0) function to initialize the system clock beats, and then call the OSStart() function to start task scheduling. The task will start executing from the highest priority among all established tasks.
Everyone still remembers that we just created an APP_TaskStart task. When the system starts task scheduling, this task is the only one registered in the system except for the default idle task with the lowest priority. So this task will run naturally. Let's first look at its related source code from the file task.c:
/*******************************************************************************
* Function Name : App_TaskStart
* Description : Main task
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void App_TaskStart(void* p_arg)
{
(void) p_arg;
OS_CPU_SysTickInit(); // Initialize system heartbeat
#if (OS_TASK_STAT_EN > 0)
OSStatInit(); // Statistics task initialization function
#endif
App_TaskCreate(); // Create a new user task
while(1)
{
LED4_HIGH;
OSTimeDlyHMSM(0,0,1,0);
LED4_LOW;
OSTimeDlyHMSM(0,0,1,0);
}
}
/***********************************************************************************
* Function Name : App_TaskCreate
* Description : Create user task
* Input : None
* Output : None
* Return : None
***************************************************************************/
void App_TaskCreate(void)
{
//=========================================================================// Test task 1
OSTaskCreateExt(
Task_Test1, // Pointer to the task code, that is, the task function name
(void *)0, // Parameters passed to the task when the task starts executing
(OS_STK *)&Task_Test1Stk[Task_Test1_STK_SIZE-1], // Top pointer assigned to the task stack, from top to bottom
Task_Test1_PRIO, // Priority assigned to the task
Task_Test1_PRIO, // Identifiers reserved for future versions, now the same as task priority
(OS_STK *)&Task_Test1Stk[0], // Pointer to the bottom of the task stack for stack verification
Task_Test1_STK_SIZE, // Specify the capacity of the stack for stack verification
(void *)0, // Pointer to the user additional data area, used to extend the task control block
OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR // Task options: Enable stack detection and clear the stack when creating a task
);
//====================================================================// Test Task 2
OSTaskCreateExt(
Task_Test2,
(void *)0,
(OS_STK *)&Task_Test2Stk[Task_Test2_STK_SIZE-1],
Task_Test2_PRIO,
Task_Test2_PRIO,
(OS_STK *)&Task_Test2Stk[0],
Task_Test2_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR
);
//==================================== ================================//Test Task 3
OSTaskCreateExt(
Task_Test3,
(void *)0,
(OS_STK * )&Task_Test3Stk[Task_Test3_STK_SIZE-1],
Task_Test3_PRIO,
Task_Test3_PRIO,
(OS_STK *)&Task_Test3Stk[0],
Task_Test3_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR
);
}
At the same time, the task priority and stack size information are given from the file app_cfg.h
#define APP_TASK_START_PRIO 10
#define Task_Test1_PRIO 7
#define Task_Test2_PRIO 8
#define Task_Test3_PRIO 9
//Task stack size
#define APP_TASK_START_STK_SIZE 64
#define Task_Test1_STK_SIZE 128
#define Task_Test2_STK_SIZE 128
#define Task_Test3_STK_SIZE 128
It can be seen that the priority of task APP_TaskStart is the lowest, so when creating other tasks in this task, it will be taken away by the task with a higher priority. In uC/OS_II, each task will be scheduled once after it is created. If the priority of the created task is higher, the system will execute the newly created task. If it is lower, it can only wait. So after creating Task_Test1, it will jump to execute this task. Now let's take a look at the source code of these three test tasks from the file app.c
/*******************************************************************************
* Function Name : Task_Test1
* Description : Task 1
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void Task_Test1(void* p_arg)
{
(void) p_arg ;
while(1)
{
if(KEY_WKUP == 0)
{
LED1_HIGH;
}
else
{
LED1_LOW;
}
OSTimeDlyHMSM(0,0,0,100); // Delay to leave room for other low-priority tasks to execute
}
}
/***********************************************************************************
* Function Name : Task_Test2
* Description : Task 2
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void Task_Test2(void* p_arg)
{
(void) p_arg ;
while(1)
{
LED2_HIGH;
OSTimeDlyHMSM(0,0,0,500);
LED2_LOW;
OSTimeDlyHMSM(0,0,0,500);
}
}
/*****************************************************************************
* Function Name : Task_Test3
* Description : Task 3
* Input : None
* Output : None
* Return : None
*****************************************************************************/
void Task_Test3(void* p_arg)
{
(void) p_arg ;
while(1)
{
LED3_HIGH;
OSTimeDlyHMSM(0,0,0,500);
LED3_LOW;
OSTimeDlyHMSM(0,0,0,500);
}
}
Where were we just now? Yes, now we are starting to execute the Task_Test1 task. Obviously, this task is to detect a key. After the detection is completed, a 100ms delay function is entered. In uC/OS_II, the role of the delay function is much greater than before. When the delay function is called in a task in uC/OS_II, the task is exited from the task ready table, and then the system scheduler OS_Sched() is called once to find the highest priority task to execute again. At this time, our system has only registered two tasks, so we can only continue to execute the task APP_TaskStart. The first test task created in this function just now was robbed of the CPU occupancy right. Now come back to create the second test task Task_Test2. The priority of this second test task is also higher than that of the start task, so naturally it is robbed of the CPU occupancy right. In the second test task, you will see a delay function again, and the function must be the same. By analogy, the third test task will be much clearer. At this time, there is another problem, which is the system operation after the delay. After the test task 1 enters the delay, it will not be called by the system. Its delay variable OSTCBDly is decremented with the heartbeat of the system. If there are two tasks in the delay at the same time, as long as the delay variable in their task control block is not 0, it will be reduced by 1 in the heartbeat interrupt service function. When it is reduced to 0, the system will put the task back into the task ready list and run the system scheduling function OS_Sched() once. This mechanism ensures that the system is always running the highest priority task. In this way, the scheduling problem of the system is explained. When interrupts and semaphores are used later, they also have an impact on the execution order of the system. How they participate in the scheduling of the system will be explained later.
Just now we talked about the role of the delay function. If I ignore the yellow highlighted part in the code above, what will happen? The result is that the other three tasks cannot run, and the system will always process the task Task_Test1. If we increase the delay parameter of the yellow highlighted part to 1s, the result is not satisfactory. Although I gave the task enough running time, I have to wait for a long time every time I detect it, which greatly reduces my detection accuracy and makes the buttons extremely difficult to use. At this time, we should think about it. In a real-time embedded operating system like uC/OS_II, the most terrible thing is aimless waiting, so we try to use interrupts to process interface information. Interrupts and real-time systems complement each other.
Previous article:STM32 uCOS_II practice of external interrupt events and system operation process
Next article:STM32 debugging using SWD
Recommended ReadingLatest update time:2024-11-15 14:32
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- Brief Analysis of Automotive Ethernet Test Content and Test Methods
- How haptic technology can enhance driving safety
- ESP32-C3 development board for 9.9 yuan with free shipping
- Design method of high-speed graphics frame storage using DSP+FPGA architecture
- Why can the defined pointer be used as an array?
- Have you ever used the YU4215 chip, SMD SO-8 package?
- Pingtouge RISC-V Development Board--STEP2--Intelligent Voltage and Current Acquisition Controller Design Preparation Part 1
- max30102 MCU selection
- Switch Mode Power Supply Board Layout Example
- How to use a signal source + power amplifier + oscilloscope to output a heart-shaped waveform? How to make a heart with LEDs?
- F28335 485SCI modbus receive interrupt length setting problem
- Altium Designer Common Component Library File