找回密码
 立即注册
查看: 136|回复: 17

IAR入门指南之开发嵌入式应用

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:348
  • 最近打卡:2025-05-02 08:34:59

7

主题

281

回帖

1055

积分

金牌会员

积分
1055
发表于 2025-4-7 09:16:36 | 显示全部楼层 |阅读模式
开发嵌入式应用

开始你的嵌入式应用软件开发之前,请研读这些概念:
●    开发周期
●    构建过程

开发周期
在实际开发之前,你必须收集需求和设计, 具体说明你的应用的架构
(手工或使用自动化代码生成工具, 如 visualSTATE)。然后,准备启动IAR嵌入式工作台IDE。
下面是典型的开发周期:
●    设立项目, 包括通用的和特定工具的选项
●    创建你的C,C++或汇编语言源代码文件
●    构建—编译和链接—你的项目供调试
●    改正源代码中的任何错误
●    测试并调试你的应用
●    为发行构建
●    加载映像到FLASH或PROM存储器。
截图202504070906174648.jpg
回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 2025-4-7 09:18:00 | 显示全部楼层
IAR入门指南之开发嵌入式应用

在嵌入式应用开发领域,IAR Embedded Workbench 是一款广泛使用的集成开发环境(IDE),它支持多种微控制器架构,并提供了强大的工具链来帮助开发者高效地完成从代码编写到最终产品部署的全过程。本文将简要介绍使用IAR进行嵌入式应用开发的关键步骤和概念。

1. 开发周期

嵌入式应用的开发周期通常包括以下几个阶段:
需求收集与设计:在开始编码之前,明确应用的功能需求和性能指标,设计系统架构。可以使用工具如visualSTATE进行自动化代码生成。
项目设置:在IAR Embedded Workbench中创建新项目,配置通用和特定工具的选项,如编译器设置、链接器脚本等。
源代码编写:使用C、C++或汇编语言编写应用程序代码。确保代码结构清晰,遵循编码规范。
构建与调试:编译和链接项目,生成可执行文件。使用IAR的调试工具进行代码调试,修正错误。
测试与验证:在目标硬件上运行应用程序,进行功能测试和性能验证。
发布构建:优化代码,生成最终的可执行映像文件。
加载与部署:将映像文件加载到目标硬件的FLASH或PROM存储器中,完成产品部署。

2. 常用软件模型

在嵌入式开发中,常用的软件模型包括:
裸机编程:直接在硬件上运行,不依赖操作系统,适用于资源有限的系统。
实时操作系统(RTOS):提供任务调度、内存管理等功能,适用于复杂的多任务应用。
事件驱动模型:基于事件触发执行相应的处理逻辑,适用于响应式系统。

3. 构建过程

IAR的构建过程主要包括编译和链接两个步骤:
编译:将源代码转换为目标机器代码,生成目标文件(.obj)。
链接:将多个目标文件和库文件合并,生成最终的可执行文件(.out或.hex)。

4. 高性能编程

为了提升嵌入式应用的性能,开发者可以采取以下措施:
优化算法:选择高效的算法和数据结构,减少计算复杂度。
减少内存访问:优化数据访问模式,减少缓存未命中和内存带宽消耗。
利用硬件特性:充分利用目标硬件的并行计算能力和专用指令集。

5. 考虑硬件和软件因素

在嵌入式开发中,硬件和软件的紧密集成是关键。开发者需要考虑:
硬件资源限制:如处理器速度、内存大小、外设接口等。
实时性要求:确保系统能够及时响应外部事件。
功耗管理:优化代码和硬件配置,降低系统功耗。

6. 执行应用程序

在目标硬件上执行应用程序时,开发者需要:
配置启动代码:确保系统正确初始化,包括时钟、内存、外设等。
调试与监控:使用调试工具监控程序运行状态,定位和解决问题。
性能分析:评估系统性能,识别瓶颈并进行优化。

通过以上步骤,开发者可以高效地使用IAR Embedded Workbench进行嵌入式应用开发,确保产品的质量和性能。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:348
  • 最近打卡:2025-05-02 08:34:59

7

主题

281

回帖

1055

积分

金牌会员

积分
1055
发表于 2025-4-7 09:18:46 | 显示全部楼层
嵌入式开发的方法具有一定的普遍性。不仅仅对IAR,对于Keil也是适用的。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:348
  • 最近打卡:2025-05-02 08:34:59

7

主题

281

回帖

1055

积分

金牌会员

积分
1055
发表于 2025-4-8 10:26:19 | 显示全部楼层
常用软件模型
这里是一些常用软件模型:
●   超级环系统 (任务按顺序执行)
●   多任务系统 (任务由RTOS调度)
●   状态机模型。
一般来说, 你要么是超级环系统要么是多任务系统,而流行的应用逻辑的组织方式是设计成状态机。

超级环系统
没有多任务内核, 一次只有一个任务可以让处理器执行。这叫做单任务系统或者超级环; 一个程序基本上在一个无尽的循环中运行并且按顺执行适当的操作。没使用任何实时内核, 所以对于软件的实时部分或者关键操作(中断等级),必须使用中断服务程序 (ISRs) 。
截图202504081028336500.jpg
如果程序变的太大,那么超级环就会变得太难维护。因为一个软件构件不能被另一个软件构件中断 (只能是ISRs), 一个软件构件的反应时间取决于系统中所有其他软件构件的执行时间。因此实时性很差。
这类系统一般使用在实时性不紧要的地方。

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:348
  • 最近打卡:2025-05-02 08:34:59

7

主题

281

回帖

1055

积分

金牌会员

积分
1055
发表于 2025-4-8 17:31:09 | 显示全部楼层
抢占式多任务系统
当使用实时操作系统(RTOS)时, 多个任务可以在单个处理器上同时执行。 所有任务都可以执行就好像它们完全拥有了整个处理器一样。任务是严格按时间调度执行的,意味着RTOS可以激活和冻结每个任务。 在一个多任务系统中, 有不同的时间调度算法将CPU的计算力分布在任务中间。
实时系统靠抢占式多任务运转。实时操作系统需要标准定时器,中断按定义的时间来中断任务并且需要的话完成任务切换。最高优先级的是处于READY状态的任务, 因此总是被执行,无论它是不是一个中断了的任务。 如果一个中断服务程序 (ISR)让一个较高优先级的任务READY(就绪),那么就会出现任务切换, 该任务,在返回到被中断的任务之前,会被执行。
截图202504081730396283.jpg
状态机模型
状态机模型简单地将进来的事件转换成推断出的出去的动作, 是一种纯反应式引擎或核心,不会和操作系统混淆。在任何给定的时间点上, 系统都处在几个可能的状态之一上。系统改变状态取决于来自环境的输入。状态发生变化时, 可以在环境上执行动作。

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:348
  • 最近打卡:2025-05-02 08:34:59

7

主题

281

回帖

1055

积分

金牌会员

积分
1055
发表于 2025-4-8 17:32:43 | 显示全部楼层
例如, 一个电子设备子系统可以是OnOff, 一扇门可以是Open或者是ClosedAndUnlocked,等等。状态机不必映射问题的所有可能的
物理状态, 只需要对解决问题来说最重要的状态。

状态机模型最重要的特征是处理并发的能力。本文中,并发这个术语是指同时操作多个并行状态的系统。
例如, 假设一台售卖机和所有要照顾到的情况:
●   如果一个杯子在盛满之前被移走会发生什么?
●   如果正在处理支付的时候,顾客取消订单,信用卡账户会发生什么?
●   如果先前的订单完成之前启动了一笔新订单会发生什么?
●   如果电子设备的部件导致机器在处理一笔订单期间停止工作,钱会正确地返回给用户吗?

状态图提供了设计的高层级视图,使得维护处理复杂性所需的总览成为可能。  一旦创建了状态图模型,就可以验证它以确保它的行为是想要的。IARvisualSTATE 还生成 C/C++ 源代码,它100%与你的设计一致。
使用状态机特别有益于面向控制逻辑的应用, 诸如监控, 计量以及主要注重的是可靠性, 规模, 不可逆转的执行的控制应用。



构建过程
本单元概述了构建过程; 各种构建工具 —编译器, 汇编器, 和链接器— 是怎样一起融洽相处, 从源代码到可执行映像的。构建过程可进一步分解:
●    翻译过程
●    链接过程

截图202504081732095845.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:348
  • 最近打卡:2025-05-02 08:34:59

7

主题

281

回帖

1055

积分

金牌会员

积分
1055
发表于 2025-4-8 17:38:14 | 显示全部楼层
●    链接之后。


翻译过程
IDE中有两个工具将应用程序源文件翻译成中间的目标文件: IAR C/C++编译器和IAR汇编器。两者都产生可重定位的目标文件, ELF/DWARF格式供ILINK生成产品和UBROF格式供XLINK生成产品。
注意:  编译器还可以将C/C++源代码翻译成汇编语言源代码。如果有需要, 你可以修改汇编语言源代码并将它汇编成目标代码。
右图展示了翻译过程:
截图202504081739242106.jpg
翻译之后, 你可以选择组织这些文件将任意数量的模块打包归档,换句话说, 归成一个库。
链接过程
可重定位的模块, 目标文件和库的形式, 是IAR编译器和汇编器产生的,是还不能执行的。要变成一个可执行的应用, 它们须要链接

注意: 根据你的产品软件包, 其他供应商的工具包产生的
模块同样可以包含在构建里。要注意,这也许需要来自同一供应商的编译器实用程序库。
链接器用来构建最终的应用。通常, 链接器需要以下信息作为输入:
●    几个目标文件,或许还有库。
●   程序的开始标记 (在ILINK链接器中默认设置而在XLINK链接器里是用户可配置的)
●   链接器配置文件描述了代码和数据在目标系统的内存中如何放置。


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:348
  • 最近打卡:2025-05-02 08:34:59

7

主题

281

回帖

1055

积分

金牌会员

积分
1055
发表于 2025-4-8 17:41:49 | 显示全部楼层
下图展示了链接过程:
截图202504081742533357.jpg

注意:  标准C/C++库包含供编译用的例行程序,以及这些C/C++标准库函数的实现。
ILINK链接器产生ELF格式的绝对目标文件,它包含可执行映像。XLINK可以生成超过30种以上的工业标准的加载器格式,还不包括C-SPY调试器使用的IAR系统专有的调试格式—UBROF。
链接期间, 链接器或许会在stdout和stderr上产生出错信息。ILINK链接器还产生日志信息, 它有助于理解应用程序为什么会以它该有的方式链接, 例如, 为什么包含了一个模块或者为什么删除了一截代码。
链接之后
链接之后所产生的绝对的可执行映像可以用于:
●    加载到IAR C-SPY调试器或者其他外部的支持所生成的格式的调试器。
●    用FLASH/PROM编程器写入FLASH/PROM存储器。当用ILINK链接时,
过去可能是这样的,映像中的实际字节必须转换成MotorolaS-record格式
或者Intel-hex格式。XLINK可以直接生成任何这些格式; 因此, 不需要额外的转换。
下图展示了输出结果可能的应用:





截图202504081741285490.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:348
  • 最近打卡:2025-05-02 08:34:59

7

主题

281

回帖

1055

积分

金牌会员

积分
1055
发表于 2025-4-8 17:47:31 | 显示全部楼层




高性能编程
本单元提供了一些思路:
●    使用适当的数据类型
●    便于寄存器分配
●    便于编译器变换

使用适当的数据类型
数据大小应该使用适当。在32位CPU上的8位操作通常效率低。反之,8位CPU上的32位操作是浪费的。如果使用整型常量, 确保添加适当的后缀, 例如 36L。
带符号的值意味着可以使用负值。然而, 当编译器修改这种值的时候, 使用了算术运算。对于无符号的值, 编译器用位和移位操作代替,一般来说比算术运算更经济。如果不需要负值, 确保使用无符号类型。

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:348
  • 最近打卡:2025-05-02 08:34:59

7

主题

281

回帖

1055

积分

金牌会员

积分
1055
发表于 2025-4-8 17:49:28 | 显示全部楼层
浮点操作 通常非常昂贵,因为它们可能需要大型库函数。考虑用整数操作(它们更高效)替换它们。
内存放置和指针类型 如果你追求下列情况,那么8和16位架构变得更加高效且产生的代码更少: 小内存区域, 小地址和小指针。避免使用最大内存类型或指针。
类型转换 应当避免指针转来换去, 以及在表达式中混合类型。 这会产生无效代码并存在信息丢失的风险。
结构填充 发生在当CPU要求对齐的时候。为避免这种内存浪费, 按大小将字段排序以确保填充所使用的内存的量减到最小。
便于寄存器分配
函数参数和局部变量  (与全局变量相反) 减少内存消耗, 因为它们可以放进寄存器,只需要在作用域内时存在。 使用全局变量会引入开销, 因为任何时候调用访问它们的函数时,它们都必须更新。
可变参数 (printf-风格) 应该避免, 因为它们迫使参数进堆栈。要不然这些参数会用寄存器传送。
便于编译器变换
函数原型 应该使用, 由于不需要类型提升 (隐式类型转换) , 所以这样更容易在源代码中发现问题。原型还会让编译器更容易生成高效的代码。
静态声明的变量和函数  只应该用于声明它们的文件或模块中,以获得最优化的代码。
内联汇编 可能会是编译器优化代码的最主要的障碍。一定要检验在你使用的编译器中asm关键字是如何工作的。
聪明的源代码 应该换成清晰的代码, 因为清晰的代码更容易维护, 更少可能包含程序设计错误, 而且通常更易于编译器进行优化。

回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 00:52 , Processed in 0.132382 second(s), 99 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表