引言
我们在初学STM32,GD32等ARM内核的MCU时,常常是先点亮一颗LED灯, 我们使用HAL库或是标准库编写代码,再利用Keil和ST-Link 将固件下载进STM32单片机,很快的就可以做出LED灯闪烁的实验,无疑,这对新手来说确实是件 成就感拉满 的事,但如果您想深入搞懂 ARM单片机,只会使用HAL库还远远不够, 您有必要更深入的学习ARM内核。我会手把手带着您。在不使用HAL库的条件下完成LED灯的闪烁实验。相信您在和本栏目一起成长的过程中一定能取得很大的进步,对ARM内核和ARM单片机有更深的理解。
0x03
上一期 芯片架构介绍 (X86 , ARM, RISC-V) 点击 -> 传送门
这是深入学习ARM架构专栏的 第三篇文章, 感谢您的观看,欢迎批评指正!
ARM微控制器是怎样构成的
了解ARM微控制器的构成有助于优化性能、提升开发效率和增强问题解决能力。通过掌握其架构,开发者可以编写更高效的代码,合理配置硬件资源,并快速定位问题。此外,深入理解微控制器有助于硬件和软件的协同开发,特别是在嵌入式系统中,能够根据项目需求灵活调整,充分发挥ARM的低功耗、高性能优势。这对提高嵌入式系统的整体表现非常重要。
ARM微控制器的构成通常包括以下几个核心部分:
-
ARM处理器内核:这是微控制器的核心,负责指令执行和数据处理。不同的微控制器使用不同的ARM内核(如Cortex-M系列)以满足性能和功耗需求。
-
存储器:包括闪存(Flash)用于存储程序代码,和SRAM用于存储运行时数据。
-
外设接口:用于与外部设备通信,如UART、SPI、I2C等接口,用于数据传输和设备控制。
-
中断系统:负责管理硬件和软件中断,保证及时响应外部事件。
-
时钟系统:提供处理器和外设的时钟信号,控制系统的速度和功耗。
这些组成部分紧密协作,形成一个完整的微控制器系统,广泛应用于嵌入式开发中。
需要准备的软件和硬件
软件:
- Keil微控制器开发套件(MDK-ARM)
- GNU Compiler Collection(GCC) (CLion, STM32-IDE等)
硬件:
- 有一块STM32开发板(没有也无所谓, 可以使用模拟器)
- 调试适配器(ST-Link, DAP-Link, J-LInk等)有一种即可
以上是本文,所需的软件和硬件,相信在这之前你应该比较熟悉STM32代码的编写和下载调试了吧。 这是本文所希望的, 若你不了解, 那我建议你先学习STM32的基本应用,再来阅读本文,因为一开始就来从底层学起,这或许不是个好方法。因此你可以收藏本文,方便日后进阶时使用。
软件开发流程
注: (本图来源: Joseph YiuO - ARM Cortex-M3与Cortex-M4权威指南)
STM32软件开发流程通常包括以下步骤:
- 需求分析与硬件选择:明确项目需求,选择合适的STM32微控制器型号,并了解其资源和外设。
- 开发环境配置:安装开发工具链,如STM32CubeIDE、Keil或IAR,安装STM32CubeMX用于生成初始化代码。
- 项目创建与初始化:使用STM32CubeMX配置芯片外设、引脚和时钟,并生成基础初始化代码。
- 编写应用代码:在生成的项目中,编写应用层代码,包括主循环、外设驱动、通信协议等。
- 编译与下载:编译项目,使用调试器(如ST-LINK)将程序下载到STM32微控制器中。
- 调试与验证:通过断点、变量监控等调试工具,测试并验证软件的功能和性能。
这个流程帮助开发者快速、高效地进行STM32嵌入式系统开发。
我们需要知道, 基本上所有的Cortex-M微控制器都用Flash存储器存放程序,在创建完程序映像后,需要将程序下载到微控制器的Flash存储器中。为了实现这一目的,若微控制器板上没有内置的调试适配器,还得另外准备一个。实际的编程过程可能非常复杂,不过这些工作是全部由IDE实现的,用户只需要单击一下鼠标就可以完成整个编程过程。
我们会 先使用 Kei 去完成 项目的 构建和下载,在后面的文章中,我会教大家使用 Makefile去构建项目, 我知道你可能和我当初一样,十分抗拒 Makefile , 但使用它去调用原生的 编译,链接命令, 这会让我们对C文件到可执行文件有深入的理解。
编译应用程序
编译应用程序的流程是十分重要的, C文件, 头文件, O文件,BIN文件, 相信你肯定比较熟悉,但是 链接文件 很多人应该不太了解吧 , 没关系,在后面的文章里,我们还会深入研究上图, 利用Makefile构建项目!
程序流程
轮询
程序执行流程中的轮询是一种反复检查某个条件是否满足的机制,执行流程如下:
-
系统初始化:初始化硬件和外设,如传感器、通信接口或定时器等。
-
进入主循环:
- 程序进入一个无限循环。
- 不断检查各个外设的状态或某些条件是否满足,如传感器数据、按键状态、数据接收标志等。
-
状态检查:每次循环中,依次检查外设或条件状态:
- 如果满足条件(例如按键被按下),则执行相应处理逻辑。
- 如果不满足,跳过并继续检查下一个外设或条件。
-
处理任务:当发现某个状态满足时,程序立即执行相关任务,如处理数据、发送响应或控制设备。
-
循环继续:处理完毕后,返回主循环继续下一轮轮询。
这种方式适用于简单任务的实现,但可能导致 CPU 忙于反复检查,无法高效处理其他任务。
中断
在程序执行流程中,中断是一种高效的事件处理机制,它允许微控制器在特定事件发生时立即响应,流程如下:
-
系统初始化:
- 初始化硬件、外设和全局变量。
- 配置中断源(如定时器、GPIO、串口等),并使能中断。
-
进入主循环:
- 程序进入主循环,执行主任务(如数据处理、状态监控等),但不需主动轮询特定事件。
-
中断事件发生:
- 当某个外设或事件(如按键按下、数据接收、定时器溢出)触发中断时,当前程序执行被暂停,微控制器自动跳转到相应的中断服务程序(ISR)。
-
中断处理:
- 在中断服务程序中,执行与事件相关的任务,如读取传感器数据、发送响应或处理通信数据。
- 中断处理通常短小精悍,尽快处理完毕后返回。
-
恢复主程序:
- 中断处理完成后,程序会恢复到中断前的执行点,继续运行主任务。
中断机制能够提高程序实时性,减少轮询带来的CPU资源浪费,非常适合处理高优先级或时间敏感的任务。
多任务系统
在多任务系统中,程序执行流程采用任务调度机制,使多个任务并发执行,流程如下:
-
系统初始化:
- 初始化硬件和操作系统内核(如FreeRTOS)。
- 创建任务,定义每个任务的优先级和执行函数。
-
任务调度器启动:
- 启动任务调度器(Scheduler),根据任务的优先级或调度策略分配CPU时间。
-
任务执行:
- 任务以“时间片”或“优先级”的方式执行。调度器按顺序分配CPU给不同任务,保证任务在不同时间段运行。
- 每个任务独立运行,完成一定工作后进入等待状态(如等待中断、信号、超时等)。
-
任务切换:
- 当一个任务进入等待状态或时间片用尽时,调度器切换到其他任务,确保多个任务轮流执行。
- 任务间可以通过消息队列、信号量或事件标志进行通信与同步。
-
中断处理:
- 在多任务系统中,中断可以打断当前正在执行的任务,处理完中断后恢复任务调度。
-
任务完成:
- 任务可以结束或持续运行,调度器持续管理任务的调度与执行。
多任务系统的关键是调度器,它确保不同任务间公平竞争CPU资源,实现并发执行和高效资源管理。
特性 | 轮询 | 中断 | 多任务系统 |
---|---|---|---|
响应时间 | 较慢,需要不断循环检查 | 快速响应,立即处理事件 | 依任务优先级或调度策略,响应时间可调 |
CPU利用率 | 较低效,CPU常空转 | 高效,只有事件发生时才占用CPU | 高效,任务间共享CPU资源 |
复杂度 | 简单,易于实现 | 复杂,需要配置中断和管理优先级 | 较复杂,需要操作系统支持和任务管理 |
适用场景 | 简单系统,实时性要求不高 | 实时性要求高的场景 | 复杂系统,多任务并发执行 |
功耗 | 高,CPU持续工作 | 低,CPU在空闲时可进入低功耗模式 | 中等,取决于任务调度和空闲管理 |
可扩展性 | 差,难以处理多任务 | 可扩展性有限,主要用于事件驱动场景 | 高,可轻松扩展多个任务并管理复杂系统 |
实现难度 | 简单,代码逻辑直接 | 需要较多硬件知识,难度中等 | 较高,需要操作系统或调度机制支持 |
实时性 | 差,取决于轮询频率 | 高,可实现精确的实时响应 | 取决于调度策略和任务优先级 |
资源占用 | 高,CPU频繁被占用 | 低,资源仅在事件发生时消耗 | 中等,系统资源被多个任务共享 |
上表深入对比了 轮询,中断 和 多任务系统的优缺点。 ARM嵌入式软件开发中,RTOS是十分重要的! 因此我花了较大的篇幅去介绍它们。 在深入学习ARM架构后, 在后期的文章中我会 手把手带着你实现多任务的调度,实现一个小型的 RTOS 系统,这将会对你有很大的提升。
通过本篇文章,我们了解到了很多嵌入式软件开发的知识, 但我们还未开始写代码, 我知道您已经迫不及待了, 实话实说我也是, 不过别急, 心急吃不了热豆腐。
由于篇幅有限,我无法给大家在本篇文章中都详细的介绍各个章节,其实每个知识点都可以引申出大量的知识, , 但是一篇文章,篇幅实在有限, 在深入学习ARM 专栏中 我们会反复的研究和学习,如果你对此感兴趣,欢迎关注!
下一期 : ARM-Cortex-M3 内存分布 以STM32为例子
连载中, 如果你对本文有兴趣或者意见,我十分希望能看到您的留言和评论!