Cortex-M0编程入门

1.嵌入式系统编程入门

微控制器是如何启动的

  • 为了保存编译好的程序代码,大多数的现代微控制器都会包含片上Flash存储器。程序代码在Flash存储器中是以二进制机器码的形式存放的,因此C代码必须经过编译,才能烧写到Flash中。有些微控制器会配备一个独立的启动ROM,里面有一个小的Boot loader程序。微控制器启动后,在执行Flash里的用户程序前,Boot loader会首先运行。
  • 程序代码烧写到Flash存储器(或者是其它类型的程序存储器)以后,处理器就可以访问程序了。复位以后,处理器将会运行复位流程。
    在这里插入图片描述
    在复位流程中,处理器会取出MSP的初始值和复位向量,然后开始执行复位处理。这些所需信息都放在一个叫做启动代码的程序文件中。启动代码中的复位处理可能还会履行系统初始化的职责,一般系统初始化是在C程序main()中开始的。
  • 执行完C启动代码后,应用程序就开始执行了。其通常包含:硬件初始化(如时钟、PLL和外设)、应用程序的处理部分、中断服务程序。
    应用程序可能会用C库函数,此时C编译器/链接器会将所需的库函数纳入编译好的程序映像中。
    硬件初始化可能会涉及到一系列的外设、系统控制寄存器和Cortex-M0里的中断控制寄存器。如果在复位处理时没有进行处理,系统时钟控制和PLL此时也需要进行初始化。外设初始化完成后,程序就可以继续执行应用程序处理部分了。

嵌入式程序设计

应用程序处理流程可以用三种方式来实现,下面是一些基本概念:

  • 轮询:轮询适用于简单的应用程序,而当应用程序变得复杂或对处理能力的要求更高时,轮询就不合适了。比如当一个进程占用时间过长,其他模块在这段时间内就不会收到处理器的任何服务。
    轮询方式示意图如下:
    在这里插入图片描述
  • 中断驱动:对于一些需要低功耗的应用,处理器可以在中断服务程序中执行处理,当没有任务需要处理时进入休眠模式。外部中断源或者芯片外设都可以触发中断,并唤醒处理器。此外,在中断程序的应用程序中,不同设备的中断可以被设置为不同的优先级。
    中断驱动应用程序方式如下:
    在这里插入图片描述
  • 轮询和中断驱动的组合使用:许多情况下,应用程序可以将中断驱动和轮询这两种方式组合使用,通过软件变量传递,中断处理程序和主处理流程间可以进行信息交换,如下图:
    在这里插入图片描述
    将一个处理任务分割为中断服务程序和主流程中的处理,可以减少中断服务的持续时间,以便低优先级的中断能有更多的机会获得服务。
  • 处理并发任务:当一个处理任务可能会占用大量时间时,上述的处理就不合适了。如果任务A的执行需要太长的时间,任务B和C可能就无法及时响应外设模块的请求。针对这种情况,一般的解决方案如下:
    1.将一个长时间的处理任务划分为一系列的状态,每次处理任务时,只执行一种状态。
    2.使用实时操作系统(RTOS)处理多任务。
    使用第1种方法,一个任务被划分为了几个部分,可以使用软件变量追踪任务的状态。每次执行任务时,状态信息就会得到更新,这样下次再执行这个任务时,就可以继续上次的处理了。如下:
    在这里插入图片描述

而对于更加复杂的应用程序,可以使用RTOS。RTOS将处理器时间划分为多个时间片,在有多个应用进程运行时,只有一个进程会获得时间片。使用RTOS,需要由定时器产生周期性的中断请求。当一个时间片的时间到时,RTOS的任务调度器会由定时器中断触发,并判断是否需要执行上下文切换。如果需要,任务调度会暂停正在执行的任务,并切换到下一个准备就绪的任务。如下:
在这里插入图片描述

RTOS可以提高系统的反应能力,并且确保在一定时间内能够执行到所有任务。

2.输入和输出

在许多嵌入式系统中,可用的输入和输出有简单的电子接口,如数字和模拟输入/输出接口(I/O)、UART、I2C和SPI等,此外,还提供了USB、以太网、CAN图像LCD以及SD卡等接口,这些接口是由微控制器的外设控制的。

Cortex-M0的寄存器映射到了系统空间,并且它们还控制着外设。外设的典型初始化过程一般包括以下步骤:

  • 配置时钟控制回路,使能外设的时钟信号,并且有必要的话,初始化相应的引脚。
  • 配置I/O,大多数微控制器的引脚都是复用的,需要对I/O引脚的功能进行配置,以确保外设接口正常工作。
  • 配置外设,大多数接口外设都有多个可编程的控制寄存器,因此,为了确保外设工作正常,就需要对寄存器进行一系列的编程操作。
  • 配置中断,如果外设操作需要中断处理,就需要另外配置中断控制器。

3.开发流程

ARM微控制器可以使用的开发工具链有很多种,它们大多数都支持C和汇编语言。开发嵌入式工程时,可以使用C语言,也可以用汇编,或者两者混合编程。多数情况下,程序代码生成流程可以总结为如下所示的形式:
在这里插入图片描述

根据所使用开发工具的不同,链接器可能会使用命令行选项来指定内存分布。

生成可执行映像后,可以将其下载到微控制器的Flash存储器或内存中进行测试。开发工具与在线调试器配合使用时,可以分步进行以下工作:创建工程,编译应用程序,然后下载嵌入式应用程序到微控制器中,如下:
在这里插入图片描述
要想对Flash进行编程,可以使用开发组件中的调试器软件,或者从微控制器供应商网站下载的Flash编程工具。在微控制器上运行程序可以测试其正确性,而将调试器连接到微控制器上,则可以控制程序的运行并且观察其各种操作。这些功能都可以通过Cortex-M0处理器的调试接口实现,如下:
在这里插入图片描述

4.C编程和汇编编程

C语言和汇编语言的使用比较如下:
在这里插入图片描述

  • 大多数C编译器都允许在C程序代码中嵌入汇编代码。
  • 有些特殊指令没法用C代码生成,所以一些C编译器还提供了内在函数,其一般是与开发工具相关联的。
  • 可以在同一个工程里使用C和汇编代码混合编程,程序的大部分代码可以用C编写,无法用C实现的部分则使用汇编,这样做是为了保证输入参数和返回值的正确传递,两部分的函数接口必须保持一致。

5.什么是程序映像

Cortex-M0的程序映像一般包括以下几个部分:

  • 向量表:
    向量表可以用C语言或汇编语言实现。由于向量表的入口需要编译器和链接器生成的内容,所以向量表代码的实现细节是同开发工具链相关的。
    为了将向量表置于系统存储器映射的开头(地址为0x00000000),链接文件或命令行选项需要知道段的名字,以便链接器能够正确识别向量并将其地址映射。
    复位向量一般指向C启动代码的开头,不过,也可以自己定义复位处理,在跳转到C启动代码前执行附加的初始化操作。

  • C启动例程:
    C启动代码用于设置像全局变量之类的数据,也会清零加载时未被初始化的内存区域。初始化完成后,启动代码跳转到main()程序执行。
    C启动代码由编译器/链接器自动嵌入到程序中,并且是和开发工具链相关的,而只使用汇编代码编程则可能不存在C启动代码。对于ARM编译器,C启动代码被标识为"_mian",而是用GUN C编译器生成的代码则通常被标记为"_start"。

  • 程序代码(应用程序代码和数据):
    用户指定的任务是由应用程序生成的指令完成的,除了指令以外,还有以下各类数据:
    1.变量的初始值,函数或子程序中的局部变量需要初始化,这些初始值会在程序执行期间被赋给相应的变量。
    2.程序代码中的常量,应用程序中的常量数据有多种用法,如数据值、外设等寄存器的地址和常量字符串等,这些数据在程序映像中一般作为数据块放在一起,并被称作文字库。
    3.其他的常量,如查找表和图像数据。

  • C库代码(C库函数的程序代码,链接时插入):
    当使用特定的C/C++库函数时,它们的库代码就会由链接器嵌入到程序映像中。另外,由于有些数据处理任务需要浮点数或除法运算,在进行这些运算时,C库代码也会被包含进来。Cortex-M0中没有除法指令,需要借助C函数库中的除法函数来实现除法运算。
    除了向量表需要放在存储器映射的开头以外,程序映像中剩余部分的位置就没有限制了。

RAM中的数据:
像程序ROM一样,微控制器的RAM也有多种用法。典型地,RAM的使用一般可以分为数据、栈和堆区域,如下所示:

在这里插入图片描述
数据、栈和堆区域存储内容如下:

数据:数据存储在内存的底部,包含全局变量和静态变量,为了节省内存,可以将局部变量分配在栈上,而且函数内未用的局部变量不占用存储器空间。
栈:栈空间用于临时数据存储(常见的PUSH和POP操作)、局部变量的存储空间、函数调用参数传递和异常处理的寄存器备份等。
堆:堆存储用于C函数自动分配存储器区域,以及其他使用这些函数的函数调用。为了确保这些函数能够正确地分配存储器空间,C启动代码需要初始化堆存储及其控制变量。

一般来说,栈位于存储器空间的顶部,而堆区域则位于底部,这样做使得内存使用具有最大的灵活性。在操作系统环境中,可能会有多个内存区域用作数据、栈和堆。

有些操作系统允许用户自定义任务的栈,这样也就需要更大的栈空间。有些操作系统则将内存分为若干个段,每个任务分配一个段,用于各自的数据、栈和堆区域,如下:
在这里插入图片描述

6.C编程:数据类型

Cortex-M0处理器支持的数据类型如下:
在这里插入图片描述
在这里插入图片描述

将应用程序从其他架构的处理器移植到ARM上时,如果两者的数据类型的宽度不同,那么可能就需要修改C代码,以确保程序运行正常。此外,在Cortex-M0上编程时,变量的存放地址为其数据宽度的倍数。

7.用C语言操作外设

  • 除了变量以外,微控制器的C应用程序通常需要操作外设。对于ARM Cortex-M0微控制器,外设寄存器被映射到系统存储器空间,它们可以通过指针进行访问。外设访问定义指针时,需要使用volatile关键字。
  • 大多数情况下,外设寄存器都被定义为32位宽度,这是因为连接外设的外部总线(APB)是按照32位处理数据传输的,有些外设可能会连接至处理器总线(AHB),这样,寄存器可以按照其他宽度的方式访问。

8.Cortex微控制器软件接口标准(CMSIS)

简介

随着嵌入式软件复杂性的增加,软件代码的兼容性和可重用性变得更加重要。为了使软件产品具有高度的兼容性和可移植性,ARM同一些微控制器供应商一起开发了一个通用的软件框架CMSIS,该框架适用于大多数的Cortex-M处理器以及Cortex-M微控制器产品,如下:
在这里插入图片描述
CMSIS一般是作为微控制器厂商提供的设备驱动库的一部分来使用的。为了使用诸如NVIC和系统控制功能等处理器特性,CMSIS提供了一种标准化的软件接口。

标准化内容

CMSIS为嵌入式软件提供了以下标准化的内容:

  • 标准化的操作函数,用于访问NVIC、系统控制块(SCB),SysTick的中断控制和初始化。
  • NVIC、SCB和SysTick寄存器的标准化定义。
  • 使用Cortex-M0微控制器指令的标准化函数。有些指令不能由普通的C代码生成,如果需要这些指令,就可以使用CMSIS提供的这类函数来实现。
  • 系统异常处理的标准化命名。
  • 系统初始化函数的标准化命名。
  • 为时钟频率信息建立标准化的变量。
  • 设备驱动库的通用平台。

组织结构

CMSIS可以分为以下 几层:

  • 核心外设访问层:命名定义,地址定义,以及访问核心寄存器和NVIC、SCB以及SysTick等核心外设的辅助功能。
  • 中间件访问层(正在进行中)
    1.典型嵌入式系统访问外设的通用方法。
    2.面向通信接口,包括UART、Ethernet和SPI等。
    3.嵌入式软件能够在任何支持特定通信接口的Cortex微控制器上使用。
  • 设备外设访问层(MCU相关):寄存器名称定义,地址定义,以及访问外设的设备驱动代码。
  • 外设的访问函数(MCU相关):可选的外设辅助函数。

这些层的作用在下图中做了总结:
在这里插入图片描述

使用方法

CMSIS被集成在微控制器供应商提供的设备驱动包中,如果使用设备驱动库进行软件开发,那么就已经在使用CMSIS了。

对于C程序代码,通常只需要包含微控制器供应商提供的设备驱动库里的头文件。这个头文件又包含了其他所有需要的文件,包括CMSIS特性和外设驱动等。

下图是包含了一个使用CMSIS包建立的简单工程,有些文件的名字由实际的微控制器设备决定(在图中标识为< device >)。

在这里插入图片描述
下图是一个使用CMSIS的简单例子:
在这里插入图片描述

优势

  • 不同的Cortex-M微控制器之间的程序移植变得容易。

  • 提高了兼容性,这是因为由于CMSIS文件的使用,中间件和嵌入式操作系统就会基于相同的内核外设寄存器定义以及内核访问函数。
    这同时也减小了代码冲突的概率,因为不同软件组件都分别使用自己的内核访问函数和寄存器定义时,就可能会发生冲突。没有CMSIS,可能会发现不同的第三方软件组件都包含了自己特有的驱动函数,这就可能会带来诸多问题,包括寄存器命名冲突、多个函数拥有类似命名引起的混乱以及重复函数带来的空间浪费,如下:
    在这里插入图片描述

  • CMSIS内核访问函数占用的存储器空间很小,并且经过测试,这有助于减少软件测试的时间。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
The Definitive Guide to the ARM® Cortex®-M0 and Cortex-M0+ Processors, Second Edition explains the architectures underneath ARM’s Cortex-M0 and Cortex-M0+ processors and their programming techniques. Written by ARM’s Senior Embedded Technology Manager, Joseph Yiu, the book is packed with examples on how to use the features in the Cortex-M0 and Cortex-M0+ processors. It provides detailed information on the instruction set architecture, how to use a number of popular development suites, an overview of the software development flow, and information on how to locate problems in the program code and software porting. This new edition includes the differences between the Cortex-M0 and Cortex-M0+ processors such as architectural features (e.g. unprivileged execution level, vector table relocation), new chapters on low power designs and the Memory Protection Unit (MPU), the benefits of the Cortex-M0+ processor, such as the new single cycle I/O interface, higher energy efficiency, better performance and the Micro Trace Buffer (MTB) feature, updated software development tools, updated Real Time Operating System examples using Keil™ RTX with CMSIS-RTOS APIs, examples of using various Cortex-M0 and Cortex-M0+ based microcontrollers, and much more. •Provides detailed information on ARM® Cortex®-M0 and Cortex-M0+ Processors, including their architectures, programming model, instruction set, and interrupt handling •Presents detailed information on the differences between the Cortex-M0 and Cortex-M0+ processors •Covers software development flow, including examples for various development tools in both C and assembly languages •Includes in-depth coverage of design approaches and considerations for developing ultra low power embedded systems, the benchmark for energy efficiency in microcontrollers, and examples of utilizing low power features in microcontrollers
【目  录】: 第1篇系统篇 第1章嵌入式系统概述3 1.1嵌入式系统的定义和特点3 1.1.1嵌入式系统的定义3 1.1.2嵌入式系统和通用计算机比较4 1.1.3嵌入式系统的特点5 1.2嵌入式系统的硬件6 1.2.1嵌入式处理器7 1.2.2嵌入式存储器15 1.2.3嵌入式I/O设备18 1.2.4嵌入式I/O接口18 1.3嵌入式系统的软件21 1.3.1无操作系统的嵌入式软件22 1.3.2带操作系统的嵌入式软件24 1.4嵌入式系统的分类27 1.4.1按硬件(嵌入式处理器)划分27 1.4.2按软件复杂度划分27 1.4.3按实时性划分28 1.4.4按使用对象划分28 1.5嵌入式系统的应用28 1.5.1国防军事28 1.5.2工业控制29 1.5.3消费电子30 1.5.4办公自动化产品30 1.5.5网络和通信设备30 1.5.6汽车电子31◆嵌入式系统原理及应用目录1.5.7金融商业31 1.5.8生物医学32 1.5.9信息家电32 1.6本章小结34 习题134 第2章嵌入式系统开发35 2.1嵌入式系统的开发环境、开发工具和调试方式35 2.1.1嵌入式系统的开发环境35 2.1.2嵌入式系统的开发工具37 2.1.3嵌入式系统的调试方式43 2.2嵌入式系统的开发语言50 2.2.1嵌入式硬件开发语言50 2.2.2嵌入式软件开发语言51 2.3嵌入式系统的开发过程53 2.3.1需求分析54 2.3.2系统设计55 2.3.3系统实现61 2.3.4系统测试70 2.3.5系统发布73 2.4嵌入式开发工程师之路74 2.4.1嵌入式行业和人才的现状分析74 2.4.2嵌入式开发工程师的能力要求74 2.4.3嵌入式开发工程师的进阶之路75 2.5本章小结77 习题278 第2篇内核篇 第3章ARM CortexM3处理器81 3.1ARM CortexM3组成结构81 3.1.1CortexM3内核82 3.1.2调试系统84 3.2ARM CortexM3总线接口86 3.2.1CortexM3总线接口类型87 3.2.2CortexM3总线连接方案88 3.3ARM CortexM3编程模型89 3.3.1工作状态89 3.3.2数据类型89 3.3.3寄存器89 3.3.4指令系统93 3.3.5操作模式和特权分级96 3.3.6异常和中断98 3.3.7双堆栈机制105 3.4ARM CortexM3存储器系统107 3.4.1存储器映射107 3.4.2位带操作110 3.4.3存储格式112 3.5ARM CortexM3的低功耗模式113 3.6本章小结114 习题3115 第4章基于ARM CortexM3的STM32微控制器117 4.1从CortexM3到基于CortexM3的MCU117 4.2基于CortexM3的STM32系列微控制器概述118 4.2.1产品线118 4.2.2命名规则124 4.2.3生态系统125 4.2.4开发方法131 4.2.5学习之路134 4.3STM32F103微控制器基础136 4.3.1概述136 4.3.2主系统结构137 4.3.3功能模块139 4.3.4引脚定义140 4.3.5存储器组织141 4.4STM32F103微控制器的最小系统145 4.4.1电源电路145 4.4.2时钟电路148 4.4.3复位电路149 4.4.4调试和下载电路150 4.4.5其他151 4.5STM32F103微控制器的时钟系统153 4.5.1输入时钟153 4.5.2系统时钟155 4.5.3由系统时钟分频得到的其他时钟155 4.5.4STM32F10x时钟系统相关库函数157 4.6STM32F103微控制器的低功耗模式162
Cortex-M0 技术参考手册是针对 ARM 公司的一款 32 位微控制器,主要采用 ARM Cortex-M0 内核,该参考手册是针对其开发者和工程师的一份技术指导文件。 Cortex-M0 技术参考手册包括了丰富的技术内容和核心板的详细介绍,提供了比较全面的硬件和软件技术支持,方便工程师在项目开发中能够更好地进行调试、优化和维护。它主要包含了以下内容: 1、Cortex-M0 架构概述:详细介绍了 Cortex-M0 架构的特点和功能,包括 CPU 核、内存系统、寄存器、中断、调试和测试等方面内容。 2、Cortex-M0 内存系统:主要介绍了 Cortex-M0 的内存类型、存储器映射机制、缓存和地址空间结构等。 3、Cortex-M0 外设:该部分主要介绍了 Cortex-M0 核芯片的外设,包括时钟、中断控制器、GPIO、ADC、DAC、SPI、I2C、PWM、UART、USB 和定时器等。 4、Cortex-M0 指令集:详细介绍了 Cortex-M0 的指令集,包括数据处理指令、数据传输指令、分支指令、短指令、系统调用指令等等。 5、Cortex-M0 软件开发工具:介绍了 Cortex-M0 开发所需要的软件工具,如开发环境、编译器、调试器、仿真器等内容。 总体来说,Cortex-M0 技术参考手册是一份非常宝贵的技术文件,它全面、详尽地介绍了 Cortex-M0 微控制器的架构、内存系统、外设、指令集和软件开发工具等方面的内容,对工程师们进行项目开发提供了强有力的支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值