0%

linux设备启动过程

一开始就是芯片厂商的引导程序了,然后就到uboot,接着加载内核和驱动,挂载根文件系统,加载虚拟文件系统,加载tty中断,自启动开机脚本和软件。

uboot

uboot 属于bootloader的一种,是用来引导启动内核的,它的最终目的就是,从flash中读出内核,放到内存中,启动内核

所以,由上面描述的,就知道,UBOOT需要具有读写flash的能力。

uboot使用

uboot刚开始被放到flash中,板子上电后,会自动把其中的一部分代码拷到内存中执行,这部分代码负责把剩余的uboot代码拷到内存中,然后uboot代码再把kernel部分代码也拷到内存中,并且启动,内核启动后,挂着根文件系统,执行应用程序。

为什么要uboot

1)uboot主要作用是用来启动操作系统内核。体现在uboot最后一句代码就是启动内核。
2)uboot还要负责部署整个计算机系统。体现在uboot最后的传参。3)uboot中还有操作Flash等板子上硬件的驱动。例如串口要打印,ping网络成功,擦除、烧写flash是否成功等。
4)uboot还得提供一个命令行界面供人来操作。很简单,至少你能看到。

计算机系统的组成部件非常多,不同的计算机系统组成部件也不同。但是所有的计算机系统运行时需要的主要核心部件都是3个东西:CPU + 外部存储器(Flash/硬盘) + 内部存储器(DDR SDRAM/SDRAM/SRAM)。而一般的PC机启动过程为:PC上电后先执行BIOS程序(实际上PC的BIOS就是NorFlash),BIOS程序负责初始化DDR内存,负责初始化硬盘,然后从硬盘上将OS镜像读取到DDR中,然后跳转到DDR中去执行OS直到启动(OS启动后BIOS就无用了)。

uboot环境变量
uboot修改
uboot烧写
uboot和裸机

一般uboot都是有一个开机时间,也就是倒计时,这个期间进行任意键输入就会取消加载内核,从而变成变成裸机开发。

此时就是跟51的单片机开发一样了,对着手册看着寄存器进行编写,然后把代码编译完毕,ftp传到特定地址,然后去运行那个地址的代码,就是裸机运行了,不过这个一般只是用来测试硬件的而已,不会真的裸机开发的。

总结

什么地方用到了ISO?

这里的iso,可不是网络七层协议/OSI七层模型。

这刚入门linux,搞VMware虚拟机的都应该见过,但是,当时大家都是萌新嘛,谁记得那么多东西,库库一顿导入,虚拟机跑起来就高兴了,然后就是跟着那些博客、手册一步步配置环境了。

这里就用一个镜像系统,也就是ISO,是有人把ubuntu、Debian这类系统拷贝了一份得到了镜像,生成了ISO格式,然后VMware虚拟机才能加载系统,才能干之后的事情。这样一说,估计大家就有印象了。

IMG又是啥?
两者差异是什么?
我想要搞一个自己的系统
ISO怎么生成
IMG怎么生成
总结

都是加载系统的,不过,两者差异还是比较大,一个类似hex,一个类似bin,但是他们的目的都是一样为了得到一个系统镜像。

Linux的缓冲区
重定向
文件标识符
日志系统
历史操作
操作查询

起因

无聊摸鱼,突然看到一个进度条一样。我就想到了这个进度条是怎么实现的呢?我们下载软件,下载插件,下载东西,编译的时候都可能会出现tty终端的进度条。我就好奇了,cmd和shell那些终端这个命令行不应该是输出一行的吗?就像我串口打印出来的东西,不可能把我已经输出的东西,在显示端删掉啊,在重新打印一边的,肯定就是换行处理了,这个不换行又覆盖打印是怎么做到的呢?

区别

我们一般进行调试,有232也有串口进行对MCU、MPU、ARM-A板子的串口调试,这个时候,处理器是直接使用串口打印的,就是把串口缓冲区立马的数据输出出来,发送给我,而我在把他显示出来,因为,显示肯定是不能丢失接收数据和信息,所以,就会全部打印,换行打印。所以来一条打印一下,显示一条符合要求和调试。

这里就有一个误区了,因为我们使用tty的时候,还没输出出去哦!

这个什么意思呢?意思就是我们这个系统还没对外输出而是内部操作,此时tty不是一个串口输出的过程,而是,直接读取一个缓冲区内部的数据。没错,tty就是一个缓冲区,它不是日志系统,不会记录所有操作,记录操作是其他功能做的,它就是一个缓冲区,也就是说,我们做的一大堆操作,其实都是在缓冲区里进行的操作,此时都没对外输出,当然可以覆盖自己缓冲区数据,然后tty显示这个缓冲区数据。当然,其他的打印和日志系统就会把每个操作,每个情况,每个数据都记录下来啊。

实现

此时直接使用回车就可以,清空本行,重新覆盖输出了,就可以实现进度条的操作了。
这里还有一点就是回车和换行,回车是\r 换行是\n;
我们在学c语言的时候,肯定打印函数和输入函数也即是scanf和printf这两里面用了很多换行,也经常会发现他们两个的效果是很相似。这是因为发送完毕,换行会直接清空缓冲区,而回车是回到首行开头,这个就有点文件io的光标的味道了,缓冲区清空了,这个时候回车肯定就是原地蹦一下而已嘛。

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

mark=''
for ((ratio=0;${ratio}<=100;ratio+=5))
do
sleep 0.2
printf "progress:[%-40s]%d%%\r" "${mark}" "${ratio}"
mark="##${mark}"
done
echo

总结

tty终端不是日志系统,它是一个收发缓冲区,它显示的内容是它缓冲区的内容,此时都没对外输出,所以它不会显示所有情况、数据、消息,只会显示缓冲区里有东西。此时,想要覆盖上一次的结果,echo就不要换行 -ne 此时直接回车到开头,然后清空本行,输出就好了,这个是只能在终端才能实现的哦。如果使用那种rt-thread那种FinSH控制台,这个就是串口输出啦,就是对外输出了,此时修改缓冲区是亡羊补牢了,因为缓冲区的数据已经被打印出来了,自然在显示端就会出现换行,而且无法覆盖上一行的操作,也无法实现进度条了捏,呜呜呜。

电源问题

这个问题,非常容易忽略,也就是,目标设备是否有外部电源或者内部电源。这个问题会影响到生产中的一些措施,设置连开发过程都会影响。

  • 一直使用swdio进行debug,却没注意到,这个swdio的vcc已经承担了供电的职责,可能会忽略没有供电的时候出现的异常bug。其实,内部线路,可能是有问题的,但是供电有了反而一切都是正常的,很可能硬件握手失败都开不了机呢。常见于热插拔设备上面。

  • 外部电源,这个电源是多大的,这个电源太大了怎么办,工人进行装配的会不会出现需要外部供电才能进行处理的操作,如何升级,如何操作等。

  • 内部电源,这个常见就是低功耗问题了,要知道一个设备的寿命,可以用多久,一般都是按照几年来处理的,一些物联网设备,或者可以外接电源的时候随便充电的策略。

  • 发热问题,这个其实很多时候也是会影响设备运行的,cpu和gpu那些都是要散热的,同理,你的温度可能会到值金属变形,可能导致电机行程异常,主控宕机,硬件损毁等诸多问题

生产顺序

这个问题,还是在电子件、模块、结构之间的顺序问题。

  • 后配置电子件,然后通过外部来进行标定和升级,这个常见于传感器和adc上面,因为只有结构装备完毕才能保证数据是正确无误的。
  • 先配置电子件,就是比如序列号啥的的,一些协议,数据,功能啥的,都不需要外部结构,而是可以通过模块来实现操作的,这个就不用担心外部的结构了,所以可以先配置好电子件,然后在安装。
  • 模块和结构,这个可以认为模块和结构合二为一,又或者说只有结构,模块就是普通的引脚电平啥的,这个时候就看是否是传感器类型的了,只是电平开关的话,就非常好处理了。
标准治具

也是一个生产规格的问题了,电机、adc、大小、孔径等,这些一系列的东西都是需要一个标准来检测和处理,这个时候就需要治具了

  • 电机治具,这个就是检测在行程之内的速度、电流、行程等处理,也可以在电机上面添加霍尔传感器来知道此时电机位置等方法,来确保电机是正常的,这样就组装了

  • 孔径治具,可以直接发射光束来作为标准,上面发送,下面接收,就知道误差范围了,这个治具设计就非常复杂和严谨,还得注意考虑灯丝温度和治具措施,一般都是购买国外进口的专门测试工具

  • 通信治具,写好一个设备,肯定需要快速检测,一般用于测试从机,因为工人是不懂代码的,只想快速验证。所以,一个比较简单,比较快速验证产品正常的东西是利于生产和检测的。

  • 老化治具,就是专门用来跑的,超频,提速,升温,升压,低温等处理,这个就是为了检测寿命的,一般是老化柜那样的东西,不过,想要自己做一个快速测试,也不难的。

  • 长度治具,这个就是尺子了,没啥好说的了。最多是来规定一些电机的运行行程,来保证统一。

    还有很多奇奇怪怪的治具。

测试日志

测试的时候,最好有记录和日志,这样方便bug复现和审查。

所以,串口数据,如果可以还是保留一下,linux的话,就是echo打印出来,重定向输出到专门的日志文件。这个就是看个人习惯了。运维的肯定就非常熟悉了,这个肯定是必不可失的部分,如果连复现都无法做到,这个bug也是根本不可能修复的。

电气规则

常见的ttl 232 485 can等那些电气特性,还有usb pcie m.2 等特有热插拔电气特性。

  • 就需要在生产的时候,注意设计防呆口,防止正负电源问题,还有设计一连串固定,唯一的组装流程,减少带来的外部干扰,还有带上静电环,人体静电还是有影响。

  • 还有就是开发中,可能开发板的电气规则可以工作,但是pcb板子就不能工作,很可能是电平范围错误,导致的通信异常,此时程序是可以运行的,但是因为外部缺少上下拉、电容、电阻、甚至是相位差等问题,导致的无法通信,需要和硬件协商,找到合适的方法实现通信。

产品生产环境

这个,实验室环境、无尘、温度、压强、电源等问题,都可能会导致传感器的误差,这些都是可以避免的,不过很多时候应该影响不大的,注意强磁强电、大噪声等环境问题、灰尘如果进入电路板很可能导致一些未知bug,最好也是杜绝为好。

设备寿命和老化

这个上面有一个老化治具的设计思路,其本质还是担心设备的耐久度,这个就非常值得考虑了,不能说,一个产品用两天就坏了,那谁还买啊,差评如潮。

但是,设备不是永久的,是一定有寿命的,一般是越是大型设备,寿命越长,越是消费电子,寿命越短,物联网设备,一般是几年左右,所以,这里就有内外电池的考虑,太阳能的考虑等

工作环境差异

设备工作区域,多热,外壳会不会化了,内部会不会积热,会不会进水,会不会受到干扰导致起振失败,导致内部emp,共振、振动环境导致螺丝和接口等松动、温度差异带来的传感器误差,电池寿命,电池电量这些都是非常大的问题,都是需要考虑进去的

焊接和贴片机

这个常常发生在pcb生产中,因为国产贴片机的问题太多了,抛料都是正常的现象,后续硬件工程师虚焊也是正常的东西,所以,就非常有必要治具了,确保电子件安装到产品设备之前是正常的。

安全和高效检测设计

这个就是比如,安装空调外机,安装复杂大型设备,不方便拆卸等情况,就需要留一个专门的接口给外部,外部调试线连接测试,就可以立刻知道设备当前状态如何,是否可以确保正常运行,这个高效,同时也一定程度上增加了安全性。这样可以高效抽查,极大程度缩短检测时间,提高现场检测的能力。

自然安全性这个就是要单独拿出来分析的,产品外壳毒性,电路板毒性,任天堂以前的卡带上面就有一些化学物质,非常非常苦,就是为了防止人去舔以及误食,这个也是一个出于安全的设计。外部结构设计是否安全,电路内部电容,电路线,电源线,dc-dc模块等问题。不能像机革那样,自己电脑炸了,还怪用户,至少得保证自己产品不得爆炸吧,三星爆炸手机可是深得人心。

运输结构设计

不能说一个设备长的和刀子一样吧,也就是说,运输的时候,要么就是有配套的外壳和箱子,要么就是设计成方便运行的结构,这个都是机械佬考虑的了,主要还是以应用场景和大小为主。

产品差异补偿

没人敢打包票说每个设备都是ok的,都是一模一样的,一定有残次品,这就是良品率了。优化生产过程,减少外界干扰,多用治具来保证产品的正常,增减检测工序,这个注定是没有最好,只有最适合了。

华为甚至更加过分,屏幕抽奖,一个手机的屏幕,几家厂商提供的产品,每个手机都想抽奖一样,这就导致了产品差异是非常大,如何软件进行调教,硬件去弥补,去做误差补偿,如色域、光亮、帧率等。这个问题是永远没有最佳方案的,都是就事论事,根据实际情况去分析和处理。

生产安全

这个是重中之重,想都不要想,只要出了一条人命和残疾,那不得了,不只是赔钱的问题,而是生产线都可能出现大问题,带来连锁反应,带来的负面影响都是不可估量的。

用电安全,设备摆放,工具摆放,特殊化学品处理区和存储区,禁止明火,不要堵路,地面防滑,尖锐突出,禁止打闹追逐,防夹,注意生产车间的机床注意实现,注意远离机床,不要为了效率而增加风险,一切高危都要做安全措施,不要靠近大型设备等诸多安全问题。

代码设计和能力需求

作为公司项目,肯定不是做着玩的,也肯定不会只有一个,所以,不同的设备就有不同的序列号和参数属性了。同时就要求有可以使用、可以修改的接口。至于使用c cpp rust python 还是什么,只要能实现功能就是好语言,qt可以用python和cpp啊,EPS32和mcu开发也可以实现cpp和python,linux的话,建议还是c开发,也可以使用rust,还可以使用luna,有需求就可以去学习。语言知识一个工具,只要能实现功能就好了。

  • 引导程序

  • 生产中特定flash读写序列号和特殊属性

  • 多层引导设计思路

  • api接口和sdk设计

  • 模块化编程思路

  • HAL、BSP、驱动等

  • 模块调用

  • 内外flash读取 和 特定地址读写

  • 扩容预备 空间预留

  • section数据 attribute对齐规则

  • 代码框架 (这个看公司的设计特点了)

  • 外留接口来实现对外的通信,增加兼容性

  • 技术栈 web、 后端 、app 、mcu 、mpu 、ui 、hmi、算法、运维、其他专业技术、代码和项目管理如gitee github、

  • 静态库和动态库 linux和win的

产品代码加密

要想办法做密钥之类的,东西,加密自己的程序,比如使用section这些来对重要函数进行加密,然后再写回flash,这个是一个很好的加密手段。

上位机

一般产品尤其是控制,遥控,定位的设备,一般都是出异常后需要用户自行矫正的,这个时候,上位机就很有存在的必要,它往往需要跨平台,需要满足多设备,多屏幕。本质就是数据收发而已,不同产品需要校准和设计的上位机是不同的。其实有的时候,会考虑,为什么不用上位机,为什么用上位机呢?我感觉是要分场景的,比如我这里是生产工厂,生产工厂需要电脑吗?自然是除了烧录代码可能需要,测试,也是装机之后才能测试,所以,不存在一边烧录一边测试的太少了。

如果我们是直接面向工厂的,此时,开发一个上位机要考虑的东西,有很多的,电脑本身其实是一个不稳定,环境差异大,不实用的生产平台。而且员工很多都不会用电脑,电脑也容易误触。所以,一个生产治具是最好的了,可以先把代码烧录到治具中,在治具中进行烧录其他设备的操作,这样员工只要操作治具就好了,一个治具是比电脑稳定很多的,而且也不存在环境差异问题。

做过linux开发就知道了,linux难就难在环境配置,系统配置上,真的天差地别,时不时就是我这里运行正常,你那边就跑不了的bug,非常痛苦,如果我直接寄一个硬件治具过来,作为烧录、测试、标定的设备,那么一下子我们就成功同步了,对于直面工厂,生产来说,这个确实是比上位机可靠好用的。上位机更适合代码烧录,固件更新,用户自定义和调节,不适合生产,也不利于生产,治具效率高,体积小,速度快,上位机一般都是一对一,这就比不上治具可以一下子插上去一堆。

上位机的优势:适合客户自定义操作,更新,微调,这个算是售后,一般都是一对一进行操作,也可以用于给用户进行检修等操作。

治具的优势:对接工厂,同步环境和标准,增加生产效率,降低员工要求,设备可靠,可以实现一对多的高效生产需求和测试需求。

统一标准

这个怎么理解呢?不单单是产品的规格,还有就是产品的标准尺度,就像卷尺一样,施工场地的单位长度都不一样呢。

统一标准,就是啥都是一样的,所以,很简单,只要所有车间和工厂都是用一样的标准,就可以做到规范和误差容许。

还有一种就是目标是标准,但是初始配置是不一样的。比如,电机此时速度是100,另一个是200,一样的最大加速度,但是我都要跑2000米,使用pid进行调制之后,就要定位,这个就是需要一个标准。而且两个因为初始速度不一样,所以最后pid调制停下来的位置是不一样的,不过误差可以接受就行了,此时就可以进行一个数据定位,只要电机复位+运行时间,就可以运行到2000米,但是如果你把100的电机速度得到的运行时间给到了200的电机速度的电机时间,就会导致,误差增加,此时,就是违反了统一标准的规则,他们应该都是对其统一标准才对。

看名字就是知道了—猫是液体[doge]。我们根据日常习惯也知道液体这些东西,它会自己去钻缝,会流动,接触面积更大,可以适应很多结构,把液体倒入圆锥体里面,它就变成圆锥体的形态啦。

文件IO和数据流
一切都是数据流
流式传输
流媒体
TCP是一种流式协议
流带来了什么
流的缺点?
总结

DMA

直接存储器访问,看这个名字就知道了,只要知道请求访问地址,访问地址,访问大小,访问模式,就可以实现地址之间的数据转移了。常见的SPI、IIC、USART等。配置好DMA、设置好地址、大小、模式,让CPU给DMA芯片发送这个命令,就会让DMA去干活了,中间cpu都不用管DMA,这就解放了CPU,去干那些耗时而且简单的访问操作。

DMA回调

DMA有错误回调,传输一半回调,传输完毕回调,所以我们只需要在回调函数中进行处理就好了,触发中断获得cpu使用权,开干。注意要使用判断DMA是否HAL_OK的状态判断函数之后,才能使用收发哦。
而且还有一点就是DMA不同那些外设一样,它本身是触发不了什么接收和发送的,SPI绑定DMA。比如SPI接收,是因为先触发了SPI的中断,因为CPU把DMA连接到一个存储器地址和SPI上了,所以才会触发SPI_DMA的接收完毕中断回调哦

DMA通道和DMA数据流
STM32F1系列(如STM32F103)

在STM32F1系列中,DMA有通道(Channel)的概念。每个DMA控制器有多个通道,每个通道可以配置为处理一个特定的外设数据流。每个通道有它自己的寄存器集合,用于配置源地址、目的地址、数据长度等。

STM32F4系列(如STM32F407)

在STM32F4系列中,DMA有数据流(Stream)的概念。每个DMA控制器有多个数据流,每个数据流可以配置为处理一个特定的外设数据流。每个数据流有它自己的寄存器集合,用于配置源地址、目的地址、数据长度等。此外,STM32F4系列的DMA控制器还有FIFO(先入先出)机制,用于优化数据传输。

使用cube的时候,就会发现要么没有通道要么没有数据流,两者只有一个。因为他们使用也非常相似。

用F04举例子:

数据流

每个DMA控制器有8个数据流,每个数据流都能够提供目标之间的单向传输链路

每个DMA控制器可以同时配置多个数据流,但在某一时刻只允许有一个数据流使用DMA控制器。当多个数据流同时请求时,由仲裁器决定哪一个数据流优先使用DMA控制器。

通道

  每个数据流有8个通道,每个通道映射到不同外设,这有利于针对不同的产品配置不同的DMA外设请求。每个数据流只能配置为映射到一个通道,无法配置为映射到多个通道。即,与数据流不同,每个DMA控制器可以同时配置多个数据流(因为有仲裁器),但每个数据流不能同时配置多个通道(因为只有选择器)。


仲裁器
  仲裁器用于在多个数据流同时请求时,解决请求冲突的问题。在硬件上,数据流的编号越低,请求优先级越高,仲裁器优先响应编号低的数据流。

  为实现更灵活的配置,数据流还可以设置软件优先级,软件优先级分为以下4个级别:

  — 非常高优先级
  — 高优先级
  — 中优先级
  — 低优先级

硬件:如果两个请求具有相同的软件优先级,则编号低的数据流优先于编号高的数据流
原文链接:https://blog.csdn.net/weixin_44567318/article/details/114003967

总结

其实用cube配置之后,用起来差不多的,我估计这个时候也没有使用标准库了吧,后面那些H系列的,比如H745还是异构双核的。反正大家也都是对着demo进行模仿的,只要代码能用是不是标准库都是一样用的。