发帖数

53

原创数

53

关注者

11

阅读数

13118

点赞数

1

黄忠

  • 单片机支持操作系统的特性


    大家好!我是张飞实战电子黄忠老师!今天给大家分享单片机支持操作系统的特性。

    1、支持操作系统的特性概述:

    就拿M0核的单片机来说,就有一部分特性是针对嵌入式操作系统的(OS),包括:

    SysTick定时器,24位向下计数,且周期产生SysTick异常。

    栈指针,即进程栈指针,两个栈指针的结构可以使得应用栈和OS内核栈相互独立。

    SVC异常和SVC指令,通过异常机制,应用程序可以使用SVC访问OS服务。

    PendSV异常,其可以被OS、设备驱动或者应用程序使用来产生可延迟的服务请求。

    2、为什么要使用嵌入式操作系统?

    当提到操作系统的时候,大多数人首先会想到WindowsLinux之类的桌面操作系统。这些操作系统要想运行起来,需要强大的处理器、大量的存储器以及其他硬件,而对于嵌入式设备,各种OS的差别很大。嵌入式操作系统可以运行在低功耗的微控制器上,它们需要很少的存储器(相对于桌面系统),并且运行的时钟频率要低很多,比如Keil RTX只需要4KB的程序空间以及大约0.5KBSRAM,一般情况下,这些操作系统设置不需要显示或者键盘。当然也可以增加一些显示接口和输入设备,并且通过运行在OS上的应用任务来访问这些输入和输出接口。

    在嵌入式应用程序中,OS一般用来管理多任务。在这种情况下,OS将处理器时间划分多个时间片,并且在每个时间片上执行不同的任务。当一个时间片结束时,OS任务调度器开始执行,这样在下一个时间片开始的时候,处理器已经切换到其他任务执行了。这种任务切换一般被称作上下文切换。

    每个时间片的长度依赖于硬件以及操作系统的设计,有些嵌入式操作系统每秒会进行几百次的任务切换。

    有些嵌入式OS也为每个任务定义了优先级,这样高优先级的任务就能在低优先级任务之前执行。如果一个任务的优先级比其他的都要高,在其到达空闲状态前,OS可能会连续多个时间片都在执行这个任务。应该注意的是,OS的优先级的定义与异常优先级是完全独立的(例如中断的优先级)。任务的优先级基于特定的OS,并且随着OS的不同而有所区别。

    除了支持多任务以外,嵌入式OS也提供了其他各种功能,包括资源管理、内存管理、电源管理,以及应用程序编程接口(API)用以访问外设、硬件和信道。


    hu.jpg

    使用嵌入式OS并不总是有好处的,因为它需要额外的程序空间来存放OS内核,而且会增加执行周期的开销。多数简单应用并不需要嵌入式OS,不过,有些复杂的嵌入式应用需要并行执行任务,这时使用OS会使软件开发更加容易,并且降低出现错误的概率。

    目前,可以应用在M0上的嵌入式OS有很多,例如,Keil 微控制器开发套件提供的免费且易于使用的RTX kernel,另外还有Micriumuc/OS-IIuc/OS-III等都支持M0处理器。并且这个支持的操作系统在不断的增加中。

    由于很多微控制器是不具备存储器管理单元(MMU),比如我们上面时候的M0核的处理器,所以它不能运行需要虚拟地址的嵌入式OS,比如Windows CESymbian OS。平常使用的Linux OS也需要MMU,它也不能再M0上工作。而uCLinuxLinux的特殊版,并且面向的是没有MMU的嵌入式设备,所以要在微控制器上加入OS也要先看能不能支持,并且支持哪些,再结合自己的项目实际选取。

     


    收藏 0 回复 0 浏览 185
  • 讲解ADC模数转白话

    首先我们来简单介绍一下ADCADCAnalogToDigitalConverter简单来讲就是它可以把模拟量转化为数字量方便程序去处理

    下面我们来看一下ADC的框图,我们从框图上来介绍ADC采样的原理

    图片19.png 

    1. 外部被采样信号从单片机特定的引脚输入ADC模块,具体信号从哪个采样引脚输入,取决于‘通道选择’配置。

    2. 当正常开始采样后,被采样信号在规定的时间(即采样时间)内对图中的电容(即采样保持电容,简称采保电容)充电,当充完电之后会控制图中的开关断开,这个过程就像科学家提取了一份标本,拿回实验室研究一样。

    3. 当开关断开之后,图中的转换模块会花费一定的时间(即转换时间)对电容中的存的电压进行转换,并把转换的结果存入缓冲器,供程序员读取使用,同理,就像科学家对提取的标本花时间研究,得出一个结果。

    以上就是整个的ADC工作过程,虽然草草几段话了解,但是其中不乏很多关键的细节问题,什么细节问题呢,很多老铁会想,这不都是自动的嘛,有嘛要注意的,那么我们先来看一下这样几个问题。

    1. 采样时间设置多久?

    2. 采样时间是越短越好还是越长越好?

    3. 采样时间设置的大小和被采样信号的源内阻有什么关系?

    4. 如何从有干扰的信号中提取有用的采样信号,实现正确采样?

    5. 采样的结果和参考电压有什么关系?

    现在我们就上面几个问题,展开说明:

    上面的描述可以得到:从采样到转换完成中间2个时间采样时间+转换时间转换时间是固定的,采样时间可以设置),这两个时间决定了ADC采样的速度问题当需要高速AD采样的时候,这两个时间尤为重要因为它决定了采样速度

    我们再回头来想这里是被采样信号先对采保电容充电因为转换时间是固定的我们能配置的就只有采样时间了是不是说采样时间我们配置的越小越好呢答案是:不是的,最起码得保证采保电容电压和被采样信号的电压非常接近吧如果一味的小,追求速度快,采保电容充不满,转换出来的数据也不对

    那就带来了一个问题这个被采样信号源内阻的问题说白了就是对这个采保电容充电的电流够不够大只有充电的电流大了,才能在最短的时间内充满如果充电的电流非常小,恰恰配置的采样时间很小,结果只有一个,采样不准确我们经常看到,有的设计方案,做电压采样,分压电阻设计的阻值非常大当这样的大阻抗遇到高速采样,那就有可能会不准确了

    图片20.png 

    大家看上面的R1R2设置大了,那么充电电流就小了那么R1R2的阻值设计小了,充电电流大了,那么带来的问题功耗就大了当需要高速采样的时候,就需要注意这个阻值分配的问题对功耗要求比较高的产品,如可穿戴产品,蓝牙耳机,智能手表等,这个就需要大的阻值了一般情况下功耗要求不高的场合,我们基本上设计在1-2mA所以从此可以得出一个结论,采样时间不是越快越好,也不是越慢越好,恰到好处即可,需要你去实际调试。

    如何从带有干扰杂波的信号中提取到有用的信号呢,一般情况下,我们会根据系统的特性进行定点采样,即避开干扰区来采样提取有用的信号,再配软件或者硬件滤波手段来提取有用信号。

    采保电容得到了准确的采样信号,就一定意味着转换结果准确吗?答案肯定

    NO,这个和参考电压也有关系,参考电压就像一标准样品一样,举例来讲:老板说照着这个样品给我做100个,那首先前提是你的样品得准确,如果样品都不准确,那做出来的东西也必然会有偏差。

    想必通过上面的描述我们已经对ADC采样有了一定的理解认知,上面的描述只是ADC的一部分要点,介于篇幅原因,这里就不再赘述了,文末留个大家几个问题:大家看图中绿色地方电容这个电容加了好还是不加好?加多大好?在布板的时候这个电容应该摆放在哪里比较好?

    图片21.png 



    收藏 0 回复 0 浏览 168
  • 异常和中断

    异常是能够引起程序流偏离正常流程的事件,当异常发生时,正在执行的程序就会被挂起,处理器转而执行一块与该事件相关的代码(异常处理)。事件可以是外部输入,也可以是内部产生的,外部产生的事件通常被称作中断或中断请求(IRQ)。几乎所有的现代处理器都支持异常和中断,微控制器的中断可以由片上外设或软件产生。由此可见,通常我们处理的中断是异常的一种。

    每种异常类型都有对应的优先级,有些异常的优先级是固定的,有些是可编程的。

    先说几个概念:

    1、不可屏蔽中断(NMI

    NMIIRQ类似,只是它不能被禁止,并且优先级仅次于复位,它对于工业控制和汽车之类的高可靠性系统非常有用。根据微控制器设计的不同,NMI可以用于掉电处理,也可以连接到看门狗单元,以便在系统停止响应时将系统复位。由于NMI不能被控制寄存器禁止,其响应的及时性就得到了保证。

    2、硬件错误

    硬件错误异常用于处理程序执行时产生的错误,这些错误可以是试图执行未知的操作码、总线接口或存储器系统的错误,也可以是试图切换至ARM状态之类的非法操作。

    3、SVC(请求管理调用)

    SVC指令执行时就会产生SVC异常,其通常用在具有操作系统的系统中,为应用程序提供了访问系统服务的入口。

    4、PendSV(可挂起的系统调用)

    PendSV是用于带OS(操作系统)的应用程序的另外一个异常,SVC异常在SVC指令执行后会马上开始,PendSV在这点上有所不同,它可以延迟执行,在OS上使用PendSV就要确保高优先级任务完成后才执行系统调度。

    5、系统节拍

    NVIC中的SysTick定时器为OS应用可以利用的另外一个特性。几乎所有操作系统的运行都需要上下文切换,而这一过程通常需要依靠定时器产生定时中断来完成。

    6、中断

    中断信号可以连接到片上外设,也可以通过IO端口连接到外部中断源上。外部中断只有在使能后才能使用,如果中断被禁止了,或者处理器正在运行另外一个相同或更高优先级的异常处理,则该中断请求会被存储在挂起状态寄存器中。当高优先级的中断处理完成或返回后,挂起的中断请求才可以执行。NVIC能够接受的中断请求信号可以是高逻辑电平,也可以是中断脉冲。应该注意的是,在微控制器的外部接口中,外部中断信号可以是高电平也可以是低电平,或者可以通过编程配置。

    异常的处理流程

    1、接受异常请求

    处理器要接受一个异常,需要满足的条件:

    ①对于中断和SysTick中断请求,中断必须使能

    ②处理器正在执行的异常处理的优先级不能相同或更大

    ③中断屏蔽寄存器没有屏蔽掉异常

    特别注意一点:对于SVC异常,如果用到SVC指令的异常处理的优先级与SVC异常本身相同或更大,这种情况就会引起硬件错误异常处理的执行。

    2、压栈和出栈

    为了使被中断的程序能正确继续执行,在程序切换至异常处理前,处理器当前状态的一部分应该被保存。不同架构处理器的处理方法不同,有的采用硬件自动处理的方法来备份和恢复处理器状态,看需求,有的是需要程序中增加软件处理过程。

    异常处理过程执行到最后时,将会利用执行特殊值来触发异常返回机制。处理器还会查看当前是否还有其他异常需要处理,如果没有,处理器就会恢复之前存储在栈空间的寄存器值,并继续执行中断前的程序。

    自动保存和恢复寄存器内容的操作被称为“压栈”和“出栈”,这种机制使得异常处理可以跟普通的C函数一样处理,同时也减小了软件开销以及回路大小,因此也降低了系统的功耗。

    3、异常返回指令

    根据处理器的不同中断处理返回有的需要特殊指令,一般都是普通的返回指令,加载到PC中的数值则会触发异常返回,这样就使得异常处理可以和普通的C函数一样使用。

    两个不同的指令可以用于异常返回:

    BX  <Reg>q     ;将寄存器中的值加载到PC

    POP {<Reg1>,<Reg1>,...,PC}  ;POP指令,PC也是更新的寄存器之一

    当其中一个指令执行,异常返回机制就会启动。

    4、末尾连锁

    如果当其他的异常处理完成后,还有异常处于挂起状态,这时处理器不会返回到中断前的程序,而是重新进入异常处理流程,这也被称作末尾连锁。当末尾连锁发生时,处理器不必马上恢复栈的值,因为如果这么做的话还得重新压栈。异常的末尾连锁降低了异常处理的开销,因此也提高了能耗效率。

    图片1.png

     


    收藏 0 回复 0 浏览 166
  • USB之特殊包

    前面文章我们说了令牌包、数据包、握手包,今天我们来看最后一个特殊包,本篇文章主要说明特殊包以及如何处理数据包,下面们开说.

    特殊包是一些在特殊场合使用的包。总共有4:pErSPLITPNG其中PRESPLITPING是令牌包,ERR是握手包。ERRSPLITPING三个是在USB2.0协议中新增的。

    PRE是通知集线器打开其低速端口的一种前导包。PRE只使用在全速模式中。平时,为了防止全速信号使低速设备误动作,集线器是没有将全速信号传送给低速设备的。只有当收到PRE令牌包时,才打开其低速端口。PRE令牌包与握手包的结构一样,只有同步域、PIDEOP。当需要传送低速事务时,主机首先发送一个PRE令牌包(以全速模式发送)。对于全速设备,将会忽略这个令牌包。集线器在收到这个令牌包后,打开其连接了低速设备的端口。接着,主机就会以低速模式给低速设备发送令牌包、数据包等。

    PING令牌包与OUT令牌包具有一样的结构,但是PING令牌包后并不发送数据,而是等待设备返回ACK或者NAK,以判断设备是否能够传送数据。在USB1.1,是没有PING令牌包的。只有在USB.0高速环境中才会使用PING令牌包,它只被使用在批量传输和控制传输的输出事务中直接使用OUT令牌包发送数据时,不管设备是否有空间接收数据,都会在OUT令牌包之后跟着发送一个数据包,如果设备没有空间接收数据,就返回一个NAK这样的结果就是浪费了总线带宽,白白传送了数据。在高速设备中增加了这个PING机制,主机先用PING令牌包试试设备是否有空间接收数据,而不用事先把数据发送出去。在全速模式下,有时会遇到一个很有趣的现象,就是下位机程序慢了一点点处理完数据,结果传输速度却下降了很多。这就是前面所说的OUT过程直接发送数据导致的,也就是说,虽然程序只慢了一点,但是却丢弃了整个数据包。

    接下来我们来说说如何处理数据包. SPLIT令牌包是高速事务分裂令牌包,通知集线器将高速数据包转化为全速或者低速数据包发送给其下面的端口。ERR握手包是在分裂事务中表示错误使用。由于高速分裂事务过程比较复杂,主要属于集线器的功能,在此就不详述了,感兴趣的读者可以阅读USB2.0协议相关部分。

    这么多类型的包以及传输过程,那我们该怎么去处理呢?其实,如果使用现成的USB接口芯片,很多过程,USB接口芯片都已经处理好了,可以不用太关心这些细节,只要知道有这么一个过程就行了。

    一般的USB接口芯片会完成如CRC校验、位填充、PD识别、数据包切换、握手等协议的处理。

    USB接口芯片正确接收到数据时,如果有空间保存,则它将数据保存并返回ACK,同时,设置一个标志表示已经正确接收到数据;如果没有空间保存数据,则自动会返回NAK

    收到输入请求时,如果有数据需要发送,发送数据,并等待接收ACK。只有当数据成功发送出去(即接收到应答信号AC)之后,它才设置标志,表示数据已成功发送;如果无数据需要发送,则它自动返回NAK

    通常只需要根据芯片提供的一些标志,准备要发送的数据到端点,或者从端点读取接收到的数据即可。所要发送和接收的数据是指数据包中的数据,至于同步域、包标识、地址、端点、CRC等是看不到的在 BUS Hound中抓到数据也是如此,仅是数据包;并且, BUS Hound中只能看到成功传输的数据,即只有ACK确认过的数据包。在USB接口芯片中,通过一些标志可以知道是哪个端点接收或者成功发送了数据。另外,由于控制传输比较特殊, SETUP包也会有相应的标志供我们使用。

    至此为止我们的包结构和包分类就全部说完了,通过对这些包的了解,我们会更加清楚的认识USB的通信知识.对我们做USB通信有很大的帮助.希望通过文章的内容分享,能给大家带来收获.


    收藏 0 回复 0 浏览 166
  • STM32中断如此简单

    大家好,我是张飞实战电子黄忠老师,下面我们先来了解一些基本概念:

    中断:中断是什么?举个例子来说,当我们正在工作时,突然电话响了,这时你会把手里的工作先停下来,然后去接电话,当接完电话后,电话里的人安排你马上做一件事,这时你需要立刻去做这件事,当把这件事做完后你会继续之前被打断的工作,这个过程为一次中断。

    异常:一个系统本应该正常的运行,但由于某些条件使系统产生了错误,就会使系统运行不正常,我们称之为异常。就好比一个健康的人,如果身体某个器官出现了问题,那他将会生病,不能像以前那样健康生活,称他的身体出现了异常。系统出现异常,我们必须对异常做出处理,才能让系统正常运行。

    事件:比如一个老师在教室里给学生上课,下面的学生会做出各种不同的动作,如有认真记笔记的,有讲小话的,有翻自己书包的等等,我们把学生的这些行为称为事件。但老师对这些事件有些是不会有动作的,有些事件是需要老师干预的,比如两个学生讲话,影响了老师上课,老师需要警告讲话的学生,然后再继续上课。

    优先级:当我们接到了两个电话,两个电话都安排你去做别的事,这时你需要先完成比较急的事,然后再完成不是太急的事,这就是优先级的问题。当有多个中断时,我们需要根据中断优先级判断先响应优先级高的中断,然后再响应优先级低的中断。

    中断与事件的联系与区别:有些事件需要响应,称这个事件为可中断事件,但有些事件不需要做出响应称这些事件为不可中断事件。当硬件正常连接时,对应事件会自动产生,但中断则需软件配置相应的中断使能位。

    抢占式优先级和响应优先级:所谓抢占式优先级和响应优先级,具有高抢占式优先级的中断可以在低抢占式优先级中断处理过程中被响应,即中断嵌套。当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后 才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。每一个中断源都必须定义2个优先级。

     

    STM32的中断管理利用了NVIC(Nested Vectored Interrupt Controller)嵌套向量中断控制器,它把所有的外设中断和系统异常用一张向量表来管理,每个系统异常和外设中断都被分配相应的地址,除了一些系统异常的优先级不能改变外,其余的系统异常和中断的优先级都可变化。具体向量表部分截图如下图所示:

     图片27.png图片28.png        

    29.png                  

    其中包含10个系统异常,有82个外部中断地址,其中有11个被保留,没有使用,从上表可查出对应的默认优先级和地址分配情况。

    NVIC是嵌套向量中断控制器,它控制芯片所有中断功能,是Cortex-Mx内核里的一个外设下图为Cortex-M4内核NVIC寄存器的分布图:

    30.png 

    从上图可以看出,Cortex-M4内核NVIC嵌套向量中断控制器总的有7个类型的寄存器,其中有1个控制器类型的寄存器,8个中断使能寄存器,8个中断失能寄存器,8个中断挂起设定/清除寄存器,8个中断有效位寄存器,60个中断优先级寄存器。而STCM4内核NVIC控制器寄存器做了一定缩减,其寄存器分布图如下:

    31.png 

        在中断编程时,我们一般使用ST提供的固件库,对中断配置在程序编写时我们一般就使用中断使能、中断失能、中断优先级设定三个寄存器。

    NVIC嵌套向量中断控制器里有一个用于管理中断优先级的寄存器NVIC_IPRx(x=0,1,20),其数据位宽度为8bit,如果8位全使用,则可配置的优先级为0-255,数值小的优先级越高,但在STM32F373中,只是使用了高4位,可配置的优先级为0-15

    4位又被分为抢占优先级和响应优先级。对这4位又有5种搭配方式,定义抢占优先级和响应优先级的位数,其分组由内核外设SCB模块的应用程序中断及复位控制寄存器AIRCRbit8-bit10(PRIGROUP[0:2])三位决定,分组可用下图所示:

    32.png 

    ST官方已经把设定优先级分组封装成了一个库函数,我们设置优先级分组时,可直接调用相关库函数即可,中断库函数可在官方库文件misc.cmisc.h中找到,其优先级分组设定函数如下图所示:

    33.png 

    如我们想设置0位响应优先级、4位抢占优先级即优先级分组0,其函数可写为:

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    那我们仅仅是配置了优先级就够了吗?我们还需要配置通道,即配置中断源,按照前面中断向量表中的Position中断编号来查询即可配置即可。配置了中断源后,我们还需对中断源使能中断,ST官方把通道配置、优先级设定、通道使能定义为了一个结构体,其定义如下:

    34.png 

    下面我们以USART1为例,配置中断优先级分组为3,即3位响应优先级,1位抢占优先级,抢占优先级级数为0,响应优先级级数为1,对其编写程序如下:

    Void NVIC_Init(void)

    {

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);         //配置优先级分组

    NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;      //USART1中断通道

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为最高 0

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //响应优先级为 1

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //使能中断通道

    NVIC_Init(&NVIC_InitStructure);    //将结构体成员的值写入对应的寄存器

    }

     

    至此,中断篇讲解完毕,更多详细的NVIC的介绍,可查阅官方技术手册NVIC部分。


    收藏 0 回复 0 浏览 162
×
黄忠