C For Linux之内存访问-内存简介

2023-05-16

1、     内存

1.1、  计算机为什么需要内存

存储器是计算机系统中非常重要的组成部分。计算机中的存储器分为两类:内存储器的外存储器(也叫辅助存储器)。


所谓外存储器在PC机中一般指硬盘、U盘、光盘等,而在嵌入式系统中一般使用nandflash、SDCard等基于flash技术的存储器。他的优点是容量大、单位存储成本低、掉电不丢失。缺点是读写速度慢(这个慢是相对于CPU的速度来说的)、不能直接寻址(如CPU需要通过nand控制器来读写外部nandflash)。因为容量大而且掉电不丢失,因此外存储器主要用来存储静态文本数据,如安装好的操作系统映象、文本文档、串行化保存的数据等。一般提到storage、disk等词汇都指的是外存储器。

而内存储器(一般简称内存)一般都是RAM(random access memory),如PC机平台广泛使用的DDR SDRAM、嵌入式系统常使用的SDRAM、单片机中使用的SRAM等都可以成为内存。RAM器件的缺点是掉电会丢失内容,因此不能用于长期存储信息。但它的优点是速度快(尽管比CPU还是慢很多,但是相比外存储器已经快太多倍了),并且CPU可以通过地址线直接寻址RAM器件的存储单元,因此内存是CPU执行任务(数据运算、程序执行等)的“演练场”。

譬如在嵌入式linux系统中,操作系统映象文件zImage(kernel image,即可被引导的二进制内核代码)被烧录到nandflash(外存储器)中保存,系统启动时bootloader将zImage复制到内存中,之后操作系统一直在内存中运行。

当我们运行应用程序的时候也是如此。程序的静态可执行文件放在文件系统中,而文件系统在外部存储器中。当我们使用./a.out运行可执行文件时,可执行程序文件先被读取到内存中特定区域然后在内存中(以进程的形式)运行。

上大学时(偶尔)都会去阅览室吧,进了阅览室先从书架上拿下自己感兴趣的图书,然后拿到阅读桌上慢慢看。如果把你看作是CPU,那么书架就是外存储器,而阅读桌就是内存。

仔细品味品味,是不是有点感觉了?是的,外存储器就是我们计算机系统的“仓库”,而内存则是计算机执行任务的“工场”。所以,与静态文本(文件、编译好的可执行程序、内核映像等在未被运行前都是静态文本)相关联的是外存储器(storage),而与运行中的程序、正在被操作的文本相关联的则是内存(memory,RAM)。CPU执行任务时以内存为场地,程序中临时变量的分配与销毁(与栈有关)、文件和数据的暂存与处理(从外存读入到内存中缓冲区)都是在内存中完成的。

1.2、  内存地址

上文说过,常用的内存有SDRAM、SRAM、DDR等种类。各种内存因为物理原理的不同而表现出不同的特性(容量、速度、操作时序等)。譬如SRAM容量小、速度快、常被用作单片机内部RAM,而SDRAM容量大、操作接口复杂(CPU需要专用的SDRAM控制器),经常用作嵌入式系统中的内存,DDR的操作特性与SDRAM类似,只是速率要比SDRAM高,PC平台与一些CPU主频较高的嵌入式场合都会选择DDR作为内存以为CPU提供较高的内存访问效率。

编程时,更多的是从逻辑层次、以地址的方式来访问内存。因此无论何种内存,对于我们写程序来说都是一致的。在逻辑层次上,我们把内存抽象成这样一种物质:

a)   内存由一个个的存储单元组成,每个单元大小为1个字节(注1:本书中均以Byte,B来表示字节)。这里我们先不提位访问和字访问形式,下文会有专门章节讲述。

b)   内存中每个单元都有一个唯一的地址来标识该单元。地址是CPU识别、定位内存的唯一凭证(C语言中的变量名、汇编中的标号等实质上都是内存地址)。打个比方,整个内存是一栋大楼,里面由一个一个的小房间组成,每个小房间就是内存这栋大楼的一个字节单元。当我们想去大楼的某个特定房间时我必须知道房间号(譬如408),当我想访问内存的某个单元时我则必须知道它对应的内存地址。用地址来标识内存是一种很好的抽象,因为它屏蔽了内存的物理细节,你根本不必考虑内存中各个单元是线性排列的还是环形排列的,也不必管物理内存是一层一层的还是一块一块的,总之你只要提供正确的内存地址就可以了。就好象你只要知道你要去的房间号,根本不用管大楼的内部结构、乘电梯还是走楼梯等细节也能找到你要去的房间。当然了,房间号不能有重复的。必须的,内存地址也不能有重复,上帝决定了一个内存地址只能对应唯一的一个物理内存字节单元。

c)   逻辑上可以认为内存是线性分布的(其实是因为作为内存地址的数字是线性分布的),事实上你所能看到的几乎所有讲述中内存都被描绘成一个长条,这让我想起了国粹麻将,实际上打麻将时你面前的牌摆成一条长城的样子逻辑上就是内存的真实写照,每个麻将牌就是一个内存单元,依次相连。

相信你现在对内存已经有了一些了解。Ok,那我们来考虑在程序中如何使用内存。程序是用编程语言写的,那么什么是语言呢?语言是人与人之间沟通思想、传递信息的媒介,而编程语言是人与机器(CPU)之间沟通信息的媒介。机器有自己的语言系统,即CPU的指令系统,除此之外它什么也听不懂。CPU的指令是什么呢?只是一串由1的0组成的编码而已。是的,既原始又麻烦枯燥、想来让人不寒而栗。听说最早期的程序员就是在纸板上用打孔机打出一串串的1和0来编程的,在我看来这份工作的难度不亚于让你“与牛聊天”、“跟树对话”,可见先辈程序员们之天赋异秉。

后来有了汇编语言情况就好很多了,程序员的要求开始由天才降低为人才。汇编语言借助汇编器来完成工作,这使得程序员可以使用汇编器可以识别的符号来编程,汇编器会在稍后将符号翻译成机器码。这样虽然CPU还是只认识那些1和0组成的长串,但是借助于汇编器程序员终于可以用人类看得懂的语言来编程了。这是一个长足的进步,因为它引入了“符号”这个概念。在汇编语言中,汇编指令、伪指令、标号这些都是符号,这些符号是给汇编器看的,汇编器会识别它们,并决定它们在最终的可执行文件中如何用1和0的长串来表达。

那么程序员如何使用编程语言访问内存呢?答案是CPU的指令集内有专门用来访问内存的指令。譬如ARM汇编中有LDR、STR、LDM、STM等内存读写指令,可以完成内存与寄存器的数据交互。在访问方式上还有所谓直接访问、间接访问等多种寻址模式(在ARM汇编访问内存一章有详细介绍),但是千变万化、原则只有一个,那就是提供正确的内存地址给汇编指令,这样CPU就可以完成相应地址的内存读写。譬如以下两句汇编指令就完成了读取内存地址0x30000000处连续4字节内存单元到寄存器中。

LDR R0, =0x30000000     // 将R0赋值为0x30000000

LDR R0, [R0]             // 读取内存地址0x30000000处的内容放入R0

至于C语言等高级语言,它们的编译器更加智能、功能也更加强大。大多数时候使用内存并不会直接指出具体的内存地址(如上例的0x30000000),而是以变量名、函数名等符号地址的形式来使用,这些符号地址稍后在编译链接的过程中会被转换为具体的内存地址提供给CPU的机器指令来执行内存读写。

可见,CPU访问内存的方式就是通过内存单元的地址。汇编语言还是C语言,标号、数字形式的地址、还是变量名、函数名,这些都只是编译器提供的编程形式的不同,其实质都是为了指定一个具体的内存地址。

1.3、  内存位宽和内存对齐

前文说过,内存单元是以字节为单位的,每个字节单元有自己的地址,CPU通过该地址来访问这个内存字节。因此内存地址0x30000000和0x30000001之间相差1字节,这就是内存的自然位宽。

提到位宽,就不得不提一下CPU的数据位宽。一般来说,一款CPU的位宽是由ALU位宽、通用寄存器位宽、数据总线位宽三个值中最小的一个来决定的。也就是说,位宽描述了CPU一次运算所能处理的数据位数。譬如MCS-51系列单片机为8位CPU,所以其一次处理8bit(即1个字节)数据,而ARM系列为32位CPU(有消息说ARM会在2014年推出首款64位CPU)因此其一次处理32bit数据。

针对不同位宽的CPU平台,取得最佳内存访问效率的方法是让内存位宽和CPU位宽相同。譬如ARM在操作32位内存时一次可以读写4字节(使用LDR,STR),而在16位内存时需要2次才能读写4字节数据(LDRH,STRH),这样访问效率就差了很多。

那么32位宽的内存和16位、8位宽的内存有什么区别呢?请看下图。


图中的长方形表示逻辑上的内存,横线和竖线(包括虚线)将内存从逻辑上分成一个一个的小块。每一块大小为1个字节,方块内的红色数字表示该内存单元的地址。可见,无论是32位内存还是8位内存,内存地址都是以字节为单位的。请原谅我不厌其烦的唠叨——是的,似乎很简单,但是这个真的很关键。

a)   首先这意味着我们以地址访问时所能精确到的最小单元就是字节,换句话说我们没法精确到要去访问某个字节单元内的某个bit(关于位访问下文会有专门讨论)。

b)   其次,对于32位宽的内存我们可以用1个地址来访问连续的4字节内存单元,这就是所谓的字地址(图中内存右侧的黑色粗体数字即是字地址)。譬如对于内存地址0,如果作为字节地址它代表的是字节地址为0的那个内存单元。而如果作为字地址,它代表的是字节地址为0、1、2、3的4个连续内存单元,这4个内存单元合称为一个字(word)。我们在访问内存时只是提供了一个数字作为地址,那么究竟访问的是字节还是字呢?本质上是由我们访问内存时使用的机器指令决定的。譬如在ARM汇编中使用LDR指令访存时地址将被解释为字地址,而使用LDRB指令访存时地址被解释成字节地址。而使用C语言访问内存时,变量的数据类型就成了如何解释变量所代表的内存地址的关键。

至此我们介绍了内存位宽,并且引入了字节地址、半字地址、字地址(注:再次强调,我这里的描述都是基于32位ARM体系的)几个概念。总结一下:所有的地址本质上都是一个数字,这个数字成为首地址。不同在于,对于字节地址,它说代表的内存空间为首地址开始的一个字节。而对于半字地址,它所代表的内存空间为首地址开始的2个字节(半字)。对于字地址,它所代表的内存空间为首地址开始的4个字节(字)。下图描述了首地址为0x33f80000时三种地址所表示的实际内存单元。


什么是内存对齐呢?首先要认识到,位宽是内存器件本身的一个物理属性。对于32位宽的内存器件,其字节地址为0、1、2、3的四个内存单元在逻辑上被整合成一个字从而可以被当作字来单周期(这里的周期指的是内存访问周期)访问。必须指出,这个整合是器件的物理特性提供的而不是无条件的。随便在内存中找4个字节单元是不能当成一个字来字访问的,这四个字节必须满足两个条件:一是四个单元的字节地址相连,二是最小的那个字节地址(组成字后的字地址、起始地址)必须被4整除。


若选出的4个单元字节地址不相连(即不满足条件一),则这4个字节根本不能组成一个字。若满足条件一则可能的排布有4种,如上图所示。图中每种排布的4个字节地址都连续分布,因此都组成了一个字。但是只有第一种同时满足条件二,因此只有第一种可以进行字(单周期)访问。其他三种情况下都要耗费多个周期才能间接完成字访问(一种惯用的做法是以字节为单位访存4次再拼接出一个对齐的字,参见llinux源码lib/string.c文件中memmove函数的实现)。

上图中第一种情况所示即为对齐访问,其他三种称为非对齐访问。可见,内存对齐访问时可以单周期字访问从而取得最佳的仿存效率,而非对齐访问却需要多次仿存及运算才能完成字访问(使用非对齐访问的一个理由是为提高内存利用率)。以上我们描述的是32位系统中的字对齐,半字对齐的概念和字对齐相类似,不同的是半字对齐要求起始地址被2整除。

1.4、  大小端模式

大小端模式是字地址的使用带来的引申问题。譬如我要将十六进制数0x12345678放到内存中一个字单元来存储,可能的存储方式有两种,如下图所示:


首先引入两个概念:MSB(Most Significant Bit)和LSB(LeastSignificant Bit)。MSB用来描述二进制数的最高加权位,类似于十进制数的最高位。LSB则用来描述最低加权位,类似于十进制数的最低位个位。如果将十六进制数0x12345678以字节为单位分割,则包含MSB的字节内容为0x12,而包含LSB的字节内容为0x78。从上图可以看出,大端模式(Big-endian)即MSB存储在内存地址的低字节处的存储方式,而小端模式为LSB存储在内存地址的低字节处的存储方式。

这两种存储方式本身并无优劣之分,在效率上也无差异,实际使用时只要保证CPU的大小端模式和内存中数据的大小端模式一致就可以。有些CPU支持小端模式,如Intel系列微处理器。而另外一些CPU支持大端模式,如Motorola公司的微处理器。还有一些CPU则可配置为支持大端模式或小端模式,典型的如ARM9 S3C2440。

另外值得一提的是,大小端模式的概念不只在内存的字存储中用到,在串行通信中也会用到,甚至Big-endian的Little-endian这两个词最早的软件搭上关系也是源于在串行通信中的大小端选择。问题其实不难理解,一条通信消息可能有多个字节(就好象一个十六进制数有多个自己长一样),而串行通信时一次只能传输一个字节(准确的说串行通信时一次只能传输一个bit,一帧才能完成一个字节的传输),因此当多个字节的一条信息被串行传输时,发送顺序是从MSB到LSB还是从LSB到MSB就造就了Big-endian和Little-endian两种字节序。

 

词源:据Jargon File记载,endian这个词来源于Jonathan

Swift在1726年写的讽刺小说 "Gulliver's Travels"(《格利佛游记》)。该小说

在描述Gulliver畅游小人国时碰到了如下的一个场景。在小人国里的小人因为非常

小(身高6英寸)所以总是碰到一些意想不到的问题。有一次因为对水煮蛋该从大的

一端(Big-End)剥开还是小的一端(Little-End)剥开的争论而引发了一场战争,

并形成了两支截然对立的队伍:支持从Big-End剥开的人Swift就称作Big-Endians

而支持从Little-End剥开的人就称作Little-Endians……(后缀ian表明的就是支持

某种观点的人:-)。Endian这个词由此而来。

  

  1980年,Danny Cohen在其著名的论文"On Holy Wars and aPlea for Peace"

中为了平息一场关于在消息中字节该以什么样的顺序进行传送的争论而引用了该词。

该文中,Cohen非常形象贴切地把支持从一个消息序列的MSB开始传送的那伙人叫做

Big-Endians,支持从LSB开始传送的相对应地叫做Little-Endians。此后Endian这

个词便随着这篇论文而被广为采用。 --(内容来自于网络)--

 

1.5、  内存的位访问

上文一直在强调,内存地址的最小单位是字节,因此我们单次访问内存中所能读写的最小单位也是字节。如果你只想更改某个字节中的一个bit,你不得不先读出整个字节,然后使用与、或等位运算更改特定bit,最后再将更改过的完整字节重新写入字节地址内。大多数系统中都是用类似手段间接实现位访问的,如ARM驱动程序中寄存器操作部分大量充斥着此类代码。

除了硬件寄存器读写时需要位操作以外,bool类型变量的使用也使人们想到位运算。很多时候我们会需要定义bool类型变量(标志位、互斥锁等都是不错的示例),这种变量要么是0要么是1,本质上只需要1个bit内存就可以存储。如果硬件平台(主要是CPU的的仿存机制)支持内存位访问,那么使用1bit内存来存储bool类型变量可以大量节省内存。不过事实上大多数平台是不支持位访问的,所以对于bool类型变量,实际可选的存储方式有两种:一是使用一个字的32位来存储一个bool值,这样实际只是使用了该字内存的其中1bit,另外31bit实际上都浪费掉了;二是仍然使用1bit内存来存储,然后使用上段中提到的读-改-写三步策略实现间接的位操作。两种处理方式的各自特点如下表:

操作方式

使用32bit表示bool

使用读--写实现间接位操作

优势

读写效率高

内存利用率高

劣势

内存浪费

读写效率低

总结

省时间,费空间

省空间,费时间

得益于半导体工业的发展,现代计算机的可用内存越来越大,因此在大多数情况下空间效率的重要性不如时间效率,这导致大多数平台都选择使用一个字来表示bool类型以追求极好的运行时效率。但是真正的位存储处理也是有的,C语言中的位段(bit-field)就是个实例。

难道就没有CPU提供真正的位访问能力吗?有,单片机就是个很好的示例。单片机因为本身内存容量很有限(像传统的8051只提供128字节内部RAM,现代32位单片机如STM32内存容量也是100KB量级),因此很在意内存使用率,提供位寻址能力以最大限度的利用内存就变得有意义起来了。可是我们之前说过,在计算机系统中地址默认是以字节为单位的,单片机系统中也不例外(想想为什么在需要位寻址的单片机系统中地址不以bit为单位呢?仅仅是为了兼容传统理念吗?)。那么单片机是如何实现位访问机制的呢?一句话,八仙过海,各有各的招吧。

8051提供128字节内存,地址为0x00-0x7f(8051汇编中习惯使用00H-7FH这样的表达方式),这些地址都是字节地址。使用MOV等普通指令读写内存也是一次操作1个字节。但是8051在字节地址20H-2FH这16个字节中提供位寻址能力,将这16个字节的总共16×8=128个bit进行按bit编址,于是乎字节地址20H-2FH的这16个字节内每个bit又有了一个额外的位地址,只要使用专用的位访问指令(如SETB、CLR)再提供位地址就可以对相应bit进行位操作。

字节地址

位地址

 

7FH

无位寻址能力

 

7EH

 

.
.
.

 
 
 

2FH

7FH

7EH

7DH

7CH

7BH

7AH

79H

78H

 

2EH

77H

76H

75H

74H

73H

72H

71H

70H

 

.
.
.

.
.
.

.
.
.

.
.
.

.
.
.

.
.
.

.
.
.

.
.
.

.
.
.

 
 
 

21H

2FH

2EH

2DH

2CH

2BH

2AH

29H

28H

 

20H

27H

26H

25H

24H

23H

22H

21H

20H

 

譬如SETB 2CH,指令执行完毕后位地址2CH、也即字节地址21H.4(.4表示该字节中的bit4)对应的bit被置位。又如CLR70H,指令执行完毕后位地址70H、也即字节地址2EH.0对应的bit被清零。

ARM Cortex-M3中提供了另一种位操作机制,称为位带操作。实现模型简单描述就是:首先从地址空间内选择一部分将要支持位操作的地址区域(譬如0x20000000-0x200fffff共1M字节),然后再挑选另外一些地址区域(譬如0x80000000开始的一段区域)作为位操作区域的地址映射区。在两个地址区域之间建立映射关系,即0x20000000开始处的一个bit对应0x80000000开始处的一个字,如下图


图中相同颜色的区域之间建立了位带映射关系,因此我们可以通过字访问0x80000000地址以达到实际位访问字节地址0x20000000处bit0的效果。具体实现细节可以参考《Cortex-M3权威手册》等书籍。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C For Linux之内存访问-内存简介 的相关文章

  • webpack开发调试模式devtool

    devtool 有7种模式 eval 文档上解释的很明白 xff0c 每个模块都封装到 eval 包裹起来 xff0c 并在后面添加 sourceURL source map 这是最原始的 source map 实现方式 xff0c 其实现
  • HDFS 集成 Kerberos

    本文主要记录 CDH Hadoop 集群上配置 HDFS 集成 Kerberos 的过程 xff0c 包括 Kerberos 的安装和 Hadoop 相关配置修改说明 注意 xff1a 下面第一 二部分内容 xff0c 摘抄自 Hadoop
  • html实现自动清理js、css文件的缓存

    方法如下 xff1a 1 手动清除浏览器缓存 xff1b 2 添加版本号 方法一 xff1a 可以通过js自动给html添加版本号 lt script type 61 34 text javascript 34 gt document wr
  • 虚拟机在nat模式下无法连接网络

    问题导入 在vmware下使用虚拟机由于某些原因设置了静态IP但是在后续的使用发现无法创建新的ssh连接 xff08 之前建立过连接并保存了密钥的仍可连接 xff09 xff0c 同时发现了主机网络可以正常ping通虚拟机的网络 xff0c
  • 74HC573芯片简介

    芯片缺口方向 为正 xff0c 然后左上往下排列 xff0c 最后一个是GND xff0c 然后 向右 xff0c 再向右上 xff0c 右上角为Vcc GND 和Vcc成对角线 xff0c 是为了防止发生短路 LE xff1a latch
  • c语言中返回值为char*的情况分析

    容易出错的地方在于 xff1a 指针作为返回值 xff0c 但是指针指向的内存单元在函数返回后 xff0c 内存单元释放了 xff0c 这样就导致了指针成了野指针了 xff01 xff01 xff01 这样会报错 xff0c 因为str数组
  • 网线水晶头接法分两种教程

    转载 xff1a https blog csdn net VickHUC article details 90081813 我们家里如果要用网线的话 xff0c 其实是可以自己接水晶头的 xff0c 当然你得有一个叫压线钳的工具 xff0c
  • STM32的定时器和DS18B20调试-第3季第8部分视频课程-朱有鹏-专题视频课程

    STM32的定时器和DS18B20调试 第3季第8部分视频课程 975人已学习 课程介绍 本课程是 朱有鹏老师单片机完全学习系列课程 第3季第8个课程 xff0c 本课程详细讲解STM32的定时器 xff0c 尤其是SYSTICK定时器和通
  • c语言/c++中指针的动态初始化及释放

    提醒 xff1a 使用指针最容易犯得错误是 xff0c 没有初始化就直接操作 xff01 xff01 xff01 1 指针的初始化 释放 1 xff09 指针指向一个内存单元 i c语言 xff1a char ch 61 char mall
  • c语言函数参数为指针的情况分析

    指针取 解引用 表示的是指针所指向内存单元中内容 xff1b 或者理解为该内存空间 指针传递其实也是一种值传递 xff0c 只不过传递的是地址值 xff0c 如果通过该地址取 解引用 xff0c 是可以改变形参指针的原值的 xff0c 但如
  • MATLAB快速傅里叶变换(fft)函数详解

    转载 xff1a https blog csdn net me4weizhen article details 53688848 定义 xff1a The 39 i 39 in the 39 Nth root of unity 39 是虚数
  • C++中substr()函数用法详解

    定义 substr 是C 43 43 语言函数 xff0c 主要功能是复制子字符串 xff0c 要求从指定位置开始 xff0c 并具有指定的长度 如果没有指定长度 Count或 Count 43 Off超出了源字符串的长度 xff0c 则子
  • 101、104规约解析

    转载 xff1a 电网101 104规约解析 xff08 Java xff09 张二狗和苗翠花的博客 CSDN博客 iec101 java 1 前言 最近在研究广东电网的101与104规约 xff0c 也就是DL T634 5101 200
  • 第一范式(1NF)、第二范式(2NF)和第三范式(3NF)

    第一范式 xff08 1NF xff09 xff1a 列1唯一确定列2 列3 列4 xff0c 即列2 列3 列4 不能再分裂出其它列 假设有关系模式列1 订单名 列2 商品 一个订单下可以有多个商品 xff0c 即列2 商品可以分裂成商品
  • 关于 傅里叶变换 的一些理解(通俗版)

    什么是傅里叶变换 xff1f 对随时间变化的曲线 xff0c 不再从时间轴上去看他的变化 xff0c 而是消去时间因子 xff0c 从出现的频率上来分析他的变化情况 例如 xff1a 股市变化曲线是随时间变化的曲线 xff0c 而通过傅里叶
  • excel取消多行隐藏

    同时取消多行隐藏 xff0c 需要选中隐藏行的上一行和下一行 xff0c 然后右键点击取消隐藏行
  • 双面打印说明

    长边翻页表示以A4纸较长的边翻页 xff0c 类似A4纸张大小的书本的翻页 xff0c 短边翻页则是以较短的边翻页 xff1b 长边翻页是从右往左翻页 xff0c 短边翻页是从下往上翻页 xff0c 翻页后文字观看方向不同 xff1b 长边
  • Segment routing分段路由

    为了解决传统IP转发和MPLS转发的问题 xff0c 业界提出了SR xff08 segment routing xff0c 分段路由 xff09 SR的转发机制有很大改进 xff0c 主要体现在以下几个方面 1 基于现有协议进行扩展 xf
  • mount: RPC: Unable to receive; errno = No route to host

    环境 xff1a gec2440开发板 VMware8 0 43 Ubuntu10 04 uboot xff0c kernel xff0c rootfs都是之前做好的 xff0c 调试驱动都反复用过很多次 今天只是搬了台电脑 xff0c 换
  • 实现Charles+Postern抓包

    实现Charles 43 Postern抓包 在实际抓手机App包场景中 有很多种方案 经典的就是Fiddler 但是Fiddler会有一个问题 如果App设置了不走代理这个选项 那Fiddler就不行了 xff0c 比如说大众点评 xff

随机推荐

  • STM32学习—systick系统定时器

    SysTick定时器配置步骤 SysTick定时器的操作可以分为 4 步 xff1a xff08 1 xff09 设置SysTick定时器的时钟源 xff08 2 xff09 设置SysTick定时器的重装初始值 xff08 如果要使用中断
  • Mac 关闭设置系统升级红点

    关闭系统更新提醒红点 xff1a 在终端输入 xff1a defaults write com apple systempreferences AttentionPrefBundleIDs 0 killall dock
  • 图像特征提取算法之Haar特征原理(一)

    文章目录 笔记截图问题积分图例子结论 笔记截图 用白色的特征值之和 黑色的特征值之和 61 这一个区域的特征值 你也可以理解为用卷积进行提取 xff0c 白色的区域为1 黑色的为 1 xff08 邪恶的黑色 xff09 然后进行相加既可以得
  • CAS方式实现单点登录

    单点登录 xff0c 英文是 Single Sign On xff0c 缩写为 SSO 多个站点 192 168 1 20X 共用一台认证授权服务器 192 168 1 110 xff0c 用户数据库和认证授权模块共用 用户经由其中任何一个
  • 双系统重装Ubuntu经验分享

    真的很喜欢ubuntu 但又没有恒心把它学通透 xff0c 毕竟不是相关专业 第一次重装是因为没多少经验 xff0c 安装qqforlinux的时候多了两个东西 xff0c 还自己生成了快捷方式 xff0c 就想点开看看是啥 xff0c 结
  • PCL三维点云拼接融合

    1 PCL三维点云拼接融合技术 2 PCL系列 拼接两个点云
  • ubuntu20版本忘记或重置密码的问题

    前段时间把ubuntu密码忘了 xff0c 进不去并且有些需要密码权限的功能也用不了 xff0c 在网上搜了一大堆 xff0c 都是什么从开始就摁shift或Esc xff0c 好家伙摁烂了也不行啊 解决如下 xff1a 首先 xff0c
  • 程序员申请加班调休被HR拒绝:996是行规,不想加班就滚?

    现如今 xff0c 很多公司为了不给员工加班费 xff0c 一般都会允许他们进行调休 也就是你加班了多少个小时 xff0c 等项目不忙的时候 xff0c 你们可以选择多休息几天 公司的这种做法 xff0c 大多数员工还是能接受的 xff0c
  • 博士生如何进行文献阅读和文献整理?

    一 阅读文献之前 先了解写文章的规则 SCI的架构 TITLE ABSTRACT main message INTRODUCTION why did you do this job METHODS how did you do it RES
  • 结构体之offsetof宏详细解析

    1 define offsetof TYPE MEMBER size t amp TYPE 0 gt MEMBER include linux stddef h 1 1 功能 xff1a 返回结构体TYPE中MEMBER成员相对于结构体首地
  • 解决curl: (7) Failed to connect to raw.githubusercontent.com port 443

    解决办法 xff1a 一 首先查询域名 raw githubusercontent com对应的ip地址 去这网址查询 xff1a https tools ipip net domain php 二 修改hosts文件 linux系统一般都
  • 关于使用Maix Bit所遇到的OSError: Reset Failed问题

    一 问题 今天在使用Maix Bit学习的时候遇到了这样一个问题 xff0c 我使用Maixpy连接上了Maix Bit xff0c 然后进行下载程序的时候 xff0c 下载失败 xff0c 弹出来一个OSError Reset Faile
  • 致小白的K210模型训练与运用

    致小白的K210模型训练与运用 文章目录 致小白的K210模型训练与运用 前言一 模型训练方法二 详细介绍1 使用MixHub平台进行训练2 使用Mx yolov3自己搭建平台进行训练3 V3模型4 V4模型 前言 由于我也是刚接触K210
  • 使用APP inventor来制作一个属于自己的蓝牙串口软件

    使用APP inventor来制作一个属于自己的蓝牙串口软件 本文主要讲述蓝牙的发送和接收功能的制作 一 准备 1 APPinventor的网址 xff1a http app gzjkw net 二 蓝牙APP界面的设置 首先我们新建一个项
  • 一起卷吧,arduino/mixly语音识别模块,10元,可以自定义,提供自制的mixly库

    一 效果演示 制作的语音风扇演示一起卷吧 xff01 语音识别 xff0c 10元 xff0c 串口通信 xff0c arduino可用 xff0c 提供自制的mixly库 操作简单 xff0c 可以语音播报 哔哩哔哩 bilibili 制
  • arduino/mixly红外发射接收模块

    一 资料 http 资料链接 xff1a https pan baidu com s 1idRcrVCxQ5zWLh59EFpi9g 提取码 xff1a n8ud 默认波特率9600 串口通信 xff0c 可以发送也可以接收 发送格式 二
  • openmv学习十三:特征点匹配

    适用于匹配多角度的物体 xff0c 需要现场提取之后才能使用 http docs openmv io library omv image html http docs openmv io library omv image html cla
  • arduino/Mixly使用TCS230颜色识别传感器

    一 器材 TCS230 arduino uno 二 接线 TCS230arduino unoGNDGNDVCC5VS0D2S1D3S2D4S3D5OE LEDD6OUTD7 三 程序 mixly程序 arduino程序 define tcs
  • arduino/Mixly心知天气

    一 准备 首先百度一下心知天气 xff0c 获取一下密钥 xff0c 具体的可以看这一篇Blynk中WebHook组件的使用方法 moshanghuaw的博客 CSDN博客 然后再准备一个esp8266或者esp32都可以 二 程序 mix
  • C For Linux之内存访问-内存简介

    1 内存 1 1 计算机为什么需要内存 存储器是计算机系统中非常重要的组成部分 计算机中的存储器分为两类 xff1a 内存储器的外存储器 xff08 也叫辅助存储器 xff09 所谓外存储器在PC机中一般指硬盘 U盘 光盘等 xff0c 而