freertos zynq 移植_freeRTOS移植――初步分析

本文详细分析了FreeRTOS在ZYNQ ZC702平台的移植步骤,包括初始化Task Stack、启动调度器、ISR处理、TASK切换和中断控制。通过理解CPU和存储器细节,移植关键函数如pxPortInitialiseStack和xPortStartScheduler,并讨论了中断向量表注册、中断处理效率和用户自定义处理API的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于之前的分析,freeRTOS的移植主要集中在以下部分,

它们对应的源文件如下

移植之前必须清楚待移植嵌入式系统的硬件架构,尤其是CPU和存储器的相关细节。后边将一一提到。实际上freeRTOS需要移植的必要代码都已经在portable.h中声明(不含freeRTOS_Config.h配置的可选功能),我们只需要按照该文件填写好对应的宏和函数即可。

以下将以freeRTOS官网上给出的基于ZYNQ_ZC702的工程,对一些常见的需要移植的代码进行分析。

初始化Task Stack

对应函数声明强制如下,

StackType_t*pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void*pvParameters )

其在freeRTOS创建TASK时被调用,用于初始化TASK的STACK,细节参考API函数xTaskCreate()、xTaskCreateStatic()、xTaskCreateRestricted和xTaskCreateRestrictedStatic()。

该函数的处理十分简单,实际就是压栈过程,但寄存器的取值完全用用户确定,但是需要注意以下几点

前两点需要用户查询CPU相关硬件手册,是必须做的。后两者并不强制要求,但是在实际移植中常常用到,可以用来检测OS崩溃。

若业务代码没有频繁创建TASK,处于便于维护的考虑,建议用C语言实现。

以下为freeRTOS官网提供的部分代码,可见其认为栈是向下生长的,按照R15到R0的顺序进行入栈的,出栈时必须保证这样的顺序。

启动调度器

对应函数声明强制如下,

BaseType_t xPortStartScheduler( void )

其在freeRTOS提供的API函数vTaskStartScheduler()中调用,用于OS启动时设置ISR、初始系统硬件和运行firstTASK。

其中,

freeRTOS官网上的代码实际上是使用函数vConfigureTickInterrupt()来设置中断和完成硬件初始化的,然后调用汇编语言实现的函数vPortRestoreTaskContext()运行first TASK

vConfigureTickInterrupt()的基本流程如下图所示,其中使用了大量的ZYNQ 7000的提供的BSP,对于其他的硬件模块,也可以使用类似的流程完成相应中断设置和初始化

其中,

只需要在首次配置中断时使用,使用BSP提供的API函数XScuGic_CfgInitialize()

以下为相应代码,实际上所有外设中断都可以如是配置。

vPortRestoreTaskContext()实际上就是出栈的处理过程,也用于任务切换的处理过程,在后边会提到。

ISR

一般而言,ISR处理过程如下图所示,包含压栈、用户自定义处理和出栈过程,

其中,

该部分的移植需要特别考虑如何提高出栈和压栈代码的效率,以及提供给用户更加方便的用户自定义处理过程的API接口。

除此之外,还需要考虑如何将ISR注册到CPU认可的中断向量表中去。

FreeRTOS使用了中断向量表替换的方式来完成注册,如下图所示,其中的函数vPortInstallFreeRTOSVectorTable()需要在操作系统启动前调用

对应的中断处理向量表freertos_vector_table如下,

PS:freertos_vector_table需要在链接器文件中注册,其中尤其要注意把vector_table的KEEP修饰关键字去掉

freeRTOS提供了名为FreeRTOS_IRQ_Handler的函数来实现ISR,细节如下。

压栈过程代码如下,其中的176行即对当前TASK进行压栈,在此之前,保存了了R14和SPSR,然后切入到SVC模式。

用户自定义处理过程相关代码如下,其中,

出栈过程相关代码如下,其中

TASK切换

如之前所述,TASK切换主要是压栈和出栈操作。freeRTOS还提供了了以API函数用于选取当前处于ready状态的优先级最高的TASK,即vTaskSwitchContextConst(),并且freeRTOS还提供了名为pxCurrentTCB的变量用于指示当前TASK的栈顶地址。

freeRTOS提供函数FreeRTOS_SWI_Handler用于TASK切换,

其中portSAVE_CONTEXT为实现压栈的宏,其中首先切换到了SYS模式,然后将必要的寄存器,中断嵌套层数(ulCriticalNestingConst)等全部入栈保存。

其中portRESTORE_CONTEXT为实现压栈的宏,其中过程与portSTORE_CONTEXT()刚好相反,但是由于OS提供的vTaskSwitchContextConst()中已经改变了当前OS执行TASK信息(pxCurrentTCBConst),因此出栈后切换到到了另外一TASK。

中断控制

如之前所属,OS基于中断实现了临界区和主动触发TASK切换的功能,它们以宏的方式定义,名称如下,

freeRTOS官网上提供了相关代码,非常简单易懂,这里就不在累述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值