RT-Thread record (2. RT-Thread kernel startup process - startup file and source code analysis)

在上一篇文章中,我们了解了RT-Thread的版本以及开发环境,使用RT-Thread Studio成功创建了一个工程。
但是要了解一个操作系统,内核的了解是必不可少的,
我们今天就在前面我们RT-Thread Studio工程基础之上讲一讲RT-Thread内核启动流程
.. 更新一个说明,SMP是对多核处理器的支持相关部分      		 2022/3/15

1. Basic introduction

The link to the official introduction of the kernel startup process is as follows:

RT-Thread official kernel startup process introduction

In my STM32 column, I have a separate blog post about the startup of STM32:

STM32 startup process (startup_xxxx.s file analysis)

In a bare metal program, generally jump to in the .s file _mainto jump to the main()function startup, while RT-Thread startup will first jump to its startup function rtthread_startup()to perform a series of necessary initializations, and finally jump to the main()function.

Simply put: When the program starts, jump to the RT-Thread startup function rtthread_startup()(C language) through the startup_xxxx.s file (assembly language), and then rtthread_startup()jump to the main()(C language) function through .

The official picture shows this process in great detail:

insert image description here
In RT-Thread, the main()function is treated as a thread. rtthread_startup()This will main()create a thread, and in addition, two threads, a thread and an idle thread , rtthread_startup()will be created .timer

Combined with the above figure, let's illustrate this process through the sample code created in the previous article.

2. Source code analysis

2.1 Assembly part - startup_xxxx.s description

Open the RT-Thread Studio project, where to find the startup_xxxx.sfile , see the following picture:
insert image description here

We have found the startup file, which can be opened and viewed. The description of the startup file is described in detail in my other blog post.

The startup process of STM32 - startup_xxxx.s file analysis (update the startup file analysis in the GCC environment)

It has been explained in more detail, here I will only briefly explain the main ones. As mentioned in the recommended blog post above, two files are needed to start the GCC environment, one is a startup_xxxx.sfile and the other is a .ldlink file. Let's take a look at the link file first:
insert image description here

As mentioned before, the link file under GCC mainly formulates the entry function, the stack size and the overall layout of the data segment. In the above image we see that the value defines the size of the system stack and does not define the size of the heap.

Why only define the system stack here?
Although we have said in other blog posts that if you don't use the mallocfunction , you don't need to use the heap. There is no definition here because the size of the heap will be defined according to whether the heap is used or not during the initialization later.
Instructions are described in the panel-level hardware initialization section below this document.

Then simply take a look at the startup_xxxx.sfile . First, we find the first command to be executed when the power is turned on Reset_Handler(the chip is powered on, it is a power-on reset, and it will trigger directly Reset_Handler):

insert image description here
If you don't understand the operations in the above figure, you can view the blog post:

Memory management related to STM32 (memory architecture, memory management, map file analysis)

After the data transfer is completed, it is the basic initialization of the system, as shown in the figure below:
insert image description here
After the basic initialization is completed, the MCU can run, and then jump to the entry function mentioned in our basic introduction above, as shown in the figure below:
insert image description here
Through the above steps, finally from . The assembly in s jumps to the C language part, and jumps to the rtthread_startupfunction . We will explain what rtthread_startupRT-Thread does after entering the function through the following introduction.

2.2 Section C - rtthread_startup Description

In the basic introduction in the first section of this article, an official picture shows the rtthread_startupoperations that will be performed after entering. We also explained how the project enters the rtthread_startupfunction , and rtthread_startupwhat operations are performed after entering the function, as shown in the following figure:
insert image description here
Supplement Description: The SMP in the above figure is related to the settings related to multi-core processors.

The above process is easy to understand. The main tasks are as follows:

1. Basic hardware initialization;

2. The main thread will be created;

3. Create a timer thread according to whether a software timer is used;

4. An idle thread will be created;

5. Initialize the scheduler;

There are some initializations that we can take a closer look at the specific operations:

2.2.1 Board Hardware Initialization - rt_hw_board_init

rt_hw_board_initHardware-related initialization is performed using the function, as shown below:
insert image description here

2.2.2 RT-Thread Heap and Stack Space Description (different from FreeRTOS)

In the above picture, there is something special, that is, the initialization of the heap space. What we have encountered before is to define the stack space in the startup file. When we analyzed the RT-Thread startup file above, we only defined the stack space. , the heap space is not defined, it is actually placed in this place :
insert image description here

At the beginning, there was still a question here. HEAP uses all the remaining RAM. According to the previous understanding, the system stack should be in the last position. What is going on here?

Regarding the position of the system stack, you can refer to the blog post: RTOS task stack and system stack

The conclusion we saw through the source code above is different from what this blog post said (the bare metal and FreeRTOS were used as examples at that time), and then under RT-Thread, where is the position of the system stack, so I looked back Look at the link file that defines the overall layout of the data segment:
insert image description here
through the link file we can infer the location of the .stack, so to confirm, we can view the .map file after the program is compiled:
insert image description here

In the RAM data segment, we can view the location where the data is stored and find the location part about the system stack:

insert image description here
It is confirmed that in RT-Thread, the position of the system stack is indeed stored between the .data segment and .bss, so there is no problem even if the heap space uses all the remaining ram space.

2.2.3 main thread creation - rt_application_init

In RT-Thread, "main"a to call main()the function, which is in the rtthread_startupfunction rt_application_init(), as shown below:
insert image description here

2.2.4 Scheduler Description

The scheduler is the core knowledge of the operating system. The scheduler operates based on the linked list. The specific principle will be described in a separate article in the future. Here we will briefly go over it and know the purpose of the function.

In the rtthread_startupfunction, use the rt_system_scheduler_init();initialization scheduler, rt_system_scheduler_start();turn on the scheduler, and after the scheduler is turned on, the threads will switch according to certain rules (time slice, priority):

insert image description here

After the scheduler is turned on, the thread with the highest priority will be found in the ready list, and then jump to the corresponding position to execute by setting the thread pointer (PSP):

What does the thread pointer mean, you can refer to the blog post: FreeRTOS record (3. Analysis of the principle of FreeRTOS task scheduling _Systick, PendSV, SVC)
insert image description here

At this point, the whole system runs normally, and then the user runs what he wants to do, he can design his own application code in the main, or create a thread.

Guess you like

Origin blog.csdn.net/weixin_42328389/article/details/122989172