技术
摘要:本文首先分析了C语言的陷阱和缺陷,对容易犯错的地方进行归纳整理;分析了编译器语义检查的不足之处并给出防范措施,以Keil MDK编译器为例,介绍了该编译器的特性、对未定义行为的处理以及一些高级应用;在此基础上,介绍了防御性编程的概念,提出了编程过程中就应该防范于未然的多种措施;提出了测试对编写优质嵌入式程序的重要作用以及常用测试方法;最后,本文试图以更高的层次看待编程,讨论一些通用的编程思想。
<strong>1、简介</strong>
市面上介绍C语言以及编程方法的书数目繁多,但对如何编写优质嵌入式C程序却鲜有介绍,特别是对应用于单片机、ARM7、Cortex-M3这类微控制器上的优质C程序编写方法几乎是个空白。本文面向的,正是使用单片机、ARM7、Cortex-M3这类微控制器的底层编程人员。
本文主要介绍嵌入式系统的一些基础知识,希望对各位有帮助。
<strong>嵌入式系统基础</strong>
<strong>1、嵌入式系统的定义</strong>
(1)定义:以应用为中心,以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。
(2)嵌入式系统发展的4个阶段:无操作系统阶段、简单操作系统阶段、实时操作系统阶段、面向Internet阶段。
(3)知识产权核(IP核):具有知识产权的、功能具体、接口规范、可在多个集成电路设计中重复使用的功能模块,是实现系统芯片(SOC)的基本构件。
<strong>1. 前言</strong>
蜗蜗很早以前就知道有WFI和WFE这两个指令存在,但一直似懂非懂。最近准备研究CPU idle framework,由于WFI是让CPU进入idle状态的一种方法,就下决心把它们弄清楚。
WFI(Wait for interrupt)和WFE(Wait for event)是两个让ARM核进入low-power standby模式的指令,由ARM architecture定义,由ARM core实现。听着挺简单,但怎么会有两个指令?它们的区别是什么?使用场景是什么?深究起来,还挺有意思,例如:能想象WFE和spinlock的关系吗?
<strong>2. WFI和WFE</strong>
边界扫描(Boundary scan)是一项测试技术,是在传统的在线测试不在适应大规模,高集成电路测试的情况下而提出的,就是在IC设计的过程中在IC的内部逻辑和每个器件引脚间放置移位寄存器(shift register)。每个移位寄存器叫做一个CELL。这些CELL准许你去控制和观察每个输入/输出引脚的状态。当这些CELL连在一起就形成了一个数据寄存器链(data register chain),我门叫它边界寄存器(boundaryregister)。除了上面的移位寄存器外,在IC上还集成测试访问端口控制器(TAP controller),指令寄存器(Instruction register)对边界扫描的指令进行解码以便执行各种测试功能。旁路寄存器(bypass register)提供一个最短的测试通路。另外可能还会有IDCODE register和其它符合标准的用户特殊寄存器。
开漏输出:输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行。适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)。
推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。
我们先来说说集电极开路输出的结构。集电极开路输出的结构如图1所示,右边的那个三极管集电极什么都不接,所以叫做集电极开路(左边的三极管为反相之用,使输入为“0”时,输出也为“0”)。对于图1,当左端的输入为“0”时,前面的三极管截止(即集电极C跟发射极E之间相当于断开),所以5V电源通过1K电阻加到右边的三极管上,右边的三极管导通(即相当于一个开关闭合);当左端的输入为“1”时,前面的三极管导通,而后面的三极管截止(相当于开关断开)。
在Realview MDK的集成开发环境中,默认情况下可以生成*.axf格式的调试文件和*.hex格式的可执行文件。虽然这两个格式的文件非常有利于ULINK2仿真器的下载和调试,但是ADS的用户更习惯于使用*.bin格式的文件,甚至有些嵌入式软件开发者已经拥有了*.bin格式文件的调试或烧写工具。为了充分地利用现有的工具,同时发挥Realview MDK集成开发环境的优势,将*.axf格式文件或*.hex格式文件转换成*.bin格式的文件是十分自然的想法。本文将详细的探讨这种转换方法。
在Realview MDK中,生成*.bin格式文件的工具是ARM公司的RVCT开发套件中的fromelf.exe。默认安装下,它位于C/:Keil/ARM/BIN40文件夹下。
下面将介绍它在Keil MDK中的使用方法:
Cortex-A32是ARM架构中独一无二的产品,拥有重要地位。Cortex-A32基于ARMv8-A架构,却是针对32位设计的处理器。下图介绍了Cortex-A32与ARMv8-A架构的匹配程度,并与Cortex-A35进行了对比。
<center><img src="http://mm32.eetrend.com/files/2016-08/wen_zhang_/100002722-8836-1.png&q…; alt=""></center>
嵌入式操作系统(Embedded Operation System,EOS)是指用于嵌入式系统的操作系统。嵌入式系统分为4层,硬件层、驱动层、操作系统层和应用层。嵌入式操作系统是负责嵌入式系统的全部软、硬件资源的分配、任务调度,控制、协调并发活动。它必须体现其所在系统的特征,能够通过装卸某些模块来达到系统所要求的功能,是一种用途广泛的系统软件。
<strong>嵌入式LINUX</strong>
在嵌入式系统开发中,目前使用的主要编程语言是C 和汇编,虽然C++已经有相应的编译器,但是现在使用还是比较少的。
在稍大规模的嵌入式程序设计中,大部分的代码都是用C来编写的,主要是因为C语言具有较强的结构性,便于人的理解,并且具有大量的库支持。但对于一写硬件上的操作,很多地方还是要用到汇编语言,例如硬件系统的初始化中的CPU 状态的设定,中断的使能,主频的设定,RAM控制参数等。另外在一些对性能非常敏感的代码块,基于汇编与机器码一一对应的关系,这时不能依靠C编译器的生成代码,而要手工编写汇编,从而达到优化的目的。汇编语言是和CPU的指令集紧密相连的,作为涉及底层的嵌入式系统开发,熟练对应汇编语言的使用也是必须的。
作者:linuxer
来源:<a href="http://www.wowotech.net/memory_management/arm64-memory-addressing.html"…
<strong>一、前言</strong>
要使用低成本的 32位处理器,开发人员面临两种选择,基于Cortex-M3内核或者ARM7TDMI内核的处理器。如何做出选择?选择标准又是什么?本文主要介绍了ARM Cortex-M3内核微控制器区别于ARM7的一些特点,帮助您快速选择。
<strong>1.ARM实现方法 </strong>
ARM Cortex-M3是一种基于ARM V7架构的最新ARM嵌入式内核,它采用哈佛结构,使用分离的指令和数据总线;ARM7是冯诺伊曼结构 冯诺伊曼结构下,数据和指令共用一条总线 。从本质上来说,哈佛结构在物理上更为复杂,但是处理速度明显加快。根据摩尔定理,复杂性并不是一件非常重要的事,而吞吐量的增加却极具价值。
单片机的正常运行的前提,硬件是一方面,另一方面就是单片机需要执行的程序。大家都知道单片机会执行写好的程序,但是单片机从哪里开始读取指令,数据又被写在了哪里呢?
让我们从最开始的环节讲起。在单片机上电的瞬间,MCU的程序指针PC会被初始化为上电复位时的地址,从哪个地址处读取将要执行的指令,由此程序在MCU上开始执行(当然在调用程序的main之前,还有一系列其他的的初始化要做,如堆栈的初始化,不过这些很少回去修改)。PC在上电时,和MCU差不多,不过读取的是BIOS,有它完成了很多初始化操作,最后,调用系统的初始化函数,将控制权交给了操作系统,于是我们看到了Windows、Linux系统启动了。
本文主要总结一些比较实用的单片机编程经验:
<strong> 经验之一:用“软件陷阱+程序口令”对付PC指针的弹飞</strong>
当CPU受到外界干扰,有时PC指针会飞到另一段程序中,或跳到空白段去。其实,如果PC指针飞到空白段去,倒也好处理。只要在空白段设立软件陷阱(拦截指令),将程序拦截到初始化段或程序错误处理段。但是,如果PC指针飞到另一段程序中去了,系统如何办?小匠在这里推荐一种方法——程序口令,思路如下:
1、首先,程序必须模块化。每个模块(子程序)执行一个功能。每个模块只有一个出口(RET)。
2、设立一个模块(子程序)ID寄存器。
3、为每个子程序配置一个唯一的ID号码。
首先安装vdmagdi软件,然后再进行以下设置:
下载地址:http://pan.baidu.com/s/1i30ultb
在Keil软件上单击“Project菜单/Options for Target”选项或者点击工具栏的“option for ta rget”按钮 ,
首先要说明,没有哪款开发工具是万能的,也没有哪款工具在所有方面都具有绝对优势。对于Keil MDK-ARM和IAR两款工具择,可以根据自己的习惯来选择,而不应该在使用其中的一款时贬低另外一款,或者总是赞美自己的选择。
好了,下面开始讲Keil MDK-ARM和IAR的区别。
<strong>一、概述</strong>
Keil MDK-ARM(旧称RealView MDK)开发工具源自德国Keil公司,被全球上百万的嵌入式开发工程师验证和使用,是ARM公司目前最新推出的针对各种嵌入式处理器的软件开发工具。
Proteus用起来十分方便,其对中国学生最大的障碍就是很多朋友不知道自己想要寻找的器件用英文怎么说,从而无法在Proteus中快速找到自己需要的器件。下面,我们就简单先来了解一下Proteus中器件的种类。
Proteus中常用的元器件被分成了25大类,为了方便快速地查找到相应器件,在Pick Devices(拾取元器件)对话框中,你应该首先选中相应的大类,然后使用关键词进行搜寻。
Proteus的这25大类元器件分别为:
Analog ICs :模拟IC
CMOS 4000 series :CMOS 4000系列
Data Converters :数据转换器
Diodes :二极管
Electromechanical :机电设备(只有电机模型)
一、ARM中异常中断的类型:
异常中断名称 含义 复位(Reset)
当处理器复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行。复位异常中断通常用在下面几种情况:
1、系统加电时
2、系统复位时
3、跳转到复位中断向量处执行,称为软复位
未定义的指令 当ARM处理器或者是系统中协处理器认为当前指令未定义时,产生未定义指令异常中断。可以通过该异常中断机制仿真浮点向量运算。
软件中断
(software interrupt SWI)
这是一个由用户定义的中断指令。可以用于用户模式下程序调用特权操作指令。在实时操作系统(RTOS)中可以通过该机制实现系统功能调用
指令预取中止
设计以MCU为核心的嵌入式系统硬件电路需要根据需求分析进行综合考虑,需要考虑的问题较多,这里给出几个特别要注意的问题。
<strong>1、MCU的选择 </strong>
选择 MCU 时要考虑 MCU 所能够完成的功能、MCU 的价格、功耗、供电电压、I/O 口电平、管脚数目以及 MCU 的封装等因素。MCU 的功耗可以从其电气性能参数中查到。供电电压有 5V、3.3V 以及 1.8V 超低电压供电模式。
为了能合理分配 MCU 的I/O资源,在 MCU 选型时可绘制一张引脚分配表,供以后的设计使用。
<strong>2、电源 </strong>
<strong>PROTEUS总线绘制</strong>
<strong>用总线的目的</strong>
1、在画数字电路时,需要对大量导线类型相同的数据和地址进行连线,这时就需要使用总线用以简单化电路图的连线。
2、在复杂的电路图中使用总线,可以清晰快速的理解多连线元件间的关系。
因为即使是自己设计绘制的电路图,时间间隔较长时,也会忘记。在读别人的电路图时也会因为总线的使用而加快理解速度。
<strong>一、进入总线绘制模式的俩种方法</strong>
1、 点击Proteus左侧工具栏按钮
网上有很多朋友都碰到IAR软件的Go to Definition of选项不是灰色,就是单击后发出声音不跳转或直接提示C文件路径错误。本人也被该问题困扰已久,咬咬牙决定研究一下,彻底解决这个问题,以下是本人经过多次尝试之后总结的解决方法及问题的分析。如有错误之处,恳请指正。
1、 Go to Definition of是灰色的
Tools → Options → Project:勾选Generate browse information
问题1分析:未开启Go to Definition of的功能,勾选上述选项即开启
2、 单击Go to Definition of发出声音但未跳转
1) Tools → Options → Project:取消勾选Generate browse information