ARM架构基础内容
@TOC
前言
一、AAPCS
AAPCS,全称为ARM Architecture Procedure Call Standard,是ARM架构下的过程调用标准。这个标准定义了在ARM架构中函数调用和返回的约定,以确保不同编译器生成的代码之间的兼容性,以及不同模块之间的互操作性。以下是AAPCS的一些重要概念和约定:
寄存器用途: AAPCS定义了一组通用寄存器,用于传递参数和返回值。在常见的AAPCS规范中,前几个参数(通常是4个或更少)被放置在寄存器 r0-r3 中,其余的参数被放置在栈上。返回值通常存储在 r0 寄存器中,如果返回值为结构体或浮点数,则可能使用多个寄存器来传递。
编写下面这样的一个C函数,然后我们来查看一下他的汇编代码:
int add_val(int a, int b, int c, int d)
{
return a+b+c+d;
}
int mymain()
{
volatile int a = 1;
volatile int b = 2;
volatile int c = 3;
volatile int d = 4;
volatile int sum;
sum = add_val(a, b, c, d);
return 0;
}
汇编代码:
通过下面的汇编代码我们可以知道,最开始的时候会把a,b,c,d这四个数值都保存到栈中,然后通过LDRD汇编指令将这些值依次保存到R0~R3寄存器中。
通过下面的汇编代码可以知道,r0寄存器会报错a+b+c+d的值,故返回值是保存在r0寄存器当中的。
栈的使用: AAPCS规定了如何在函数调用期间使用栈。它定义了栈的增长方向(通常是向低地址方向增长),以及函数调用时如何保存和恢复寄存器的状态。这样可以确保在函数调用期间栈的使用是一致的,使得不同模块之间的函数调用能够正确地协同工作。
对齐规则: AAPCS规定了数据类型的对齐规则,以确保访问数据时的效率和正确性。例如,它规定了不同大小的数据类型应该如何对齐在内存中,以及如何处理结构体和数组的成员对齐。
异常处理: AAPCS也定义了异常处理的约定,包括如何传递异常和中断的参数,以及如何在异常发生时保存和恢复寄存器的状态。
AAPCS是ARM架构生态系统中的重要组成部分,它确保了不同编译器和开发工具生成的代码之间的兼容性,使得不同模块和库可以无缝地集成在一起,构建复杂的嵌入式系统和应用程序。
二、中断调用过程
保存现场:
当中断发生时,处理器会暂停当前执行的任务,并将程序状态和寄存器内容保存到内存中。这通常包括将程序计数器(PC)和程序状态寄存器(PSR)的值保存到栈中,以及可能的其他寄存器内容。
在ARM架构中,R0到R3寄存器通常用于保存参数和临时数据,它们的值通常在函数调用之间需要被保存和恢复。而R4到R11寄存器则被称为“callee-saved registers”(被调用者保存寄存器),在函数调用期间,被调用者负责保存和恢复这些寄存器的值,以确保在函数调用之间的数据不会被破坏。
在中断处理过程中,除了硬件自动保存的PC和PSR寄存器外,通常还需要手动保存其他寄存器的值,以确保被中断的任务可以在恢复现场时继续执行。
处理中断:
一旦中断发生,处理器将控制转移到相应的中断服务程序。这个服务程序可能是预先定义好的,也可能是动态指定的。
在中断服务程序中,处理器可能会执行一些特定的操作,如处理输入/输出设备、响应定时器事件等。这些操作通常与中断的类型和来源有关。
恢复现场:
当中断服务程序完成其任务时,需要将之前保存的现场恢复,以便被中断的任务能够继续执行。
恢复现场的过程涉及将之前保存在栈中的寄存器值重新加载到相应的寄存器中,包括PC和PSR寄存器。
除了硬件自动恢复的PC和PSR寄存器外,还需要手动从栈中取回其他寄存器的值,以确保任务可以从被中断的地方继续执行。
在ARM架构中,由于寄存器R0到R3通常用于参数传递和临时数据,在中断处理期间,这些寄存器的值需要被保存和恢复,以确保被中断的任务可以正确地继续执行。而寄存器R4到R11通常在函数调用之间由被调用者保存和恢复,因此在中断处理中它们的值通常不会被破坏。
三、FreeRTOS中任务切换的实质
在 FreeRTOS 中,任务切换是通过保存和恢复任务的执行环境来实现的,其中栈扮演了关键的角色。下面是任务切换的基本过程:
保存现场: 当 FreeRTOS 决定切换到另一个任务时,它会首先保存当前任务的执行环境,以便稍后能够正确地恢复。这个执行环境包括任务的寄存器状态、栈指针以及其他相关的上下文信息。
切换任务: 一旦当前任务的执行环境被保存,FreeRTOS 就会选择下一个要执行的任务,并将控制权转移到该任务上。这个过程通常涉及任务调度器,它会根据任务的优先级、时间片轮转等策略来选择下一个要执行的任务。
恢复现场: 在切换到新的任务之后,FreeRTOS 会从该任务的执行环境中恢复相关的上下文信息,包括寄存器状态和栈指针。这样,新的任务就可以继续执行,好像它从未被中断过一样。
在这个过程中,栈的作用非常重要。每个任务都有自己的栈空间,用于保存局部变量、函数调用信息以及其他与任务执行相关的数据。当任务切换时,FreeRTOS 会通过调整栈指针来切换到不同任务的栈空间,从而实现任务的切换和上下文的保存与恢复。
FreeRTOS 中的任务切换的实质就是通过保存和恢复任务的执行环境来实现的,其中栈扮演了关键的角色。这种机制保证了多个任务之间的并发执行,并且能够有效地管理任务的上下文切换。
总结
本篇文章主要介绍了ARM架构一些相关的知识和内容,大家可以再熟悉熟悉。
- 点赞
- 收藏
- 关注作者
评论(0)