0%

虚拟内存

我记得我小时,我爸买了一台1米手机,没错就是1米手机,笑死我了,他还以为是小米,不得不说,真的垃圾,还贼贵,真的小米确实是把手机打下来了。后面我换了一部联想手机,但是,用着用着,我就觉得内存好小啊,完全不够,当时是很多手机都可以root,所以,我发现我也root成功了,我还非常高兴,后面,我看到有那些刷机和扩容软件,我就试了一下,后面手机白屏了,开不了机,我觉得是这个软件把我的系统刷没了,当时也是啥也不懂,更别说用电脑去搞啥固件了。

MCU扩容

后面学习了嵌入式,我才发现,嵌入式是可以扩容的,我一开始还非常担心,这个扩容会不会不安全啊,会不会出现我小时候的问题啊,现在发现,完全不会的。扩容其实是很安全的,MCU本身也是使用了虚拟的内存来实现编址的,也就是32位4G的空间,但是,MCU根本没用到4G啊,用256kb都算大的了,虽然确实有上M大小的MCU,但是离4G空间还差远了。

SDRAM的储存单元叫BANK(一般有4个),每个BANK中以阵列形式排列,先指定BANK号和行地址,然后指定列地址,则能确定唯一地址。

就是选择和使用BANK,然后访问和使用这些地址就ok了,因为MCU早就为了这些扩容的地址进行编址了。

虚拟内存的意义

说白了,就是为了以后,虽然说一个产品出场是一定满足自身寻求的,比如笔记本电脑,他出场是一定能满足系统调度和使用,还有很多操作的,但是它允许用户扩容,也允许用户更换设备。

同时,内存是程序的以进行的基础,进程的进行内存资源是非常必要的,如何在有限的内存中运行足够大的程序,变成了一个非常有挑战的事情,而虚拟内存相对于物理内存可以提供更大的空间。

简单来说,虚拟内存可以让系统看上去去拥有比物理内存大得多的内存空间,为多道程序的执行提供了资源。

还有就是统一编址了,所有外接的内存也得满足给定的要求,这样系统和内核就能正常访问他们啦,这种随插随用的方法,非常适合嵌入式。

shell

这个在使用命令行系统的时候再熟悉不过的东西了,就是敲指令,让系统去工作。在linux中,gcc编译完毕之后会有一个a.out文件,可以./a.out直接运行,也可以在环境变量中添加这个可执行文件,就可以直接使用了。shell也是最接近内核的那一层,它可以把数据和指令传递给内核去操作和处理。

父shell

父 Shell 是用于登录某个远程主机或虚拟控制器终端或在 GUI 中运行终端仿真器时所启动的默认的交互式 Shell 。可以认为就是可执行文件的那一层的进程

子shell

子 Shell 是父 Shell 进程调用了 fork() 函数,在内存中复制出一个与父 Shell 进程几乎完全一样的子进程。所以,它有着父亲的资源。

  • 子 Shell 继承了父 Shell 的所有环境变量(包括全局和局部变量)
  • 可以通过环境变量 BASH_SUBSHELL(其值表明子 Shell 的嵌套深度)判断是第几层子 Shell(0 说明当前 Shell 不是子 Shell)
孩子shell

孩子 Shell 是父 Shell 进程调用了 fork() 函数后又调用了 execve() 函数来执行新的 shell 命令(比如 bash),从而覆盖 fork() 复制出来的 Shell 子进程。

  • 孩子 Shell 只继承到父 Shell 的全局环境变量(而不能访问到父 Shell 的局部环境变量)
  • 可以通过环境变量 SHLVL(其值表明孩子 Shell 的嵌套深度)判断是第几层孩子 Shell(启动的第一个 Shell 其 SHLVL 为 1)
shell全局变量、局部变量、环境变量

环境变量就是都可以使用的变量,全局变量就是shell代码中本文件或者链接的文件可以使用的变量,局部就是shell函数中的变量。

注意力,父shell和子shell之间的变量是独立的,只能在自己的作用范围内生效,子shell是可以追踪到父shell的id号的。

shell功能的必要性?

shell就是为了实现操作系统可以让用户输入来实现操作的一种手段,我们在使用rt-thread中,会发现,有一个cmd宏,可以添加函数进去,这样只要在虚拟串口输入指令,就可以执行对应的函数,这个是一种选择。在嵌入式中,用户的输入端可能就只有几个按钮,你说这怎么可能输入指令呢?如果是一种调试接口或者可执行的交互系统等才有有用的意义,不然就是浪费。在linux,mac,windows这些系统中才有非常有意义的作用。

shell编程

1.解释器

首先就是选择解释器,比如bash。也可以选择python作为解释器,不过这写法就要编程python的写法了哦。

2.变量和数据

然后就是全局变量,局部变量,还有外部的环境变量,这些变量有数字,有文件路径,有字符串等。

3.也是跟c语言一样,顺序判断循环,三大结构。

if elif else switch for while

4.不定长输入

还有就是shell是指令输入和执行的,所以少不了不定长,所以,就要$#、 $1、 $$ 、$* 、$@这些来做类似于argc和argv那些东西,得到数据就处理呗。

5.shell函数定义

这个太经典了。

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

function func1(){
count=0
for cont in {1..3}; do
count=`expr $count + 1`
done
# 函数中使用return返回时,返回值的数据类型必须是数字
return $count
}
res1=$(func1)

7.shell格式化

因为一个数据可能是特殊指令,比如date这个是日期,但是shell可能会理解成date这个字符串,所以,我们就要告诉它是date就可以了。

8.shell引用

因为shell的变量只是容器,这个和python是一模一样的,所以,你可以把csm这个字符串赋值给一个变量,但是也可以$csm赋值给一个变量。

1
2
3
csm="1234"
echo csm #这个会打印csm
echo $csm #这个是打印“1234”

还有$(( ))${}$()等用法

$()这个会执行一边中间的shell脚本、$(( 运算式 ))、$[]运算式

9.正则表达式

shell脚本——正则表达式(包含grep详细介绍及应用)_sh脚本 if 中加 grep-CSDN博客

总结

shell就是一个对可执行文件的操作方法,可以使用编程的方法,让计算机来代替人做繁琐无意义的多次执行。可以说只有在可以操作的人机交互的界面可以使用,怎么说也得有键盘鼠标等或者每个按钮有特殊的控制上下左右。所以,低端的嵌入式设备用不到shell。shell就是执行已经写好的可执行程序罢了,然后执行完毕回到系统,继续下一个shell操作。

起因

我一直好奇,cpu是怎么工作,虽然我脑袋里面有一个雏形了,但是,这个终究是知道他是加工的,而不知道加工具体流程,虽然也确实不需要知道。然后,我无意间看到DSP芯片,他是哈佛结构的,我愣了一下。现在不应该都是哈佛结构的吗?然后我去看了一下,还真不是,现在pc端,那些大型竟然都是冯诺依曼结构,也就是普林斯顿结构,我蒙了啊,我一直以为这个结构应该淘汰了,因为不能同时取值和取指。看哈佛多好啊,指令数据分开,不同区域,可以同时获取。为什么会这样呢?我们就要先看看两个结构的区别了。

哈佛结构

这个结构就是数据和指令分来存放,这样就可以让cpu同时进行取值和取指操作,这样的效率非常高,非常适合用在MCU和DSP中,因为这中结构设计很复杂,但是效率高,而MCU和DSP本来就是简单的集成电路,所以,可以使用哈佛结构,这样可以在底层进行高效的处理。之前,我参加了rt-thread的线下会,他们的方案就是上层linux,下层rtos的mcu,这其实是一种非常有意义的设计。因为,上次的应用对于实时性和高效的要求其实是不高的。

冯诺依曼结构

这个结构是数据和指令放一起,通过不同的时期来区分数据和指令,cpu识别到是指令之后,就会去取数据,和取下一个指令,这个是一个顺序的结构,至于实现,这就是编译器和中间件的事情的,这些对于写代码是没有影响的。也不担心,指针取地址和跳转那些操作,这些都是有底层的配置和映射的。这个结构就非常简单了,光是思考这个地址就简单太多了,因为数据和指令是想要一对一的的,使用哈佛的话,这个映射就有点麻烦了,而普林斯顿可以直接写在一起,这就非常简单了。所以,冯诺依玛结构非但没有没落,反而是越高端越高级的计算机就越明显。因为得考虑成本和设计难度等诸多情况。

混合策略

现在,已经不是纯种得哈佛和普林斯顿结构了。很明显哈佛是可以选择独立编址也可以选择统一编制得,虽然普林斯顿也行,但是数据和指令分开来得普林斯顿明显更适合独立编址。举例子,比如stm32就是普林斯顿结构,但是cpu使用得哈佛的结构。这个现在太明显了,因为普林斯顿结构可以节约空间,方便设计,而哈佛结构可以增加效率同时进行。

总结

哈佛和普林斯顿现在基本上没有纯血的版本了,都是混合为主的策略。还有不用担心啥编址和地址的问题,这些都是厂商处理的,独立编址、统一编制啥的,使用独立io就可以随便调用外部的IO,也可以把我们作为开发者,只需要写好代码。

开发模型

这个是什么鬼东西?很多时候,我们写代码都是凭感觉去写的,所以啊,有时候写的得心应手,有时候写的莫名其妙,因为,不知道流程和先后顺序,也不知道流程的重要性,还有软件设计和预备等操作,这些一般都是总工和负责人、经理去考虑的。但是我们不是那种只会敲代码的傻瓜啊,我们得思考,得设计,得理解,不是他给我们做什么,就去做什么。这样是牛马和奴隶。

起因

因为,我看到公司的bootloader竟然支持拖拽下载,所以就去了解一下usb设备,和一些协议。

开发

这里打开cube,选择usb host模式,然后就可以在下面找到usb的功能选择,有MSC 也有HID等,这个就是ST官方帮我们封装好了USB库和驱动,方便我们可以快速实现应用层开发,只需要配置好,就可以模拟成对应的USB设备了,说白了就不用闭门造车了,确实快速,大家也千万别自己尝试去敲USB底层驱动代码,这个费力不讨好,而且还不一定能用,费时费力。

使用
HID协议
MSC特征和属性
AUDIO
常见BUG
总结