技术
<strong> 1、快速排序算法</strong>
快速排序是由东尼•霍尔所发展的一种排序算法。在平均状况下,排序n个项目要Ο(nlogn)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(nlogn)算法更快,因为它的内部循环(innerloop)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divideandconquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
算法步骤:
(1)从数列中挑出一个元素,称为“基准”(pivot),
<strong> 3、标识符</strong>
a、变量的命名
方法一:采用匈牙利命名法。命名规则的主要思想是“在变量中加入前缀以增进人们对程序的理解”。
例如平时声明32位整型变量Length对应使用匈牙利命名法为unLength。现在列出经常用到的变量类型。
变量类型 示例
char cLength
unsigned char ucLength
short int sLength
编程的总则:编程首要是要考虑程序的可行性,然后是可读性、可移植性、健壮性以及可测试性。大多数程序员只是关注程序的可行性,而忽略了可读性,可移植性和健壮性,其实我个人认为,程序的可行性和健壮性与程序的可读性有很大的关系,能写出可读性很好的程序的程序员,他写的程序的可行性和健壮性必然不会差,也会有不错的可移植性。程序的可读性需要程序员有一个良好的编程风格。
好风格应该成为一种习惯。如果你在开始写代码时就关心风格问题,如果你花时间去审视和改进它,你将会逐渐养成一种好的编程习惯。一旦这种习惯变成自动的东西,你的潜意识就会帮你照料许多细节问题,甚至你在工作压力下写出的代码也会更好。
<strong>1、排版</strong>
这篇文章是俄国人Sergei P.Skorobogatov就读英吉利剑桥大学之博士论文,讲解了各种MCU的攻防技术,堪称一部小百科全书。对于志在研究MCU防护的筒子,能给你很多参考思路:但对于想当黑客的人,我们对后果概不负责!
C非侵入式攻击不需要对元器件进行初始化。攻击时可以把元器件放在测试电路中分析,也可单独连接元器件。一旦成功,这种攻击很容易普及,并且重新进行攻击不 需要很大的开销。另外,使用这种攻击不会留下痕迹。因此,这被认为是对任意元器件的硬件安全最大的威胁。同时,通常需要很多时间和精力来寻找对特定元器件 的非侵入式攻击方法。这通常对元器件进行反向工程,包括反汇编软件和理解硬件版图。
ARM支持7种异常。问题时发生了异常后ARM是如何响应的呢?下面一起来学习一下:
所有的系统引导程序前面中会有一段类似的代码,如下:
<center><img src="http://mm32.eetrend.com/files/2016-09/wen_zhang_/100002849-9339-8ecbff5…; alt=""></center>
作者:ce123
<strong>IICvs SPI</strong>
现今,在低端数字通信应用领域,我们随处可见IIC (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身影。原因是这两种通信协议非常适合近距离低速芯片间通信。Philips(for IIC)和Motorola(for SPI) 出于不同背景和市场需求制定了这两种标准通信协议。
常把单片机系统的复位分为冷启动和热启动。所谓冷启动,也就是一般所说的上电复位,冷启动后片内外RAM的内容是随机的,通常是0x00或0xFF;单片机的热启动是通过外部电路给运行中的单片机的复位端一复位电平而实现的,也就是所说的按键复位或看门狗复位。复位后,RAM的内容都没有改变。在某些场合,必须区分出设备的重启是热重启还是冷重启。常用的方法是:确定某内存单位为标志位(如0x40003FF4~0x40003FF7 RAM单元),启动时首先读该内存单元的内容,如果它等于一个特定的值(例如为0xAA55AA55),就认为是热启动,否则就是冷启动。
根据以上的设计思路思路定义一个变量:
uint32 unStartFlag;
在程序启动时判断:
if(unStartFlag==0xAA55AA55)
{
最近写一个程序,需要在用户模式下关中断,但ARM 7的体系结构决定了中断必须在特权模式下才可以更改,所以想到使用ARM的软中断来实现关中断和开中断。
使用软中断,首先要有硬件指令的支持,ARM有条指令是SWI。
SWI 指令的格式为:
SWI {条件} 24 位的立即数
SWI 指令用于产生软件中断,以便用户程序能调用操作系统的系统例程。操作系统在 SWI 的异常处理程序中提供相应的系统服务,指令中 24 位的立即数指定用户程序调用系统例程的类型,相关参数通过通用寄存器传递,当指令中 24 位的立即数被忽略时,用户程序调用系统例程的类型由通用寄存器 R0 的内容决定,同时,参数通过其他通用寄存器传递。
指令示例:
SWI 0x02 ;该指令调用操作系统编号位02的系统例程。
各种事物都有套路,开关电源的套路就是各种拓扑。对这些拓扑了然于胸,就能看清开关电源的本质。
为了表征各种电压或电流波形的好坏,一般都是拿电压或电流的幅值、平均值、有效值、一次谐波等参量互相进行比较。在开关电源之中,电压或电流的幅值和平均值最直观,因此,我们用电压或电流的幅值与其平均值之比,称为脉动系数S;也有人用电压或电流的有效值与其平均值之比,称为波形系数K。
因此,电压和电流的脉动系数Sv、Si以及波形系数Kv、Ki分别表示为:
Sv=Up/Ua——电压脉动系数
Si =Im/Ia——电流脉动系数
Kv=Ud/Ua——电压波形系数
Ki=Id/Ia——电流波形系数
<strong>1、单片机的工作频率</strong>
<strong>1.1 单片机的设计应根据客户的需求来选择较低的工作频率</strong>
首先介绍一下这样做的优点:采用低的晶振和总线频率使得我们可以选择较小的单片机满足时序的要求,这样单片机的工作电流可以变得更低,最重要的是VDD到VSS的电流峰值会更小。
当然我们这里需要做一个妥协,因为客户的要求可能是兼容的和平台化的(目前汽车电子的发展趋势就是平台化),选择较高的工作频率可以兼容更多的平台,也方便以后升级和扩展,因此要选择一个较低的可以接受的工作频率。
<strong>2、恰当的输出驱动能力</strong>
<strong>1、基本概念(CMSIS):</strong>
Cortex Micro-controller Software Interface Standard,微控制器软件接口标准。
<strong>2、CMSIS标准的文件结构:</strong>
a) core_cm.c (stdint.h)
b) system_.c (core_cm, system_)
c) startup_.s
其中core_cm.c以及core_cm中为内核外设访问层,其中定义了内核中的外设以及一些内核的访问及控制函数。
startup_.s文件是系统的启动文件,其包括堆和栈的初始化配置、中断向量表的配置以及将程序引导到main()函数等功能。
<strong>1、前言</strong>
在软件开发的过程中,debug(调试)是一个很重要的事情,因为没有百分之百正确的代码,一旦结果不符合预期,我们需要知道问题出在哪里了。
在PC环境下开发应用程序,我们不需要太操心,因为有各式各样的模拟器、调试器可供使用,我们可以追踪到每一行代码的执行过程和执行结果,找出问题只是时间问题而已。但在嵌入式环境下,就有些麻烦了,能用的手段,无外乎两种:
1)使用硬件仿真器定位问题。
2)使用日志输出定位问题。
对嵌入式工程师(特别是linux工程师)而言,鉴于使用硬件仿真器的诸多不便(成本高,无法保证人手一个;硬件连接复杂,需要预留特定接口;使用不方便;等等),日志输出几乎成为必备且唯一的debug手段。但是,总会有例外:
<strong>1、static关键字</strong>
这个关键字前面也有提到,它的作用是强大的。
要对static关键字深入了解,首先需要掌握标准C程序的组成。
标准C程序一直由下列部分组成:
1)正文段——CPU执行的机器指令部分,也就是你的程序。一个程序只有一个副本;只读,这是为了防止程序由于意外事故而修改自身指令;
2)初始化数据段(数据段)——在程序中所有赋了初值的全局变量,存放在这里。
3)非初始化数据段(bss段)——在程序中没有初始化的全局变量;内核将此段初始化为0。
注意:只有全局变量被分配到数据段中。
<strong> 1、前言 </strong>
设备的可靠性涉及多个方面:稳定的硬件、优秀的软件架构、严格的测试以及市场和时间的检验等等。这里着重谈一下作者自己对嵌入式软件可靠性设计的一些理解,通过一定的技巧和方法提高软件可靠性。这里所说的嵌入式设备,是指使用单片机、ARM7、Cortex-M0,M3之类为核心的测控或工控系统。
嵌入式软件可靠性设计应该从防错、判错和容错三方面进行考虑。 此外,还需理解自己所使用的编译器特性。
<strong> 2、防错</strong>
良好的软件架构、清晰的代码结构、掌握硬件、深入理解C语言是防错的要点,这里只谈一下C语言。
对Flash-based的MCU来说,ISP和ICP几乎是不可或缺的功能。但我们经常被这两个功能搞混,究竟他们的差别在哪里?对客户的意义又是什么?在这里,和大家分享并澄清一些观念,希望对大家有所帮助,进而解答来自客户关于ISP与ICP的疑问。
<strong>1)在开发阶段</strong>
改code时,不再需要将MCU从板子上拔起来,拿到烧录器上烧,然后再装回去。可以直接利用ISP/ICP Programmer做板上烧录,为开发者提供了极大的便利性。
<strong>2)在量产阶段</strong>
客户可以采用“先焊到板子上再烧code”的方式,将烧code的动作安排在生产线的某一站。
那么传统的方式(先将code烧好再焊到板子上)有什么缺点?
作者:Founder_U
<strong>1. Cortex-M0 的两种总线协议:</strong>
1)AHB_Lite 系统总线协议:32位地址线,高速高性能访问(Flash, SRAM,总线桥,外部存储器接口)
2)APB 外设总线协议: 32位, 外设等较慢设备通讯(I/O,Timer, UART, Watch Dog。)
系统总线和外设总线是相互分离的,两种总线通过总线桥连接通讯,时钟频率控制不同,可能有多个外设总线段,并且每个段运行在不同的时钟频率下。有些高速外设是直接连接在AHB_Lite系统总线上的。
<strong>2. 存储器映射(4GB地址空间) </strong>
晶振,在板子上看上去一个不起眼的小器件,但是在数字电路里,就像是整个电路的心脏。数字电路的所有工作都离不开时钟,晶振的好坏,晶振电路设计的好坏,会影响到整个系统的稳定性。所以说晶振是智能硬件的“心脏”。
每个单片机系统里都有晶振(晶体震荡器),在单片机系统里晶振的作用非常大,他结合单片机内部的电路,产生单片机所必须的时钟频率,单片机的一切指令的执行都是建立在这个基础上的,晶振的提供的时钟频率越高,那单片机的运行速度也就越快。
复杂的电子产品,晶振是必须的,而RC或LC振荡无法企及,原因就是信号的稳定性不够,而晶振的三种切型:AT切,SC切和X切,把石英按照一定的角度切成薄片,而根据其厚度就可以给出一定的频率信号,根据需要可以任意设计频率值。
作者:Founder_U
<strong>一、 NVIC和系统控制块特性</strong>
1. 灵活的中断管理:使能/禁止中断,优先级配置
2. 硬件嵌套中断支持
3. 向量化的异常入口
4. 中断屏蔽
5. NVIC寄存器的起始地址:0xE000E100, 对其访问必须是每次32bit
6. SCB的起始地址: 0xE000E010,也是每次32bit访问。
<strong>二. 中断使能和清除使能</strong>
1. 中断寄存器是可编程的,用于控制中断请求(异常编号16以上)的使能(SETENA)和禁止(CLRENA), 如下所示:
作者:Founder_U
<strong>1、异常类型及编号 </strong>
Cortex-M0的每个异常源都有一个单独的编号:
1~15内部系统异常:Reset(1), NMI(2), H/W Error(3), SVC(11), PndSV(14), SysTick(15)其他编号未用;
16~47外部中断:IRQ#0~IRQ#31。
<strong>2、异常优先级 (Cortex-M0 支持7个)</strong>
1). Cortex-M0 支持3个固定的最高优先级(Reset(-3), NMI(-2), H/W Error(-1))和4个可编程优先级;
作者:linuxer
<strong>一、前言</strong>
kernel的整个启动过程涉及的内容很多,不可能每一个细节都描述清楚,因此我打算针对部分和ARM64相关的启动步骤进行学习、整理,并方便后续查阅。本文实际上描述在系统启动最开始的时候,bootloader和kernel的交互以及kernel如何保存bootloader传递的参数并进行校验,此外,还有一些最基础的硬件初始化的内容。
本文中的source来自4.1.10内核,这是一个long term的版本,后续一段时间的文章都会基于这个long term版本进行。
<strong>二、进入kernel之前</strong>