mcu_reset
单片机复位介绍
经典的STM32内部复位电路如下
可以看到复位分为两大类:内部复位和外部复位
内部复位源通过脉冲发生器在 NRST 引脚产生延时至少 20μs 的脉冲,引起 NRST 保持电平产生复位;
外部复位源则直接将 NRST 引脚电平拉低产生复 位。
外部复位
NRST 引脚上的低电平。
软件复位
将 Arm® Cortex®-M3 中断应用和复位控制寄存器中的 SYSRESETREQ 置“1” 时,可实现软件复位。JLINK对设备的复位就是控制的这一位。Reset: Reset device via AIRCR.SYSRESETREQ.
内核复位
在Cortex-M内核文档中大概有这样的描述:通过设置 NVIC 中应用程序中断与复位控制寄存器(AIRCR)的VECTRESET 位,可只复位处理器内核而不复位其它片上设施。
也就是说,这样操作只复位Cortex-M内核,不会复位UART这些片内外设。
1 | void NVIC_CoreReset(void) |
系统复位
软件复位中的系统复位操作的寄存器位(SYSRESETREQ)不同,复位的对象为整个芯片(除后备区域)。
系统复位函数:
1 | void NVIC_SysReset(void) |
电源复位
分为上电复位(POR 复位),掉电复位(PDR 复位),从待机模式唤醒。
依靠单片机内部的电源监控电路,在供电电压达不到设定值时自动进行复位。当检测到 VDD/VDDA低于阈值电压 VPOR和 VPDR 时,芯片将会自动保持为复位状 态,上电复位和掉电复位的波形图如下。
低功耗复位
低功耗管理复位的产生有两种情况,一种是进入待机模式时,另一种是进入停止 模式时。在这两种情况下,如果把用户选择字节中的 RSTSTDB 位(待机模式 时)或 RSTSTOP 位(停止模式时)清零,系统将被复位而不是进入待机模式或 停止模式。
复位源查看
可以通过查看 RCM_CSTS(控制/状态寄存器)中的复位标志位识别复位事件来源,也可以相应清除标志位。
pll
PLL原理
由一个基准频率振荡器(晶体振荡器),相位频率比较器,VCO(电压控制振荡器),回路滤波器组成。晶振产生频率为fr的时钟,与VCO产生的fo的时钟同时传入相位频率比较器中进行比较,产生比较结果以脉冲波的形式传入回路滤波器,回路滤波器通过低频将脉冲波转变为直流低压VR,传入VCO对fo进行控制,形成反馈控制电路。
当fr>fo时产生PD为正脉冲,VR变大,当fr<fo时,PD产生负脉冲波,VR减小,形成对fo的闭环控制,最终目的,是fo==fr。
倍频器
PLL的主要功能还是倍频。倍频的实现其实很简单,只要在VCO的后面加一个分频器,时参与比较的Fvco=(1/n)fo,fo’是VCO产生的。这样就实现了Fvco=n*fr。
分频器原理
分频器原理就是之前上的简单的数电知识,在这就一块说了。
主要就说一个偶数分频。
偶数分频器的实现简单,用计数器在上升沿或者下降沿计数,当计数器的值等于分频系数的一半或等于分频系数时,信号翻转。
电路原理是用一个上升沿计数的计数器,每次计数到2时输出信号clkout翻转一次,每次计数到4时clkout再翻转一次,一直周期重复下去。其他的偶数分频器原理也是一样。
uart-speed
串口波特率计算补充
由于单片机内部的RC时钟引起的误差而导致的产品失效,比如 Uart串口通信(常温不可以通信,温度高才行)、Watchdog看门狗复位失灵等等。所以在这里补充一下串口波特率相关计算。“串口波特率的最大偏差多少,对方就不能接收了或出错了?”
最常见的10位串口的输出时序( 1个起始位 + 8个数据位 + 1个停止位 )
我们要确保实际波特率对应的 D0 ~ D7 时区段,都分别落在对方波特率的采样点的范围内,
从多个常见的波特率推送来看,****最大偏差一般在5% 以内都可以正常通信。
但考虑到不同芯片的采样点的方式有所不同,以及一帧的串口位不同(数据位越长,累计的偏差会更多),建议确保波特率控制在2%以内最好。
- 值得注意的是,每次接收数据采样点均会从第1 bit 数据初始化,这意味着采样偏差并不会累积至下一次数据传输,如图1所示,每次检测到下降沿时将重新开始进行数据采样。
mcu_cold_restart_question
转载 –> 单片机冷启动下重启问题分析
问题现象
客户反馈MCU作为他们产品的控制芯片,在常温下工作是正常的,但是稍微冷冻下就会启动失败,重现率100%,再次加热或者恢复到常温又能正常工作。
问题分析解决
从客户描述上来看,猜测很大可能是硬件问题,因此带了一块STM32F030-NUCLEO板过去,想着做个芯片交换测试看下结果。
到达客户现场,了解到客户只是使用了内部高速晶振HSI。先使用示波器抓下VDD和NRST的启动波形,在常温下发现并没有明显异常。于是做低温测试,为了对比,基于STM32F030-NUCLEO板了写了一个只使用内部高速晶振HSI , 翻转一个LED灯的程序。
结果显示,STM32F030-NUCLEO板能正常启动,而客户的板子问题重现,再次测量其VDD和NRST的启动波形,发现VDD上电过程中有稍微不规则波形,但感觉不至于导致MCU无法启动。考虑到当前客户板子上的MCU跑的是客户自己的程序,为了统一对比,将客户板子上的MCU烧录成NUCELO板上一样的程序,再次做低温测试,结果显示客户的板子也能正常启动!
于是可以初步断定,此问题与客户自己的软件有关,而与外围电路无关。
接下来对比测试代码与客户自己的代码,并再次做低温测试验证结果,最终发现客户的时钟树配置有个参数有问题:
如上红色代码所示,RCC_OSCILLATORTYPE_NONE改成RCC_OSCILLATORTYPE_HSI后。问题现象明显改善,但经过测试,发现偶尔还会启动不正常的时候。但相对于之前100%可以重现的现象,至少说明之前软件的失误至少是一个因素。
现在问题变成偶尔重现,已经向前迈进一大步。接下来怀疑与硬件有关了,理由是同样的测试软件跑在用户的板子上和跑在NUCELO软件上的结果不一致。
因此接下来首先对于用户的板子的外围电路与STM32F030-NUCLEO板子的外围电路,发现客户MCU的BOOT0引脚是悬空的,于是加上一个外部10K下拉电阻,再次测试问题不再重现。
至此,问题解决!
后话
回过头来看这个问题,发现客户知道MCU使用的是HSI,可偏偏在代码中配置时钟树时使用的晶振类型却是NONE !这种问题现在看来是非常低级的问题,但在代码量大,或者代码迭代的过程中,之前写代码的人离职,后续接手的工程师又不能全盘了解所有代码的情况下时就会变得束手无策,当碰到此类莫名其妙的问题,特别是无法判断到底是硬件问题还是软件问题的时候,保持清晰的思路是非常重要的。(另外,对于这个现象,看门狗也是可能是一种思路。比如说冷启动的时候导致看门狗模块异常不能及时喂狗所导致的重启)。继续补充一下。在低温环境,要注意晶振负载电容随温度的变化。
这里我需要强调的是,最有效的解决方法就是快速找到一个 “参照物”,而ST的DEMO板和示例代码就是在硬件上和软件上扮演这样一个参照物的角色。可以通过MCU交换测试来判断是不是芯片外围电路的问题或者芯片问题,可以使用Cube库下的示例代码,对比其运行结果来判断是否与软件有关。先从大方向明确问题到底是与硬件有关还是与软件有关,然后再做下一步分析,这种方法希望读者能有效掌握。
总结
转载这篇文章,对思路进行一下开阔,有的问题可能看似与软件无关,实则确实息息相关。遇到异常的时候,首先分析时钟,电源,复位是否都是正常,不论是从软件还是从硬件上来确认。
linux-udev
networkcard-cfg
Linux下网卡命名规则
rename 规则
1 | step1 依据/usr/lib/udev/rules.d/60-net.rules, 查看是否有ifcfg-xx配置文件(路径在/etc/sysconfig/network-scripts/), |
传统命名
centos6之前采用的都是传统的命名方式,如eth0,1…
可预测的命名
cenos7之后提供了可预测性的网卡命名方式。
1 | 如果从BIOS中能够取到可用的,板载网卡的索引号,则使用这个索引号命名,例如: eno1,如不能则尝试2 |
自定义规则
1 | 在用户没有自定义rules文件前提下,step1中的网卡命名方式也可认为是一种用户自定义的网卡命名, |
udevadm info /sys/class/net/网卡名
可以显示此时这个网卡的pcie信息,vendor_id,idbus等等信息
1 | root@Bai5gc:/sys/class/net/eth1# udevadm info /sys/class/net/eth1 |
ps:解释一下pci地址
/pci0000:00
:这是根 PCIe 控制器的地址,pci0000:00
表示根控制器。/0000:00:02.2
:这是连接到根控制器的第一个 PCIe 设备的地址。0000:00:02.2
表示这个设备的总线号、设备号和功能号。/0000:03:00.0
:这是连接到第一个 PCIe 设备的下一个 PCIe 设备的地址。0000:03:00.0
表示新设备的总线号、设备号和功能号。
命名rule.d
biosdevname和net.ifnames两种命名规范
1 | net.ifnames的命名规范为:设备类型+设备位置+数字 |