RT-thread源码入门到入土 -(嵌入式提升篇)

本文旨在记录研究RT-thread的源码的过程。

Written by: Zhai Xiufeng

1. 概述

RT-thread是一个实时操作系统,也就是操作系统是以时间片和优先级共同来判定和分配CPU的执行资源。

2. 移植和搭建环境

2.1 RT系统源码和工具下载

源码下载地址:根据需求选择RT的系统版本即可。一般是选择某个大版本的最新版本。

GitHub - RT-Thread/rt-thread: RT-Thread is an open source IoT real-time operating system (RTOS).

ENV工具下载地址:

GitHub - RT-Thread/env: Python Scripts for RT-Thread/ENV

3. 系统挂载初始化

系统运行在MCU中,需要如同片上外设一般初始化,因为操作系统本质上是根据MCU的内核和片上外设的机制,来运行的一个功能。所以需要配置片上外设和基础变量初始化。

RT-Thread初始化接口的名称是rtthread_startup一般是执行在启动文件中_cmain中被执行。

初始化通过env建立新的工程时,会自动挂载,不太需要我们去管理。

4. 系统机制分析

实时操作系统(Real-Time Operating System,RTOS)具备一些关键功能,以满足实时应用的需求。以下是RTOS常见的功能:

任务管理:

多任务支持:允许多个任务并发运行。

任务优先级:任务可以分配不同的优先级,优先级高的任务会优先执行。

任务调度:实时调度器根据任务的优先级和时间限制,决定任务的执行顺序。

任务同步和通信:提供任务间同步和通信机制,如信号量、消息队列和事件标志。

中断管理:

快速中断响应:能够快速响应和处理硬件中断。

中断优先级:支持中断优先级设置,以确保关键中断优先处理。

内存管理:

静态和动态内存分配:支持静态和动态内存分配,确保内存使用的高效性和安全性。

内存保护:防止任务间的内存访问冲突,提高系统稳定性和安全性。

定时器和时钟管理:

精确定时:提供高精度的定时器,用于时间敏感的任务。

延时和超时功能:支持任务的延时和超时处理。

4.1 多任务支持

任务也就是当前执行业务代码,项目中任务会很多,比如显示、规约等等。在嵌入式中,任务也会被称作线程,一个进程有多个线程。根据嵌入式原理,业务代码是通过寄存器堆栈执行在内核中。但是由于一般MCU只存在一个内核和一些其他的限制,无法自动支持多任务运行,这个时候就需要软件辅助来促使多个任务在内核中被执行。

多任务支持(Multitasking Support)是实时操作系统(RTOS)和一般操作系统,使用一个核心让进程中能够在看似同时地运行多个任务。

多任务的支持内容的核心就是任务极短时间内完成切换,中间无法感知到线程执行的延时。

这其中有个特殊的中断(PendSV_Handler),该中断是多任务能够实行的必要条件。PendSV(可悬挂的系统服务调用,Pendable Service Call)是 ARM Cortex-M 系列处理器中的一种特殊中断。它设计用于操作系统的上下文切换,它是为了切换任务而专门设计的。PendSV 中断的优先级通常被设置为最低,这样它可以在其他更高优先级的中断处理完之后再执行。

原理如下:

保存当前任务上下文:

保存当前任务的寄存器状态(如程序计数器、堆栈指针、通用寄存器)。

将当前任务的上下文信息存储在任务控制块(管理和调度任务的关键数据结构)中。

选择下一个任务:

调度器从就绪队列中选择下一个最高优先级的任务。

更新当前任务指针以指向新任务的任务控制块。

恢复新任务上下文:

从新任务的任务控制块中恢复寄存器状态。

设置程序计数器指向新任务的执行地址。

恢复堆栈指针指向新任务的堆栈。

注意:当 PendSV_Handler 中的 BX LR 指令执行时,处理器会根据 PSP 恢复 R0-R3, R12, LR, PC, xPSR,这些寄存器的值是在新线程的堆栈中保存的。因此,恢复的新值是新线程的上下文。流程是当前线程执行指令时,中断来临,执行完当前的指令,LR保存当前线程的下一个指令,STM32自动压栈保存特殊寄存器的值。执行以下指令实现保存普通寄存器的值,最后执行BX LR,弹出PSP内的特殊寄存器值,跳回到另一个线程前面进入中断的原来LR压栈内容。

实现以上功能的代码如下:

; r0 --> switch from thread stack

; r1 --> switch to thread stack

; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack

        EXPORT PendSV_Handler

PendSV_Handler:

    ; 禁用中断以保护上下文切换

    MRS     r2, PRIMASK            ; 将当前中断状态(PRIMASK寄存器)保存到r2中

    CPSID   I                      ; 禁用中断,防止嵌套的PendSV处理

    ; 获取 rt_thread_switch_interrupt_flag

    LDR     r0, =rt_thread_switch_interrupt_flag  ; 加载线程切换中断标志的地址

    LDR     r1, [r0]               ; 加载线程切换中断标志的值到r1中

    CBZ     r1, pendsv_exit        ; 如果标志为0,表示PendSV已经处理,直接退出

    ; 将 rt_thread_switch_interrupt_flag 清零

    MOV     r1, #0x00              ; 将r1设为0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值