结合AliOS Things谈嵌入式系统通用问题定位方法(1):CPU相关基础

简介: 本文着重从问题定位的角度来介绍如何定位嵌入式软件系统中的问题,并结合AliOS Things提供的部分维测手段来介绍

1、背景介绍
本文着重从问题定位的角度来介绍如何定位嵌入式软件系统中的问题,并结合AliOS Things提供的部分维测手段来介绍。

AliOS Things目前已经提供了丰富的Debug维测功能、离线的脚本解析,以及可视化的IDE工具来让用户快速上手使用我们的维测功能;相关的维测功能和工具也在实际开发项目中不断完善。

完善的维测工具一直是AliOS Things的主要发展的方向;但是从另一个方面来说,工具本身的作用也是有限的,嵌入式系统出现的问题可以说是千变万化;不同的开发者,对于工具提供的信息理解也不尽相同。我们在熟悉使用基本的维测工具的同时,还需要了解底层问题定位的基础知识,基本的定位手段和思路。解Bug的技术思路和维测工具的完善应该是相辅相成,相互促进的。

本文介绍了部分常用的嵌入式问题定位的基础知识和基本的手段。其中涉及到的AliOS Things内核一些已有的工具,以及一些内容的拓展和深入,读者可以自行了解和学习。

结合AliOS Things谈嵌入式系统通用问题定位方法(2):内核相关基础

结合AliOS Things谈嵌入式系统通用问题定位方法(3):问题定位思路

1.1、对象
嵌入式内核和驱动开发测试人员

协议栈、中间件开发测试人员

上层APP组件开发测试人员

1.2、目的
如何从底层软件源头上开始解bug

如何快速确认分流大量bug

从问题本身理解规范性代码如何编写

1.3、内容
结合AliOS Things内核来介绍:

解bug的必要知识点

解bug的通用方法、步骤、关键点

AliOS Things提供定位问题的手段、工具

本文介绍的内容主要以ARMv7架构为例,编译器为gcc。

2、CPU相关基础点
(以ARMv7a为例)

2.1、基础架构
image.png

Monitor:安全非安全

Hypervisor: 虚拟化

PL1:特权模式

PL0:用户模式

内核的内核态对应CPU的特权模式;

内核的用户态对应CPU的用户模式。

对于PL1,有7种子模式,我们主要关注:

SVC:内核正常运行模式

IRQ:中断进入模式

UND: 指令异常

ABT:数据异常

CPU当前状态可通过CPSR尾部的Mode状态寄存器来获取:

.equ CPSR_Mode_USR, 0x10

.equ CPSR_Mode_FIQ, 0x11

.equ CPSR_Mode_IRQ, 0x12

.equ CPSR_Mode_SVC, 0x13

.equ CPSR_Mode_ABT, 0x17

.equ CPSR_Mode_UND, 0x1B

.equ CPSR_Mode_SYS, 0x1F

2.2、基础寄存器

32bit ARM汇编有16个32位寄存器:

  • r0-r3 主要用来传递函数调用第1到第4个参数(a0-a3),更多的参数须通过栈来传递。
  • r0-r1也作为结果寄存器,保存函数返回结果;被调用的子程序在返回前无须恢复这些寄存器的内容。
  • r4-r9 为被调保存(callee-save)寄存器,一般保存内部局部变量(local variables)。
  • r7 大部分情况用来保存系统调用号(syscall number)。
  • r9 某些变体可能当作特殊寄存器。
  • r10(SL)被调保存寄存器,Stack Limit。
  • r11(FP)被调保存寄存器, 帧指针(Flame Pointer)。
  • r12(IP)特殊寄存器,栈寄存器(Intra Procedure)。
  • r13(SP)特殊寄存器,栈指针,类似x86_64中的RSP。
  • r14(LR)特殊寄存器。Link Register.
  • r15(PC)特殊寄存器。Program Counter (like RIP in x86_64 & EIP in x86)

其中注意几点:每个模式下SP(R13)独立,PC只有一个,LR独立,SPSR自动保存着进入该模式前的CPSR。Fiq比较特殊,R8~R14都是独立的。

image.png

2.3、协处理器
ARM体系架构支持协处理器,用于扩展ARM处理器功能。协处理器指令用于访问协处理器。协处理器支持16个协处理器,编号0-15,使用CP0-CP15描述。

CP15:提供系统控制功能。包括架构和特性ID,以及控制,状态信息和配置支持。
CP14:提供硬件Debug功能。
CP10,CP11:共同支持浮点运算和向量操作。控制和配置浮点和高级SIMD扩展架构。
CP8,9,12,13:为ARM架构保留协处理器。
CP0-7:由厂家定义协处理功能

2.4、基础指令
ARM提供两种指令编码格式:Thumb(2)、ARM指令集

ARM指令集每条指令固定为4 字节大小;

Thumb(2)指令集每条指令为2或者4字节大小;

具体细节不在此赘述。

2.5、压栈出栈相关
压栈出栈指令可以用下面表格来概括:
image.png

其中LDM的后缀对应关系:

FA: full + add 满增

FD:full + decrease 满减

EA:empty + add 空增

ED:empty + decrease 空减

IA: increment after 先取值,SP后增加

IB: increment before SP先增加,后取值

DA: decrement after 先取值,SP后减小

DB: decrement before SP先减小,后取值

目前一般使用的是:

LDMIA :弹栈时,先取SP内数据,后SP地址增大

STMDB :压栈时,SP地址先减小,后开始存放数据

2.6、异常
异常寄存器:

主要关注四个寄存器,来判断访问哪个地址出现了何种异常:

DFSR:数据异常状态寄存器

DFAR:导致数据异常的地址

IFSR:指令异常状态寄存器

IFAR:导致指令异常的地址

2.7、MMU/MPU相关

对于MPU和MMU的细节,用户可不需要关注。但是需要了解基本概念。

MPU针对ARM-M系列,可以设定特殊内存段的属性是特权还是非特权访问,没有虚拟和物理的映射;

MMU针对ARM-A系列,包含虚拟和物理的映射,以及各种权限的控制。

M系列的用户态有特权和非特权之分;

A系列的用户态即对应最小用户权限模式。

对于访问地址的权限问题,有时需要查看MMU页表,去核对属性。

容易遇到的问题:

访问权限问题,如代码段数据段的权限问题
页表覆盖导致内存空间冲突问题

2.8、函数/数据断点
函数和数据断点是CPU提供的基本调式Debug功能。

对应gdb的对函数打断点,watch监控某一块内存的修改访问,以及进一步的单步调试功能。

2.9、编译汇编链接相关

2.9.1、需关注编译选项
Cpu相关:

-mcpu=cortex-a7 :指定cpu架构

-mfpu=neon-vfpv4 :浮点数、neno指令

-mfloat-abi=hard :软硬浮点

emu相关:

-fshort-enums:

sizeof(enum1)不增加这个-fshort-enums选项的时候为4,增加后为该enum实际可以存放的最小字节数据类型,如1字节。

默认不设定,一旦设置就选用节省内存的enum长度

编译告警相关:

-Wall : 编译显示所有告警

-Werror: 所有的警告当成错误进行处理

-Wfatal-errors:出现错误停止编译

-w : 关闭告警

需要使用gdb查看详细的数据结构信息:

加入-g选项

2.9.2、汇编注意点

函数跳转指令(B、BL、BLX):

BL 和 BLX 指令可将下一个指令的地址复制到 LR(r14,链接寄存器)中。

BX 和 BLX 指令可将处理器的状态从 ARM 更改为 Thumb,或从 Thumb 更改为 ARM。

BLX label 无论何种情况,始终会更改处理器的状态。

BX Rm 和 BLX Rm 可从 Rm 的位 [0] 推算出目标状态:

如果 Rm 的位 [0] 为 0,则处理器的状态会更改为(或保持在)ARM 状态

如果 Rm 的位 [0] 为 1,则处理器的状态会更改为(或保持在)Thumb 状态。

反汇编别名:

在查看汇编时,通用寄存器会有特殊的别名,常用对应如下:

R10 sl 栈限制

R11 fp 桢指针

R12 ip

R13 sp 栈指针

R14 lr 连接寄存器

R15 pc 程序计数器

函数入参传递:

对于ARM-32位处理器,R0、R1、R2、R3寄存器分别作为函数的第0个至第3个入参,超出入参使用栈空间;

32位函数出参统一使用R0。

调用者报错和被调用者保存的寄存器:

被调用函数只会保存被自己上下文修改的R4开始的寄存器,R0~R3由调用栈按需保存。

指令编码:

每条指令都有固定的编码格式,否则就是非法指令。动态加载/调用栈解析等会有对指令修改的操作,一般对定位问题有两个小用途:

看开栈大小:主要有没有定义过大的数组,通过sub sp的指令来搜索立即数的大小;
e24dd014 sub sp, sp, #20

强制修改指令
在代码段可修改的情况下,强制修改指令,达到某种如进入死循环,强制跳转的目的

2.9.3、ELF结构相关
ELF内是比较复杂的数据结构,其中分可重定位文件(.o)、共享目标文件(.so)、以及可执行文件(elf)。二进制bin文件不属于elf格式,而是没有elf的头部和相关符号等信息,纯碎装载的可执行段的二进制文件。内部结构比较复杂,只介绍基本定位问题使用的。

Elf中的section:一般在ld中可见定义的描述,如下面即是一个section

.data : {

__data_start = .;

*(.data)

(.data.)

__data_end = .;

} > DRAM_ADDR

Elf中的段:在最后链接时,链接器会将各个section组合成最终的几个段,当然可以在ld中显示地关联段。

Section一般存在于尚未链接的可重定位文件,最终生成可执行的elf中都是组合的段信息

image.png

基本查看ELF信息的编译器工具:

查看ELF头部信息、段组成

arm-none-eabi-readelf -lS ./helloworld@developerkit.elf

结果示例:

image.png

image.png

Elf转汇编

localhost: arm-none-eabi-objdump -d ./helloworld@developerkit.elf

查找符号

localhost: arm-none-eabi-nm ./helloworld@developerkit.elf | grep aos_init
 
080021f8 T aos_init

相关信息也可通过map文件,其同样也是通过elf生成。

addr2line

localhost: arm-none-eabi-addr2line -e ./helloworld@developerkit.elf 0x80021f8
 
/workspace/aos_gerrit_new/core/osal/aos/rhino.c:815

通过指令地址,导出对应C的文件名和行数

对于C++一般使用 –pfiCe选项

C++函数名
汇编中C++的函数名非常复杂,可通过下面命令输入正常的函数名:

localhost: arm-none-eabi-c++filt smartbox@mt8153a-mk.app.elf _ZN17GwMeshControlInfoD1Ev smartbox@mt8153a-mk.app.elf
 
GwMeshControlInfo::~GwMeshControlInfo()

开发者技术支持
如需更多技术支持,可加入钉钉开发者群,或者关注微信公众号
image.png

相关文章
|
3月前
|
缓存 开发者 测试技术
跨平台应用开发必备秘籍:运用 Uno Platform 打造高性能与优雅设计兼备的多平台应用,全面解析从代码共享到最佳实践的每一个细节
【8月更文挑战第31天】Uno Platform 是一种强大的工具,允许开发者使用 C# 和 XAML 构建跨平台应用。本文探讨了 Uno Platform 中实现跨平台应用的最佳实践,包括代码共享、平台特定功能、性能优化及测试等方面。通过共享代码、采用 MVVM 模式、使用条件编译指令以及优化性能,开发者可以高效构建高质量应用。Uno Platform 支持多种测试方法,确保应用在各平台上的稳定性和可靠性。这使得 Uno Platform 成为个人项目和企业应用的理想选择。
66 0
|
Linux 开发者
Linux嵌入式驱动开发——platform机制的使用(led驱动示例实现)
Linux嵌入式驱动开发——platform机制的使用(led驱动示例实现)
297 0
Linux嵌入式驱动开发——platform机制的使用(led驱动示例实现)
|
开发工具 芯片 开发者
5.6 芯片SDK开发:硬件无关组件相关开发|学习笔记
快速学习5.6 芯片SDK开发:硬件无关组件相关开发
5.6 芯片SDK开发:硬件无关组件相关开发|学习笔记
|
Linux 编译器 Shell
arm嵌入式Linux系统移植实例过程及问题
arm嵌入式Linux系统移植实例过程及问题
512 0
|
前端开发 Java 编译器
【译】eBPF 概述:第 4 部分:在嵌入式系统运行
【译】eBPF 概述:第 4 部分:在嵌入式系统运行
715 0
|
编解码 JavaScript IDE
RISC-V生态开发套件解析(五):LicheeRV 86开发板BSP SDK开发和Xboot 镜像体验
随着RISC-V生态的蓬勃发展,相关开源开发套件也开始逐渐丰富。为了帮助开发者快速了解、玩转新推出的RISC-V开发套件,OCC推出RISC-V生态开发套件解析系列内容,详细讲解生态开发套件的功能特点与上手教程。
510 0
RISC-V生态开发套件解析(五):LicheeRV 86开发板BSP SDK开发和Xboot 镜像体验
|
存储 物联网 Linux
AliOS Things操作系统之中断管理
前言本文主要介绍AliOS Things中断相关的概念。由于中断处理与CPU架构密切相关,所以本文会基于HaaS100开发板/HaaS EDU K1所使用的ARM Cortex-M3的CPU架构,来介绍AliOS Things的中断管理机制。读完本文,大家将深入了解AliOS Things的中断处理过程、如何添加中断服务程序(ISR)以及相关的注意事项。AliOS Things 中断管理硬件中断行
580 0
AliOS Things操作系统之中断管理
|
NoSQL 安全 IDE
结合AliOS Things谈嵌入式系统通用问题定位方法(1):CPU相关基础
本文着重从问题定位的角度来介绍如何定位嵌入式软件系统中的问题,并结合AliOS Things提供的部分维测手段来介绍。
结合AliOS Things谈嵌入式系统通用问题定位方法(1):CPU相关基础
|
监控 IDE 物联网
结合AliOS Things谈嵌入式系统通用问题定位方法(2):内核相关基础
内核提供的任务创建接口,会存在参数指定当前任务创建完立即运行还是需要显示调用start运行,需要注意。如果在创建任务时指定了立即执行,而在创建任务后去设置任务参数,可能是不生效的。(尤其posix的pthread接口经常遇到这种问题)
结合AliOS Things谈嵌入式系统通用问题定位方法(2):内核相关基础
|
监控 物联网 测试技术
下一篇
无影云桌面