推荐星级:
  • 1
  • 2
  • 3
  • 4
  • 5

RT-Thread快速入门-内核移植

更新时间:2023-10-03 07:02:39 大小:263K 上传用户:sun2152查看TA发布的资源 标签:RT-Thread 下载积分:1分 评价赚积分 (如何评价?) 打赏 收藏 评论(0) 举报

资料介绍

RT-Thread 快速入门-内核移植 RT-Thread 快速入门系列前面的文章介绍了内核相关的知识,以及内核提供的 接口函数和如何使用。 本篇文章主要介绍如何将 RT-Thread 内核移植到某个硬件平台之上。移植分为 两部分:  CPU 架构移植  BSP 移植 也就是将 RT-Thread 内核在不同的芯片架构、不同的板卡上运行起来,能够具 备线程管理和调度,内存管理,线程间同步和通信,定时器管理等功能。 CPU 架构移植,会用到 CPU 架构的汇编指令,因此如果要自己动手移植,需 要熟悉一下目标 CPU 的汇编指令。 备注:在介绍移植过程的各个部分时,会以 Cortex-M 为例进行说明。 CPU 架构移植 为了方便将 RT-Thread 移植到不同 CPU 架构的芯片上运行,RT-Thread 提供 了一个 libcpu 抽象层。该抽象层用来适配不同的 CPU 架构,起到承上启下的 作用。  向上对内核提供统一的函数接口。包括全局中断的开关、线程初始化、上 下文切换等等。  向下提供了统一的 CPU 架构移植接口,包括全局中断开关函数、线程上 下文切换函数、时钟节拍配置、Cache 等等。 CPU 架构移植需要实现的接口函数,如下表 函数和变量 描述 rt_base_t rt_hw_interrupt_disable(void); 关闭全局中断 void rt_hw_interrupt_enable(rt_base_t level); 打开全局中断 rt_uint8_t *rt_hw_stack_init(void *tentry, voi d *parameter, rt_uint8_t *stack_addr, void *te xit); 线程栈的初始化,内核在线程创建 和线程初 始化里面会调用这个函 数 void rt_hw_context_switch_to(rt_uint32 to); 没有来源线程的上下文切换,在调 度器启动第一个线程的时候调用 void rt_hw_context_switch(rt_uint32 from, rt_u int32 to); 从 from 线程切换到 to 线程,用 于线程和线程之间的切换 函数和变量 描述 void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); 从 from 线程切换到 to 线程,用 于中断里面进行切换的时候使用 rt_uint32_t rt_thread_switch_interrupt_flag; 表示需要在中断里进行切换的标志 rt_uint32_t rt_interrupt_from_thread, rt_inter rupt_to_thread; 在线程进行上下文切换时候,用来 保存 from 和 to 线 1. 实现全局中断开关 RT-Thread 为了解决临界区问题,提供了一系列的线程间同步和同步机制。这 些机制内部实现都需要用到 libcpu 里提供的全局中断开关函数,他们分别是: /* 关闭全局中断 */ rt_base_t rt_hw_interrupt_disable(void); /* 打开全局中断 */ void rt_hw_interrupt_enable(rt_base_t level); 以 Cortex-M 为例,其快速开关中断的指令如下(汇编代码): CPSID I ;PRIMASK=1, ;关中断 CPSIE I ;PRIMASK=0, ;开中断 关闭全局中断 关闭全局中断函数 rt_hw_interrupt_disable() 内部需要依次完成如下功能:  保存当前的全局中断状态,并把状态作为函数的返回值  关闭全局中断。 基于 MDK,在 Cortex-M 内核上实现关闭全局中断,代码如下(已经添加注释): ;/* ; * rt_base_t rt_hw_interrupt_disable(); ; */ rt_hw_interrupt_disable PROC ;PROC 伪指令定义函数 EXPORT rt_hw_interrupt_disable ;EXPORT 输出定义的函数,类似于 C 语言 extern MRS r0, PRIMASK ;读取 PRIMASK 寄存器的值到 r0 寄存器 CPSID I ;关闭全局中断 BX LR ;函数返回 ENDP ;ENDP 函数结束 上面代码中,寄存器 r0 存储的数据就是函数的返回值。 打开全局中断 打开全局中断函数 rt_hw_interrupt_enable(rt_base_t level) 中,参数 level 为 需要恢复的全局中断状态。 基于 MDK,在 Cortex-M 内核上打开全局中断的代码如下(已经添加注释): ;/* ; * void rt_hw_interrupt_enable(rt_base_t level); ; */ rt_hw_interrupt_enable PROC ;PROC 伪指令定义函数 EXPORT rt_hw_interrupt_enable ;EXPORT 输出定义的函数,类似于 C 语言 extern MSR PRIMASK, r0 ;将 r0 寄存器的值写入到 PRIMASK 寄存器 BX LR ;函数返回 ENDP ;ENDP 函数结束 该函数用 MSR 指令将寄存器 r0 的值写入到 PRIMASK 寄存器中,恢复之前的中断 状态。 2. 实现线程栈初始化 在线程创建过程中,会调用栈初始化函数 rt_hw_stack_init(),对线程栈进行初 始化。该函数内部,会构造一个上下文内容,这个上下文内容被当作每个线程第 一次执行的初始值。 Cortex-M 的栈初始化代码如下: rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit) { struct stack_frame *stack_frame; rt_uint8_t *stk; unsigned long i; /* 对传入的栈指针做对齐处理 */ stk = stack_addr + sizeof(rt_uint32_t); stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8); stk -= sizeof(struct stack_frame); /* 得到上下文的栈帧的指针 */ stack_frame = (struct stack_frame *)stk; /* 把所有寄存器的默认值设置为 0xdeadbeef */ for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++) { ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef; } /* 根据 ARM APCS 调用标准,将第一个参数保存在 r0 寄存器 */ stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* 将剩下的参数寄存器都设置为 0 */ stack_frame->exception_stack_frame.r1 = 0; /* r1 寄存器 */ stack_frame->exception_stack_frame.r2 = 0; /* r2 寄存器 */ stack_frame->exception_stack_frame.r3 = 0; /* r3 寄存器 */ /* 将 IP(Intra-Procedure-call scratch register.) 设置为 0 */ stack_frame->exception_stack_frame.r12 = 0; /* r12 寄存器 */ /* 将线程退出函数的地址保存在 lr 寄存器 */ stack_frame->exception_stack_ = (unsigned long)texit; /* 将线程入口函数的地址保存在 pc 寄存器 */ stack_frame->exception_stack_ = (unsigned long)tentry; /* 设置 psr 的值为 0x01000000L, 表示默认切换过去是 Thumb 模 式 */ stack_frame->exception_stack_ = 0x01000000L; /* 返回当前线程的栈地址 */ return stk; } 3. 实现上下文切换 CPU 架构不同,线程之间的上下文切换和中断到线程的上下文切换,上下文的 寄存器部分可能会有所差异。在 Cortex-M 里面上下文切换都是统一使用 PendSV 异常来完成,切换部分并没有差异。 为了能适应不同的 CPU 架构, RT-Thread 的 libcpu 抽象层需要实现三个线 程切换相关的函数:  rt_hw_context_switch_to():没有来源线程,切换到目标线程,在调度器 启动第一个线程的时候 被调用。  rt_hw_context_switch():在线程环境下,从当前线程切换到目标线程。  rt_hw_context_switch_interrupt():在中断环境下,从当前线程切换到 目标线程。 线程环境下,调用 rt_hw_context_switch() 函数,可以立即进行上下文切换。在 中断环境下,需要等待中断服务函数完成之后才能进行切换。 实现 rt_hw_context_switch_to() 该函数只有目标线程,没有来源线程。实现流程图: 在 Cortex-M3 内核上的 rt_hw_context_switch_to() 实现(基于 MDK),其代 码如下: ;/* ; * void rt_hw_context_switch_to(rt_uint32 to); ; * r0 --> to ; * this fucntion is used to perform the first thread switch ; */ rt_hw_context_switch_to PROC EXPORT rt_hw_context_switch_to ; r0 的值是一个指针, 该指针指向 to 线程的线程控制块的 SP 成员 ; 将 r0 寄存器的值保存到 rt_interrupt_to_thread 变量里 LDR r1, =rt_interrupt_to_thread STR r0, [r1] ; 设置 from 线程为空,表示不需要从保存 from 的上下文 LDR r1, =rt_interrupt_from_thread MOV r0, #0x0 STR r0, [r1] ;设置标志为 1,表示需要切换,这个变量将在 PendSV 异常处理函数里切换的时被清零 LDR r1, =rt_thread_switch_interrupt_flag MOV r0, #1 STR r0, [r1] ; 设置 PendSV 异常优先级为最低优先级 LDR r0, =NVIC_SYSPRI2 LDR r1, =NVIC_PENDSV_PRI LDR.W r2, [r0,#0x00] ; read ORR r1,r1,r2 ; modify STR r1, [r0] ; write-back ; 触发 PendSV 异 常 (将执行 PendSV 异常处理程序) LDR r0, =NVIC_INT_CTRL LDR r1, =NVIC_PENDSVSET STR r1, [r0] ; 放弃芯片启动到第一次上下文切换之前的栈内容,将 MSP 设置启动时的值 LDR r0, =SCB_VTOR LDR r0, [r0] LDR r0, [r0] MSR msp, r0 ; 使能全局中断和全局异常,使能之后将进入 PendSV 异常处理函数 CPSIE F CPSIE I ;不会执行到这里 ENDP 实现 rt_hw_context_switch()/ rt_hw_context_switch_interrupt() 这两个函数都有两个参数 from 和 to,他们实现从 from 线程切换到 to 线程的功 能。流程图如下

部分文件列表

文件名 大小
RT-Thread快速入门-内核移植.pdf 263K

【关注B站账户领20积分】

全部评论(0)

暂无评论

上传资源 上传优质资源有赏金

  • 打赏
  • 30日榜单
  • sd-hyc 打赏1.00元   1天前

    资料:神州易刻2024最新版

  • 柏涵 打赏1.00元   3天前

    资料:XDS100_v1_1_RTM

  • 21ic下载 打赏310.00元   3天前

    用户:jh0355

  • 21ic下载 打赏310.00元   3天前

    用户:w178191520

  • 21ic下载 打赏210.00元   3天前

    用户:gsy幸运

  • 21ic下载 打赏210.00元   3天前

    用户:zhengdai

  • 21ic下载 打赏210.00元   3天前

    用户:jh03551

  • 21ic下载 打赏110.00元   3天前

    用户:liqiang9090

  • 21ic下载 打赏60.00元   3天前

    用户:sun2152

  • 21ic下载 打赏60.00元   3天前

    用户:xuzhen1

  • 21ic下载 打赏80.00元   3天前

    用户:xzxbybd

  • 21ic下载 打赏25.00元   3天前

    用户:WK520077778

  • 21ic下载 打赏20.00元   3天前

    用户:w1966891335

  • 21ic下载 打赏20.00元   3天前

    用户:铁蛋锅

  • 21ic下载 打赏20.00元   3天前

    用户:玉落彼岸

  • 21ic下载 打赏15.00元   3天前

    用户:kk1957135547

  • 21ic下载 打赏10.00元   3天前

    用户:zpf22332

  • 21ic下载 打赏5.00元   3天前

    用户:pangpidan

  • 21ic下载 打赏5.00元   3天前

    用户:hpxny

  • 21ic下载 打赏5.00元   3天前

    用户:pandq2009

  • 21ic下载 打赏5.00元   3天前

    用户:tomp

推荐下载