Arm Cortex-M 软件开发与调试指南
1. 闪存编程流程
下载的闪存编程代码中的闪存编程过程取决于微控制器系统的特性,具体如下:
- 当实现了 TrustZone 安全功能且预加载了安全固件时,下载的闪存编程代码会调用安全固件中的安全固件更新函数来更新闪存。
- 如果未实现 TrustZone 安全功能,或者未预加载安全固件更新函数,下载的闪存编程代码需要包含闪存编程算法并执行闪存编程控制步骤。
2. 软件设计考虑因素
Cortex - M 处理器提供了广泛的调试功能。为了充分利用这些调试功能,软件开发人员应注意以下几点:
1.
低功耗优化
:根据芯片设计,为了让调试器能够持续访问处理器状态和内存,某些低功耗优化可能会被禁用,这可能导致应用在调试期间消耗略多的电量。
2.
低功耗模式
:某些 Cortex - M 设备的低功耗模式可能会导致调试连接丢失。例如,当处理器断电时,调试器将无法访问处理器状态。
3.
SysTick 定时器
:在处理器暂停时,SysTick 定时器会停止,但系统级(处理器外部)的外设可能仍在运行。
4.
调试寄存器
:一般来说,应用代码应避免修改调试寄存器,因为这可能会干扰调试操作。
5.
DWT 数据跟踪
:要使用 DWT 数据跟踪功能,被跟踪的数据应声明为全局或静态变量,以便有固定的地址位置。因为局部变量是在栈内存中动态分配的,没有固定地址,无法被跟踪。
6.
I/O 引脚
:许多设备的 I/O 引脚将调试信号与功能 I/O 特性结合在一起。虽然这些 I/O 引脚在复位后通常分配用于调试,但通过切换调试引脚的功能,可能会使设备无法进行进一步的调试活动。不过,这并不是防止调试连接或阻止访问调试功能的安全方法,因此硅供应商通常会提供其他读出保护功能,以防止第三方读取产品的软件资产。
7.
性能分析
:一些开发工具提供了一系列性能分析功能,使软件开发人员能够优化他们的应用程序。
3. 软件开发概述
使用 Armv8 - M 架构时,会有多种软件开发场景。例如,设备可能实现了 TrustZone 功能,也可能未实现,而且即使实现了,为其创建软件的应用软件开发人员可能也无需了解相关信息。
3.1 典型 Cortex - M 软件项目
基于 CMSIS - CORE 兼容软件驱动的基本软件项目通常包含多个软件文件。设备特定的头文件会引入额外的 CMSIS - CORE 头文件,包括一些通用的 Arm CMSIS - CORE 文件,从而可以访问一系列 CMSIS 功能,如中断管理、SysTick 定时器配置和特殊寄存器访问功能。
使用典型的微控制器设备时,通常可以从微控制器供应商处获取示例软件包。这些示例项目通常包含:
- Cortex - M 处理器的 CMSIS - CORE 头文件。
- 基于 CMSIS - CORE 的设备特定头文件。
- 设备特定的启动代码(可以是汇编语言或 C 语言),可能有针对不同工具链的多个版本。
- 设备驱动程序文件。
- 示例应用程序。
- 项目配置文件,可能有针对不同工具链的多个版本。
为了便于这些重要文件的分发和集成,一些设备特定文件会打包成基于 CMSIS - Pack 标准的软件包。这些软件包使用 XML 文件来指定和详细说明可用的软件组件,使软件开发人员能够:
- 下载和集成必要的和可选的文件。
- 确保满足软件依赖要求。
CMSIS - Pack 支持实用程序通常作为微控制器工具链的一部分集成,在 Keil 微控制器开发套件(MDK)中称为“Pack 安装程序”。此外,Arm 还提供了 CMSIS - Pack Eclipse 插件,使第三方软件开发工具能够利用 CMSIS - Pack。使用 CMSIS - PACK 的优势在于可以轻松创建 Cortex - M 应用程序。不过,也可以不使用 CMSIS - Pack,通过手动将各种文件添加到软件项目中来创建项目,但这需要更多的努力,因为需要确保所有内容都正确就位。或者,也可以从微控制器供应商的示例项目开始,然后进行修改。
3.2 Keil 微控制器开发套件(MDK)概述
在基于 Armv8 - M 的设备上开发软件时,需要一个支持 Armv8 - M 处理器的软件开发工具链。为了演示软件开发过程,很多示例使用了 Keil 微控制器开发套件(MDK),不过还有许多其他工具链,包括微控制器供应商提供的工具链,也支持 Armv8 - M 架构。
Keil MDK 包含以下组件:
- μVision 集成开发环境(IDE)
- Arm 编译工具,包括:
- C/C++ 编译器
- 汇编器
- 链接器及其实用程序
- 调试器,支持多种类型的调试探针,如 Keil 调试探针(ULINK2、ULINK Pro、ULINK Plus)、基于 CMSIS - DAP 的探针,以及一些第三方产品,如 ST - LINK(来自意法半导体,多个版本)、Silicon Labs 的 UDA 调试器和 NULink 调试器。
- 模拟器
- RTX 实时操作系统内核
- 支持 CMSIS - PACK,使软件开发人员能够访问超过 6000 个微控制器的参考软件包,这些软件包包括设备特定的头文件、程序示例、闪存编程算法等。
- 某些版本的 Keil MDK 还可选包含中间件,如 USB 栈、TCP/IP 栈。
Keil 提供了各种版本的 MDK,并且一些特定微控制器供应商的微控制器设备可以使用免费版的 Keil MDK。因此,开始开发时不需要花费太多资金,只需考虑开发板的成本,因为许多开发板都内置了低成本的调试探针。
3.3 典型程序编译流程
使用 Keil MDK 的项目,其典型程序编译流程由集成开发环境(IDE)处理。创建项目后,只需几个简单步骤即可对微控制器进行编程并测试应用程序。
需要注意的是,Keil MDK 包含两种类型的 C 编译器:
- Arm 编译器 6:这是最新版本,支持 Armv8 - M 架构。
- Arm 编译器 5:这是上一代 C 编译器,不支持 Armv8 - M 架构。
由于从 Arm 编译器 5 切换到 Arm 编译器 6(基于不同的编译器技术),一些特定于编译器的功能发生了变化。因此,在某些情况下,为 Arm 编译器 5 创建的 C 代码可能需要更新(例如,函数属性、嵌入式汇编器的使用)。
3.4 从头创建新项目
开发新软件时,最简单的方法是复用微控制器供应商的现有项目示例。不过,为了演示 MDK 开发工具的工作原理,以下是从头创建一个基于 Keil MDK 的新项目的步骤:
1.
安装软件包
:启动 μVision IDE 后,如果是首次运行 Keil MDK,Pack 安装程序会自动启动。建议使用 Pack 安装程序安装正确的软件包并更新可能过时的软件包。可以通过工具栏访问 Pack 安装程序。选择所需的硬件平台(如 “IOTKit_CM33_FP”),然后点击“安装”按钮安装所需的软件包。如果软件组件旁边的按钮显示“更新”,则点击该按钮进行更新。
2.
创建新项目
:点击下拉菜单中的“新项目”选项,IDE 会要求输入项目的位置和名称。
3.
选择微控制器设备
:输入项目名称和位置后,需要选择项目中要使用的微控制器设备。例如,选择基于 Cortex - M33 处理器且带有 FPU 的 “IOTKit_CM33_FP” 硬件平台。设备列表中的设备基于已安装的 CMSIS - Pack,如果所需设备不在列表中,说明该设备的 CMSIS - Pack 未安装或不存在。
4.
选择软件组件
:选择所需的微控制器设备后,会显示“管理运行时环境”窗口,可在此选择一系列软件组件。默认情况下,Keil MDK 会按组导入指定的软件组件。
5.
添加应用代码
:创建项目并选择所需的软件组件后,下一步是添加应用代码(即 C 程序)。右键点击“源组 1”,选择“添加新项到组…”,选择文件类型并输入文件名。以下是一个控制 LED 闪烁的示例代码:
// Device specific header
#include "IOTKit_CM33_FP.h" /* Device header */
#include "Board_LED.h"
/* ::Board Support:LED */
int main(void)
{
int i;
LED_Initialize();
while (1) {
LED_On(0);
for (i = 0; i < 100000; i++) {
__NOP();
}
LED_Off(0);
for (i = 0; i < 100000; i++) {
__NOP();
}
}
}
-
编译项目
:所有源文件准备好后,可以通过以下方式编译项目:
- 点击工具栏上的“构建目标”图标。
- 从下拉菜单中选择“项目 -> 构建目标”。
- 在项目浏览器中右键点击“目标 1”,选择“构建目标”。
- 使用“F7”热键。
编译项目后,会生成一个名为 “example1.axf” 的可执行映像。在将程序下载到开发板并进行测试之前,还需要执行以下步骤:
1.
检查调试探针驱动
:检查是否需要安装调试探针的设备驱动,如果需要,则安装所需的设备驱动。
2.
更新调试设置
:更新调试设置,选择正确的调试探针并配置所需的设置。可以通过以下方式访问调试设置:
- 在项目浏览器中右键点击“目标 1”,选择“目标 ‘目标 1’ 的选项”。
- 从下拉菜单中选择“项目 -> 目标 ‘目标 1’ 的选项”。
- 使用热键 Alt - F7。
- 点击工具栏上的目标选项按钮。
项目选项窗口打开后,顶部有多个选项卡。需要注意的是:
- 内存映射设置、C 预处理宏和闪存编程选项应根据 CMSIS - Pack 中提供的信息正确配置。
- 一些项目选项(如项目是否使用 FPU 以及时钟速度设置)需要软件开发人员根据应用需求进行配置。
- 调试探针选项(在“调试”选项卡下)需要软件开发人员根据使用的调试探针进行配置。
例如,使用 Keil 的 ULINKPro 调试探针时,需要在调试选项中选择正确的调试探针,然后点击“设置”按钮,定义以下方面的调试设置:
- JTAG 或串行线调试连接协议和连接速度
- 程序“下载”和复位选项
- 跟踪选项(在“跟踪”选项卡下)
- 闪存编程选项(在“闪存下载”选项卡下)
- 调试设置序列(在“Pack”选项卡下,可选,可用于设置调试认证控制序列)
由于示例中使用的是 FPGA 板(没有闪存),所以闪存编程选项中只剩下“不擦除”选项可供选择。通常,使用标准微控制器时,需要定义闪存编程算法。
调试设置正确设置且开发板连接并通电后,调试器工具可以通过“调试设置”窗口检测 JTAG 或串行线调试接口是否已连接。如果连接成功,会显示一个 IDCODE。此时,可以关闭项目选项窗口,并通过以下方式启动调试会话:
- 使用下拉菜单“调试 -> 开始/停止调试会话”。
- 使用 Ctrl - F5 热键。
- 点击工具栏上的相应按钮。
调试器窗口出现后,可以通过以下方式启动程序执行:
- 点击下拉菜单中的“调试 -> 运行”选项。
- 使用 F5 热键。
- 点击工具栏上的“运行”按钮。
下面是创建新项目的流程图:
graph LR
A[启动 μVision IDE] --> B{首次运行?}
B -- 是 --> C[自动启动 Pack 安装程序]
B -- 否 --> D[可手动访问 Pack 安装程序]
C --> E[安装/更新软件包]
D --> E
E --> F[点击新项目选项]
F --> G[输入项目位置和名称]
G --> H[选择微控制器设备]
H --> I[选择软件组件]
I --> J[添加应用代码]
J --> K[编译项目]
K --> L[检查调试探针驱动]
L --> M[更新调试设置]
M --> N[启动调试会话]
N --> O[启动程序执行]
通过以上步骤,软件开发人员可以使用 Keil MDK 完成基于 Arm Cortex - M 处理器的软件开发和调试工作。在实际开发过程中,还需要根据具体的项目需求和硬件平台进行适当的调整和优化。
4. 调试设置详细说明
4.1 调试探针选择与配置
在更新调试设置时,选择正确的调试探针至关重要。不同的调试探针具有不同的特点和适用场景,以下是常见调试探针的简要介绍:
| 调试探针 | 特点 | 适用场景 |
| ---- | ---- | ---- |
| Keil ULINKPro | 功能强大,支持多种调试模式和协议,与 Keil MDK 兼容性好 | 适用于大多数基于 Keil MDK 的开发项目 |
| CMSIS - DAP 探针 | 开源、低成本,广泛支持各种 Cortex - M 设备 | 适合初学者和对成本敏感的项目 |
| ST - LINK | 由意法半导体提供,专门针对 STM32 系列微控制器优化 | 用于 STM32 微控制器的开发和调试 |
选择调试探针后,点击“设置”按钮,需要配置以下关键参数:
1.
连接协议和速度
:根据硬件平台和调试需求,选择合适的 JTAG 或串行线调试连接协议,并设置连接速度。较高的连接速度可以提高调试效率,但可能会受到硬件限制。
2.
下载和复位选项
:配置程序“下载”和复位选项,确保程序能够正确下载到目标设备并在下载后进行复位操作。
3.
跟踪选项
:在“跟踪”选项卡下,可以启用和配置 DWT 数据跟踪、ETM 跟踪等功能,以便对程序的执行过程进行详细分析。
4.
闪存编程选项
:对于具有闪存的微控制器,需要定义闪存编程算法,确保程序能够正确写入闪存。在使用 FPGA 板时,由于没有闪存,闪存编程选项可能会有所不同。
5.
调试设置序列
:在“Pack”选项卡下,可以设置调试认证控制序列等可选参数,增强调试的安全性。
4.2 项目选项配置要点
项目选项窗口中的配置参数对项目的编译和调试有重要影响。以下是一些关键配置要点:
1.
内存映射设置
:根据目标设备的内存布局,正确配置内存映射,确保程序能够正确加载和运行。
2.
C 预处理宏
:定义 C 预处理宏可以控制代码的编译行为,例如启用或禁用某些功能模块。
3.
FPU 使用和时钟速度设置
:根据应用需求,决定项目是否使用 FPU,并设置合适的时钟速度。FPU 可以提高浮点运算性能,但会增加功耗。
4.
调试探针选项
:根据使用的调试探针,配置相应的调试选项,确保调试器能够正常连接和工作。
5. 常见问题及解决方法
在使用 Keil MDK 进行软件开发和调试过程中,可能会遇到一些常见问题。以下是一些常见问题及解决方法:
1.
编译错误
:
-
找不到头文件
:检查头文件的路径是否正确,确保所需的 CMSIS - CORE 头文件和设备特定头文件已正确安装。
-
语法错误
:仔细检查代码中的语法错误,特别是函数调用、变量声明等方面。
-
编译器不兼容
:如果使用 Arm 编译器 6 编译为 Arm 编译器 5 编写的代码,可能会出现兼容性问题。参考 Keil 应用笔记,对代码进行相应的更新。
2.
调试连接问题
:
-
调试探针未识别
:检查调试探针的连接是否正确,确保设备驱动已正确安装。
-
调试接口未连接
:检查开发板的 JTAG 或串行线调试接口是否连接正常,尝试重新插拔调试探针。
-
IDCODE 未显示
:如果调试器无法检测到 IDCODE,可能是硬件故障或调试设置不正确。检查硬件连接和调试设置,确保连接协议和速度配置正确。
3.
程序运行异常
:
-
程序崩溃
:检查代码中的内存访问错误、栈溢出等问题,使用调试器进行单步调试,定位问题所在。
-
功能异常
:如果程序的某些功能无法正常工作,检查相关的硬件驱动和代码逻辑,确保功能模块正确实现。
6. 总结与建议
6.1 总结
本文详细介绍了 Arm Cortex - M 处理器的软件开发和调试过程,包括闪存编程流程、软件设计考虑因素、Keil MDK 的使用方法以及从头创建新项目的步骤。通过合理利用 Cortex - M 处理器的调试功能和 Keil MDK 的强大工具集,软件开发人员可以高效地进行项目开发和调试。
6.2 建议
- 充分利用 CMSIS - Pack :CMSIS - Pack 提供了丰富的软件组件和示例代码,能够大大简化项目的开发过程。建议软件开发人员充分利用 CMSIS - Pack,提高开发效率。
- 注意编译器兼容性 :在使用 Keil MDK 时,要注意 Arm 编译器 5 和 Arm 编译器 6 的兼容性问题。对于新开发的项目,建议使用 Arm 编译器 6 以获得更好的性能和功能支持。
- 重视调试技巧 :掌握调试技巧是提高软件开发效率的关键。建议软件开发人员熟练掌握调试器的使用方法,如单步调试、断点设置、变量监视等,以便快速定位和解决问题。
- 持续学习和实践 :Arm Cortex - M 处理器和相关开发工具不断发展和更新,软件开发人员需要持续学习和实践,跟上技术的发展步伐。
以下是软件开发和调试的关键步骤总结表格:
| 步骤 | 描述 |
| ---- | ---- |
| 闪存编程 | 根据微控制器系统特性选择合适的编程方式 |
| 软件设计 | 考虑低功耗优化、调试寄存器等因素 |
| 项目创建 | 复用示例项目或从头创建,使用 CMSIS - Pack 简化流程 |
| 编译项目 | 选择合适的编译器,处理兼容性问题 |
| 调试设置 | 选择调试探针,配置连接协议、下载选项等 |
| 调试运行 | 启动调试会话,使用调试技巧定位问题 |
通过遵循以上步骤和建议,软件开发人员可以更加顺利地进行 Arm Cortex - M 处理器的软件开发和调试工作,开发出高质量的嵌入式应用程序。
最后,为了更清晰地展示整个软件开发和调试的流程,下面给出一个综合的流程图:
graph LR
A[软件设计考虑] --> B[项目创建]
B --> C{是否使用 CMSIS - Pack?}
C -- 是 --> D[安装/更新软件包]
C -- 否 --> E[手动添加文件]
D --> F[选择微控制器设备]
E --> F
F --> G[选择软件组件]
G --> H[添加应用代码]
H --> I[编译项目]
I --> J[检查调试探针驱动]
J --> K[更新调试设置]
K --> L[启动调试会话]
L --> M[调试程序运行]
M --> N{是否存在问题?}
N -- 是 --> O[定位并解决问题]
O --> I
N -- 否 --> P[项目完成]
希望本文能够为软件开发人员在 Arm Cortex - M 处理器的开发和调试过程中提供有价值的参考和指导。在实际应用中,要根据具体的项目需求和硬件平台进行灵活调整和优化。
超级会员免费看
2281

被折叠的 条评论
为什么被折叠?



