当前位置: 首页 > news >正文

FreeRTOS之ARM CR5栈结构操作示意图

FreeRTOS之ARM CR5栈结构操作示意图

  • 1 FreeRTOS源码下载地址
  • 2 ARM CR5栈结构操作宏和接口
    • 2.1 portSAVE_CONTEXT宏
      • 2.1.1 portSAVE_CONTEXT源码
      • 2.1.2 portSAVE_CONTEXT宏操作栈结构变化示意图
    • 2.2 portRESTORE_CONTEXT宏
      • 2.2.1 portRESTORE_CONTEXT源码
      • 2.2.2 portRESTORE_CONTEXT宏操作栈结构变化示意图
    • 2.3 pxPortInitialiseStack
      • 2.3.1 pxPortInitialiseStack源码
      • 3.2.2 pxPortInitialiseStack栈结构变化示意图
    • 2.4 pxPortInitialiseStack调用关系
    • 2.5 portRESTORE_CONTEXT调用关系
  • 3 参考文章

下面以FreeRTOS源码中arm cortex-r5处理器的栈处理为例来介绍栈结构操作前后变化。

1 FreeRTOS源码下载地址

https://www.freertos.org/
在这里插入图片描述

2 ARM CR5栈结构操作宏和接口

  • .macro portSAVE_CONTEXT
  • .macro portRESTORE_CONTEXT
  • pxPortInitialiseStack

2.1 portSAVE_CONTEXT宏

2.1.1 portSAVE_CONTEXT源码

.macro portSAVE_CONTEXT/* Save the LR and SPSR onto the system mode stack before switching tosystem mode to save the remaining system mode registers. */SRSDB   sp!, #SYS_MODECPS     #SYS_MODEPUSH    {R0-R12, R14}/* Push the critical nesting count. */LDR     R2, ulCriticalNestingConstLDR     R1, [R2]PUSH    {R1}#if defined( __ARM_FP )/* Does the task have a floating point context that needs saving?  IfulPortTaskHasFPUContext is 0 then no. */LDR     R2, ulPortTaskHasFPUContextConstLDR     R3, [R2]CMP     R3, #0/* Save the floating point context, if any. */FMRXNE  R1,  FPSCRPUSHNE  {R1}VPUSHNE {D0-D15}/* Save ulPortTaskHasFPUContext itself. */PUSH    {R3}#endif /* __ARM_FP *//* Save the stack pointer in the TCB. */LDR     R0, pxCurrentTCBConstLDR     R1, [R0]STR     SP, [R1].endm

2.1.2 portSAVE_CONTEXT宏操作栈结构变化示意图

在这里插入图片描述

2.2 portRESTORE_CONTEXT宏

2.2.1 portRESTORE_CONTEXT源码

.macro portRESTORE_CONTEXT/* Set the SP to point to the stack of the task being restored. */LDR     R0, pxCurrentTCBConstLDR     R1, [R0]LDR     SP, [R1]#if defined( __ARM_FP )/** Is there a floating point context to restore?  If the restored* ulPortTaskHasFPUContext is zero then no.*/LDR     R0, ulPortTaskHasFPUContextConstPOP     {R1}STR     R1, [R0]CMP     R1, #0/* Restore the floating point context, if any. */VPOPNE  {D0-D15}POPNE   {R0}VMSRNE  FPSCR, R0#endif /* __ARM_FP *//* Restore the critical section nesting depth. */LDR     R0, ulCriticalNestingConstPOP     {R1}STR     R1, [R0]/* Ensure the priority mask is correct for the critical nesting depth. */LDR     R2, ulICCPMRConstLDR     R2, [R2]CMP     R1, #0MOVEQ   R4, #255LDRNE   R4, ulMaxAPIPriorityMaskConstLDRNE   R4, [R4]STR     R4, [R2]/* Restore all system mode registers other than the SP (which is alreadybeing used). */POP     {R0-R12, R14}/* Return to the task code, loading CPSR on the way. */RFEIA   sp!.endm

2.2.2 portRESTORE_CONTEXT宏操作栈结构变化示意图

在这里插入图片描述

2.3 pxPortInitialiseStack

2.3.1 pxPortInitialiseStack源码

/** See header file for description.*/
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,TaskFunction_t pxCode,void * pvParameters )
{/** Setup the initial stack of the task.  The stack is set exactly as* expected by the portRESTORE_CONTEXT() macro.** The fist real value on the stack is the status register, which is set for* system mode, with interrupts enabled.  A few NULLs are added first to ensure* GDB does not try decoding a non-existent return address.*/*pxTopOfStack = ( StackType_t ) NULL;pxTopOfStack--;*pxTopOfStack = ( StackType_t ) NULL;pxTopOfStack--;*pxTopOfStack = ( StackType_t ) NULL;pxTopOfStack--;*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ){/* The task will start in THUMB mode. */*pxTopOfStack |= portTHUMB_MODE_BIT;}pxTopOfStack--;/* Next the return address, which in this case is the start of the task. */*pxTopOfStack = ( StackType_t ) pxCode;pxTopOfStack--;/* Next all the registers other than the stack pointer. */*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* R14 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x12121212;              /* R12 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x11111111;              /* R11 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x10101010;              /* R10 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x09090909;              /* R9 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x08080808;              /* R8 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x07070707;              /* R7 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x06060606;              /* R6 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x05050505;              /* R5 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x04040404;              /* R4 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x03030303;              /* R3 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x02020202;              /* R2 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) 0x01010101;              /* R1 */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) pvParameters;            /* R0 *//** The task will start with a critical nesting count of 0 as interrupts are* enabled.*/pxTopOfStack--;*pxTopOfStack = portNO_CRITICAL_NESTING;#if ( configUSE_TASK_FPU_SUPPORT == 1 ){/** The task will start without a floating point context.* A task that uses the floating point hardware must call* vPortTaskUsesFPU() before executing any floating point* instructions.*/pxTopOfStack--;*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;}#elif ( configUSE_TASK_FPU_SUPPORT == 2 ){/** The task will start with a floating point context. Leave enough* space for the registers and ensure they are initialized to 0.*/pxTopOfStack -= portFPU_REGISTER_WORDS;memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );pxTopOfStack--;*pxTopOfStack = pdTRUE;ulPortTaskHasFPUContext = pdTRUE;}#elif ( configUSE_TASK_FPU_SUPPORT != 0 ){#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 0, 1, or 2.}#endif /* configUSE_TASK_FPU_SUPPORT */return pxTopOfStack;
}

3.2.2 pxPortInitialiseStack栈结构变化示意图

在这里插入图片描述

2.4 pxPortInitialiseStack调用关系

		|- xTaskCreate( pxIdleTaskFunction, ...)|- prvCreateTask|- pxStack = pvPortMallocStack( ( ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ) ) );|- pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );|- prvInitialiseNewTask|- vListInitialiseItem( &( pxNewTCB->xStateListItem ) );|- vListInitialiseItem( &( pxNewTCB->xEventListItem ) );|- pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );

2.5 portRESTORE_CONTEXT调用关系

|- vTaskStartScheduler|- prvCreateIdleTasks()|- xTaskCreate( pxIdleTaskFunction, ...)|- prvCreateTask|- pxStack = pvPortMallocStack( ( ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ) ) );|- pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );|- prvInitialiseNewTask|- vListInitialiseItem( &( pxNewTCB->xStateListItem ) );|- vListInitialiseItem( &( pxNewTCB->xEventListItem ) );|- pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );|- *pxCreatedTask = ( TaskHandle_t ) pxNewTCB;|- prvAddNewTaskToReadyList|- prvInitialiseTaskLists|- prvAddTaskToReadyList|- listINSERT_END( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) );|- xTimerCreateTimerTask()|- xTaskCreateAffinitySet|- prvCreateTask|- pxStack = pvPortMallocStack( ( ( ( size_t ) uxStackDepth ) * sizeof( StackType_t ) ) );|- pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );|- prvInitialiseNewTask|- vListInitialiseItem( &( pxNewTCB->xStateListItem ) );|- vListInitialiseItem( &( pxNewTCB->xEventListItem ) );|- pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );|- *pxCreatedTask = ( TaskHandle_t ) pxNewTCB;|- prvAddNewTaskToReadyList|- prvInitialiseTaskLists|- prvAddTaskToReadyList|- listINSERT_END( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) )|- pxNewTCB->uxCoreAffinityMask = uxCoreAffinityMask;|- prvAddNewTaskToReadyList( pxNewTCB );|- xPortStartScheduler()|- vPortRestoreTaskContext|- portRESTORE_CONTEXT

3 参考文章

arm汇编指令之数据块传输(LDM,STM)详见
arm 处理器的堆栈操作

相关文章:

FreeRTOS之ARM CR5栈结构操作示意图

FreeRTOS之ARM CR5栈结构操作示意图 1 FreeRTOS源码下载地址2 ARM CR5栈结构操作宏和接口2.1 portSAVE_CONTEXT宏2.1.1 portSAVE_CONTEXT源码2.1.2 portSAVE_CONTEXT宏操作栈结构变化示意图 2.2 portRESTORE_CONTEXT宏2.2.1 portRESTORE_CONTEXT源码2.2.2 portRESTORE_CONTEXT宏…...

Java线程的interrupt中断、wait-notify/all(源码级分析)

实例方法: interrupt()方法是设置结束阻塞(sleep、),并且设置中断标记true isInterrupted()判断当前是否中断 静态方法: Thread.interrupted():调用这个方法的线程中断标记位还原为false 那么好,既然上面的方法作用是清晰的&…...

计网408考点讲解

IPv4...

当linux可执行文件缺少或者不兼容so库时候,如何查看版本以及缺少那些库

解决方法: ldd 命令来验证程序是否加载了正确的库: 如检查linear_elasticity可执行文件缺少的库,用下面命令: ldd linear_elasticity 可以发现下面not found就是缺少的库,还有对应的库的位置已经版本 $ ldd lin…...

文件下载的几种方式

1、使用window.open方法 url: 可以为文件存放的地址 function downloadFile(url) {window.open(url); }2、使用<a>标签进行文件下载 <a href"/多因素登录说明文档.pdf" class"link-text">说明文档</a> 3、使用fetch和Blob对象 这种…...

车联网安全学习之TBOX

Telematics BOX&#xff0c;简称 T-BOX&#xff0c;也称远程信息处理控制单元&#xff08;Telematics Control Unit, TCU&#xff09;&#xff0c;集成GPS、外部通信接口、电子处理单元、微控制器、移动通信单元和存储器等功能模块。 TBOX 提供的功能有网络接入、OTA、远程控制…...

访问http网页强制跳转到了https的解决办法

目录 解决浏览器自动从 HTTP 重定向到 HTTPS 的问题问题原因&#xff1a;HSTS&#xff08;HTTP Strict Transport Security&#xff09;什么是 HSTS&#xff1f;HSTS 的工作原理 如何解决&#xff1f;1. 清除浏览器的 HSTS 信息在 Chrome 中清除 HSTS 信息&#xff1a;在 Firef…...

3D 生成重建016-SA3D从nerf中分割一切

3D 生成重建016-SA3D从nerf中分割一切 文章目录 0 论文工作1 方法介绍2 实验结果 0 论文工作 1 SAM的背景和目标&#xff1a; SAM 是一种强大的二维视觉基础模型&#xff0c;能够在 2D 图像中进行任意物体的分割。传统上&#xff0c;SAM 在二维空间表现出色&#xff0c;但其无…...

阿里云整理(二)

阿里云整理 1. 访问网站2. 专业名词2.1 域名2.2 域名备案2.3 云解析DNS2.4 CDN2.5 WAF 1. 访问网站 用户使用浏览器访问网站大体分为几个过程&#xff1a; 用户在浏览器输入域名URL&#xff0c;例如www.baidu.com。 不过&#xff0c;浏览器并不知道为该域名提供服务的服务器具…...

qt基本部分控件用法(一)

前言: 以前 windows下做工具主要是MFC&#xff0c;趁有点空时间&#xff0c;研究了QT&#xff0c;感觉跟MFC 差不多&#xff0c;VS 比 QT CREATOR 还是强大&#xff0c;不过QT可以跨平台&#xff0c;功能更强大&#xff0c;MFC 只能在win平台下.&#xff1b; 1&#xff1a;环境…...

【Linux】环境ChatGLM-4-9B 模型之 openai API 服务

一、摘要 最近看到 Function Call 比较感兴趣,它的核心是赋予大模型能够调用外部API的能力,能够解决大模型功能扩展性问题,允许模型调用外部数据库或API,提供特定领域的详细信息;解决信息实时性问题,模型可以实时获取最新数据;解决数据局限性问题,大模型训练数据虽多但…...

Too many open files 问题处理

某个简单的 python 服务&#xff0c;运行一段时间就崩溃。查看日志后发现有一个系统错误 OSError: Errno24 Too many open files要理解这个问题&#xff0c;首先要理解什么是文件描述符&#xff0c;可以参考我的另一篇文章(Linux 系统文件描述符&#xff08;File Descriptor&a…...

CentOS 7 环境下常见的操作和配置

目录 1. CentOS 7 中的 vsftpd 配置与使用 安装与启动 vsftpd 配置 vsftpd&#xff08;/etc/vsftpd/vsftpd.conf&#xff09; 常见命令 2. 使用 yum 包管理器 3. 安全性与防火墙配置 开放端口 4. 使用 systemd 管理服务 5. SELinux 配置 查看 SELinux 状态 临时禁用…...

HTTP(超文本传输协议)

HTTP是万维网通信的基础构成&#xff0c;是一个简单的请求相应协议&#xff0c;基于TCP之上80号端口 通信原理 DNS解析 将域名甩个DNS服务器解析&#xff0c;将域名化为IP访问 建立TCP连接 如图&#xff0c;客户端先发送一个sys置位seq为x&#xff08;任意值&#xff09;的…...

etcd-v3.5release-(3)-readIndexRead

笔记1&#xff1a;读操作包括两种&#xff0c;readIndex和serilizable&#xff0c;readIndex指一致性读&#xff0c;一旦a读到了数据x&#xff0c;那么a及a以后的数据都能读到x&#xff0c;readIndex读会先确认本leader是不是有效地leader&#xff0c;如果有效则记录此刻的comm…...

IPv6 NA RTR/SOL/OVR标志位,单播多播选择,ndppd代理和kernel配置

NA消息用单播还是多播的判断理由 单播回复&#xff08;Unicast&#xff09;&#xff1a; 如果客户端发送 RS 消息时&#xff0c;使用的是一个全局地址或链路本地地址作为源地址&#xff0c;则 RA 消息会单播回复到客户端的源地址。这种方式减少了网络中的广播流量&#xff0c;…...

C语言程序设计P5-4【应用函数进行程序设计 | 第四节】——知识要点:数组作函数参数

知识要点&#xff1a;数组作函数参数 视频&#xff1a; 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 任务要求用选择法对数组中的 10 个整数按由小到大的顺序排序&#xff0c;前面在讲解数组时讲冒泡法排序曾提到选择法排序的思想。 所谓选择法就是…...

PostgreSQL数据库连接:psqlODBC驱动安装与配置实战指南

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;本文将提供详细的psqlODBC驱动程序在Windows操作系统上的安装和配置指南&#xff0c;使用户能够通过ODBC标准连接到PostgreSQL数据库。安装步骤涵盖获取安装文件、运行安装向导、选择安装路径、完成安装以及配置…...

【NLP 8、normalization归一化函数:sigmoid、softmax】

目录 Normalization&#xff08;归一化&#xff09; 1.特点 目的 应用场景 输出范围 2. Sigmoid 函数 目的 应用场景 输出范围 3. Softmax 函数 目的 应用场景 输出范围 "燃尽最后的本能&#xff0c;意志力会带你杀出重围" —— 24.12.2 Normalization&#…...

鸿蒙ArkTS 与安卓Android-底层逻辑对比

鸿蒙OS&#xff08;ArkTS&#xff09; 架构&#xff1a; 鸿蒙OS采用了微内核架构&#xff0c;其核心操作系统将设备的硬件资源和服务进行模块化&#xff0c;微内核负责最基本的服务&#xff08;如调度、通信、同步等&#xff09;&#xff0c;而其他功能则由用户空间的进程提供。…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...