当前位置: 首页 > 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;而其他功能则由用户空间的进程提供。…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...