ARM体系与架构

硬件基础

NOR Flash 和 NAND Flash异同

NOR,Not OR,逻辑是或非门;NAND,Not AND,逻辑是与非门。

两者都是FALSH芯片,断电不丢失。FLASH只能写0不能写1,所以写前都要先擦除。

NOR FLASH 按照BANK扇区进行内存组织。

NOR FLASH的最小擦除单位是扇区最小读取、写入单位是字节。(可以随机访问)

NAND FALSH 按照进行内存组织。

NAND FLASH的最小擦除单位是块最小写入、读取单位是页

NOR FLASH读的快,NAND FLASH写的快。'

NAND FLASH寿命和可靠性更低,价格便宜,适合存储大容量数据。

NOR FALSH读写最小单位是字节,代码可以直接在 NOR FLASH 上运行,无需先加载到 SRAM中。

固态硬盘SSD使用的就是NOR FLASH或者NAND FLASH。

机械硬盘HDD不是基于闪存技术的,按块、扇区组织,。对于机械硬盘而言最小的擦除单位是扇区,最小的读写单位也是扇区。

对于操作系统而言,不管是SSD还是HDD,都是以[块]为单位进行读写和擦除的

CPU,MPU,MCU,SOC,SOPC联系与差别

CPU(中央处理器)

定义:冯诺依曼结构中CPU包括运算器和控制器。

功能:执行程序代码,处理数据。
MPU(内存保护单元)

定义:MPU可以限制对内存区域的访问,比如限制只读、只写、禁止访问等等。

功能:可以设置内存区域的访问权限,划分内存区域用于不同的任务。
MCU(微控制器单元)

定义:MCU是集成了运算器、控制器、输入输出单元、存储器的高集成芯片。

功能:除了基本的CPU功能外,还可能包括操作系统的支持、高级的数据处理能力等。
SoC(片上系统)

定义:芯片集成技术。用来将传统计算机组件集成到单个芯片上。

功能:CPU、GPU、内存、存储控制器、网络接口等都属于Soc。
SOPC(可编程片上系统)

定义:SoPC是一种基于FPGA(现场可编程门阵列)的SoC,允许用户配置和编程硬件。

功能:支持编程定制。

什么是交叉编译

支持交叉编译的编译器,作用就是,一个架构环境编译,另一个架构环境运行。这个编译过程就叫交叉编译。像windos平台用keil编译,然后stlink下载**.axf文件**,或者Jlink烧录hex文件,这种也属于交叉编译。x86架构上面生成arm架构的可运行程序。

基于ROM的运行方式和基于RAM的运行方式区别

RAM 是断电丢失,ROM 是断电不丢失。

RAM 运行需要先把硬盘SSD或者闪存FLASH的代码加载到RAM中。FLASH、EEPROM就属于ROM。

ROM运行代码比RAM慢,因为所有的代码和数据都需要缓存到RAM中然后执行。因此ROM运行比RAM运行多了个把执行代码搬运到RAM的过程。

ARM处理器

哈佛结构、冯诺伊曼结构

冯诺伊曼结构:

输入设备、输出设备、控制器、运算器、存储器。控制器和运算器属于CPU。

冯诺伊曼结构指令和数据放在一个存储器,一条总线分时传输指令或数据。

哈佛结构:

指令有指令总线和指令存储器,数据有数据总线和数据存储器

哈佛改进结构:

指令存储器、数据存储器、指令数据通用存储器

允许程序存储器和数据存储器之间直接传输数据,不经过CPU。

现在计算机大都冯诺依曼结构。 哈佛结构主要用于嵌入式计算机,运算速度和吞吐量较大

ARM流水线技术

流水线技术通过多个功能部件并行工作缩短程序执行时间,提高处理器内核效率和吞吐率。

ARM7处理器 是 ARM v3架构使用典型三级流水线的冯诺依曼结构内核,

ARM9处理器 是 ARM v4\v5架构使用五级流水线的哈佛结构内核。

CortexM3 使用 ARM v7架构,五级流水线,改进哈佛结构内核。

CortexM4 使用 ARM v7架构,改进哈佛结构内核。CortexM4相较于CortexM3多了DSP处理功能、SIMD单指令多数据功能等。

Cortex-M4 在硬件上增加了 SIMD 指令集,允许一次操作多个数据,从而提高数据处理的效率。

流水线是 RISC精简指令集处理器执行指令时采用的机制。

三级流水线:

  1. 取指令。从寄存器装载一条指令。

  2. 译码。识别装载的指令。并从寄存器组中读取操作数。

  3. 执行。处理指令并将结果写回寄存器。

三级流水线的内核一般是冯诺伊曼架构。一条总线分时处理数据和指令。

五级流水线:

  1. 取指令。从寄存器装载一条指令。

  2. 译码。识别装载的指令。并从寄存器组中读取操作数。

  3. 执行

  4. 缓冲。如果需要则访问数据存储器,否则 ALU 只是简单地缓冲 1 个时钟周期。

  5. 回写。将指令的结果回写到寄存器堆,包括任何从寄存器读出的数据。

五级流水线的内核一般是改进哈佛结构,指令和数据分开存储和处理。

在执行的过程中,通过R15寄存器直接访问PC的时候,必须考虑此事流水线执行过程的真实情况。程序计数器R15(PC)总是指向取指的指令,而不是指向正在执行的指令或者正在译码的指令。一般情况下,人们总是习惯把正在执行的指令作为参考点,称之为当前第1条指令,因此PC总是指向第3条指令。

对于ARM状态下指令,PC值=当前程序执行位置+8;

对于Thumb指令, PC值=当前程序执行位置+4.

题目:

若每一条指令都可以分解为取指、分析和执行三步。己知取指时间t取指=4△t,分析时间t分析=3△t,执行时间t执行=5△t。。如果按照流水方式执行,执行完100条指令需要__△t。

解答:

第一条指令取指时间4t+

max{取指令,分析时间}+

97个max{取指时间,分析时间,执行时间}+

max{分析时间,执行时间}+

最后一个执行时间5t,这个加起来就是507t。

分析:

当多条指令同时在流水线中处理时,流水线的效率取决于最慢的阶段,即影响整体速度的是最慢的阶段。

RISC 和 CISC区别

常见的CPU有两种架构,X86、ARM。前者主要用在电脑里,后者主要用在手机、平板上。

常见的指令集有两种,一种是复杂指令集(CISC),X86就属于复杂指令集;一种是精简指令集(RISC),家族成员有ARM、RISC-V、MIPS等。

1、精简指令集每条长度固定32位;由于指令位数较短,内部还有快速处理指令的电路,使得指令的译码与数据处理较快。不过必须经过编译处理才能发挥效率。

2、精简指令集不能直接操作内存数据,要用load/store命令;每个指令周期都能执行一条指令。

Thumb指令属于精简指令集,但是更精简,一条指令16位。

ARM 指令集分为几类

指令集分为复杂指令集RISC和精简指令集CISC。

ARM架构使用精简指令集,同时包括ARM指令集和Thumb指令集。ARM指令长度为32位,Thumb指令长度为16位。使得ARM既可以执行32位指令又可以执行16位指令。

ARM 处理器有几种工作状态

ARM 微处理器的工作状态有 ARM 和 Thumb 两种,两种状态可切换。

ARM 状态:此时处理器执行32位的ARM指令。

Thumb 状态:此时处理器执行16位的Thumb指令。

NVIC和位带操作

Cortex-M3内核采用嵌套中断向量控制器 NVIC,使得中断响应时间减少。

Cortex-M3采用位带操作,使得响应速度更快。

在STM32中,支持位带操作的区域称为位带区 (Bit Band regieon),而被位带区映射的地址被称为别名区 (Alias region)。

SRAM片上外设 各有1M 处于低地址的位带区 ,分别映射到高地址的32M别名区

SARM 区的最低 1M 范围位带:

0x2000_0000‐0x200F_FFFF,绑定的别名区0x2200_0000~0x23FF_FFFF。

片上外设 区的最低 1M 范围:

0x4000_0000‐0x400F_FFFF,绑定的别名区0x4200_0000~0x43FF_FFFF。

注意:映射地址的1位,对应物理地址的8位。

位带操作

支持了位带操作以后,可以使用普通的加载/存储指令来对单一的比特进行读写。在CM3中,有两个区实现了位带。其中一个是SRAM的最低1MB范围,另一个是片上外设的最低1MB范围。这两个位带区中的地址除了可以像普通的RAM一样使用外,还有自己的"位带别名区"。

位带别名区把每个比特膨胀成一个32位的字。位带区的值等于对应位带别名区最低位的值。当通过位带别名区访问这些字的时候,就可以达到访问原始比特的目的。

位带操作的优越性

最容易想到的就是,通过GPIO管脚来单独控制每盏LED的点亮与熄灭。也就是位带操作使得STM32具有对寄存器进行位操作的功能。

ARM 的 7种工作模式

用户模式、系统 模式、普通中断 模式、快速中断 模式、管理 模式、终止 模式、未定义模式

用户模式(USR)

用户程序的工作模式,运行在操作系统的用户态。

除非产生软中断或者异常,否则用户模式只能访问自己的数据,没有权限操作其他资源或切换到其他模式。

系统模式(SYS)

系统模式是特权模式。该模式下系统模式和用户模式共用一套寄存器,操作系统可以访问用户模式的寄存器,操作系统的特权任务可以访问受控资源。

普通中断模式(IRQ)

用于处理一般的中断请求,硬件产生中断信号之后自动进入该模式。中断模式也属于特权模式,可以自由访问系统硬件资源。

快速中断模式(FIQ)

用来处理紧急的中断请求,主要用于高速数据传输及通道中。

管理模式(SVC)

CPU上电后默认进入管理模式。管理模式主要用来做系统的初始化。软中断处理也在该模式下。当用户模式通过软中断访问硬件资源时,自动进入管理模式。

终止模式(ABT)

当用户访问非法地址时进入终止模式。linux下编程时经常抛出的segment fault都是在该模式下抛出返回的。

未定义模式(UND)

CPU在指令的译码阶段碰到不能识别的指令时进入未定义模式。抛出不能识别指令的异常。

除了用户模式外,其他六种模式,都属于特权模式。

(系统、普通中断、快速中断、管理、终止、未定义)

ARM 寄存器

ARM处理器有37个寄存器。31个通用寄存器6个状态寄存器ARM寄存器都是32位的。

通用寄存器R15~R0、R16(程序状态寄存器CPSR)都是可访问的。

R16是程序状态寄存器CPSR*。R15是程序计数器PC,R14是链接寄存器LR,R13是堆栈指针SP。*

通用寄存器包括R0~R15,可以分为3类:

(1)未分组寄存器R0~R7

未分组寄存器在所有运行模式下都指向同一个物理寄存器。在中断、异常、模式转换时,处理器的不同运行模式均使用相同的物理寄存器,可能造成寄存器中数据的破坏。

(2)分组寄存器R8~R14

分组寄存器在不同运行模式下指向不同的物理寄存器。

分组寄存器 R8~R12,每个寄存器对应 2个不同的物理寄存器( fiq 和 usr )。当FIQ(快速中断)模式时,访问寄存器R8_fiq~R12_fiq;其他模式时,访问寄存器R8_usr~R12_usr。

分组寄存器 R13、R14 ,每个寄存器对应 6个不同的物理寄存器。其中物理寄存器 usr是用户模式与系统模式共用,另外 5个对应其他5中不同的运行模式。并采用以下记号来区分不同的物理寄存器:R13_ ; R14_ 。

其中 mode 可为:usr,irq,frq,svc,abt,und 。

处理器的每种模式都有自己对应的R13(SP堆栈寄存器),R13在用户应用程序的初始化部分初始化 ,指向该运行模式空间的栈顶。当程序的运行进入异常模式时,可以将需要保护的寄存器放入R13指向的堆栈 ,当程序从异常模式返回时,则从对应的堆栈中恢复。采用这种方式可以保证异常发生后程序的正确执行

R14称为子程序链接寄存器LR,当执行子程序调用指令(BL)时,R14可得到R15(PC程序计数器)的备份。在每种运行模式下,都可用R14保存子程序的返回地址,当用BL或BLX指令调用子程序时,将PC的当前值(即子程序的返回地址)复制给R14,执行完子程序后,又将R14的值复制回PC,即可完成子程序的调用返回。R14也可作为通用寄存器。

(Link Register,LR) (Branch with Link,BL)

(3)程序计数器PC(R15)

寄存器R15用作程序计数器(PC)。

在ARM状态下,位[1:0]为0,位[31:2]用于保存PC。

在Thumb状态下,位[0]为0,位[31:1]用于保存PC。

由于ARM体系结构采用多级流水线技术,对于ARM指令集而言,PC总是指向当前指令的下两条指令的地址,即PC的值为当前指令的地址+8字节程序状态寄存器。(若是thumb指令集则+4字节)

3级流水线包括取值、译码、执行三步。

PC时钟始终指向当前取出的指令的地址。将正在执行得到指令作为参考点,称之为当前第一条指令,ARM状态时每条指令为4字节长度,因此PC总是指向当前执行的指令+8。

因为5级流水线使用哈佛结构,缓冲和回写属于对ALU的数据操作,数据和指令分开读写。因此 5级流水线,PC依然指向当前执行的指令+8。

从异常中断处理程序返回:

当数据访问异常发生时,如果是在ALU中发生,那么PC的值已经更新,PC指向当前指令后的第3条指令。如果不是在ALU中发生,则PC要返回发生错误的指令重新访问数据,因此PC不变。

寄存器R16(状态寄存器CPSR)

寄存器R16用作CPSR(当前程序状态寄存器),CPSR可以在任何模式下被访问。它包括条件标志位、中断禁止位、当前处理器模式标志位,以及其他一些相关的控制和状态位。每种运行模式下都有一个专用的备份程序状态寄存器CPSR。当异常发生时SPSR用于保存CPSR的当前值,从异常退出时则可由SPSR来恢复CPSR。

由于用户模式和系统模式不属于异常模式,因此没有SPSR,访问SPSR时结果未知。

SPSR(Saved Program Status Register,备份的程序状态寄存器)

ARM 系统调用函数时参数是通过哪种方式传递

当参数小于等于 4的时候是通过寄存器 r0~r3 传递,当参数大于4的时候是通过压栈的方式。

ARM 协处理器指令

协处理器用来协助中央处理器完成其无法完成的任务。中央处理器无法完成的工作有很多,比如接入设备的管理,图像和音频处理。

ARM32位架构最多支持16个协处理器(CP0~CP15)。最重要的协处理器是CP15,该协处理器提供了共计15个寄存器来配置和控制cache、MMU、保护系统、时钟模式等。

从ARMv8开始的64位架构弱化了协处理器的概念。

ARM 协处理器指令包括 3类:

  1. 用于 初始化协处理器的指令

  2. 用于 ARM处理器的寄存器协处理器的寄存器间的数据传送。

  3. 用于 协处理器内存之间的数据传送。

中断与异常

中断与异常的区别

中断是由外部事件向CPU发送信号,请求CPU响应。

异常是CPU内部执行时发生错误,需要打断CPU的执行来处理这种不正常的情况。

中断与DMA的区别

DMA是一种无需CPU参与,就可以让外设与系统内存之间进行双向数据传输的硬件机制。

中断是外部事件向CPU发送信号,请求CPU响应,CPU暂停执行当前的程序处理突发事件,处理完再返回源程序被中断的位置继续执行。

DMA不需要CPU参与,中断需要CPU参与。

中断上下半部

当中断处理程序比较长时,linux内核会将中断处理程序分为中断上半部中断下半部两部分。其中上半部用来标记中断,做紧急响应;下半部负责真正的中断操作。

拿网卡来举例,在linux内核中,当网卡一旦接受到数据,网卡会通过中断告诉内核处理数据,内核会在网卡中断处理函数(上半部)执行一些网卡硬件的必要设置,因为这是在中断响应后急切要干的事情。接着,内核调用对应的下半部函数来处理网卡接收到的数据,因为数据处理没必要在中断处理函数里面马上执行,可以将中断让出来做更紧迫的事情。

可以有三种方法来实现下半部:软中断、tasklet和等待队列。

tasklet 是通过软中断实现的,软中断就是软件实现的异步中断。优先级比硬中断低,比普通进程高,和硬中断一样不能休眠。

tasklet机制的引入,是为了支持SMP(对称多处理,不同tasklet可以在不同cpu上同时运行)。

tasklet属于中断上下文,因此不能被阻塞,不能睡眠,不能被打断

workqueue机制特点是把中断下半部交给worker thead,因此下半部处于进程上下文,可以被重新调度,可以阻塞,也可以睡眠

中断响应的执行流程是什么

CPU接受中断->

保存中断上下文->

跳转到中断处理程序->

执行中断上半部->

执行中断下半部->

恢复中断上下文

异常出现后,ARM微处理器会执行哪几步操作

1、如果异常是从ARM状态 进入,则链接寄存器LR中保存下一条指令的地址 (PC+4或PC+8)。如果异常是从Thumb状态 进入,则链接寄存器LR中保存当前PC的偏移量

2、将程序状态寄存器CPSR复制到相应的备份状态寄存器SPSR中。

3、根据异常类型,强制设置CPSR的运行模式位。

4、强制PC从相关的异常向量地址取下一条指令执行,从而跳转到相应的异常处理程序处。

写一个中断服务函数需要注意哪些?

1、中断服务函数要快进快出。在中断服务函数尽快采集信息,处理使用tasklet或者workqueue方式。也就是中断上半部和下半部。

2、中断服务函数不能有阻塞操作。应为中断完全占用CPU,其他进程无法执行。

3、中断服务函数应该使用操作系统定义的宏作为返回值

为什么FIQ比IRQ要快

1、FIQ模式提供了更多的banked寄存器,R8~R14,还有SPSR,而IRQ模式就没有这么多。在IRQ模式下,要自己保存R8~R12这几个寄存器 ,然后退出中断时要恢复这几个寄存器 。而FRQ模式由于这几个寄存器都有banked寄存器,模式切换时CPU自动保存这些值到banked寄存器,退出FIQ模式时自动恢复。ARM编译的时候,如果FIQ中断足够用这几个独立的寄存器来运作,就不会进行通用寄存器的压栈,节省时间。

2、FIQ比IRQ有更高优先级

3、FIQ的入口地址是0x1c,IRQ的入口地址是0x18。也就是IRQ入口地址连续的空间只有4个字节,只能放一条指令。想放更多的就需要进行地址跳转。而FIQ的入口地址后面都是连续的,没有其他的中断向量表了。

中断和轮询哪个效率高?怎样决定是采用中断方式还是采用轮询方式去实现驱动?

中断是CPU在被动状态 下接收设备的信号,而轮询是CPU主动去查询该设备是否有请求。

如果设备频繁请求 CPU,那么轮询 的效率是比中断高。如果设备请求cpu的频率比较低 ,用中断效率要高一些。因为中断可能出现饥饿现象,请求频繁时轮询综合效率高一些。

中断

硬中断/软中断是什么?有什么区别?

硬中断

硬中断是硬件产生的,每个设备都有自己的IRQ(中断请求)硬中断可以直接中断CPU

对于时钟中断,内核调度代码会将当前正在运行的进程挂起,让其他的进程运行。它的存在是为了让调度器可以调度多任务。

软中断

软中断是由当前正在运行的进程产生的。

软中断通常是一些对IO的请求。对于某些设备,I/O请求需要被立即处理,而磁盘I/O请求通常可以排队并且可以稍后处理

软中断仅与中断内核相联系。而内核主要负责对其他进程进行调度。

软中断并不会直接中断CPU。这种中断是一种需要内核为正在运行的进程去做一些事情(如I/O请求)。有一个特殊的软中断是Yield调用,它的作用是释放cpu去执行其他进程。

硬中断和软中断的区别

1、软中断是执行中断指令产生的,而硬中断是由外设引发的。

2、硬中断的中断号是由中断控制器提供的,软中断的中断号由指令直接指出。无需使用中断控制器。

3、硬中断可屏蔽,软中断不可屏蔽。

4、硬中断要快进快出,属于上半部。软中断处理硬中断未完成的工作,属于下半部。

中断为什么区分上半部和下半部

Linux中断分为硬件中断和内部中断(异常),调用过程:外部中断产生->发送中断信号到中断控制器->通知处理器产生中断的中断号。

对于中断上半部和下半部的产生,为了中断处理过程被新的中断打断,将中断一分为二,上半部登记新的中断,快速处理简单的新任务,复杂耗时的处理留给下半部。下半部处理可以被抢占,上半部处理不能被抢占。

中断下半部一般如何实现?

可以有三种方法来实现下半部:软中断、tasklet和等待队列。

tasklet 是通过软中断实现的,软中断就是软件实现的异步中断。优先级比硬中断低,比普通进程高,和硬中断一样不能休眠。

tasklet机制的引入,是为了支持SMP(对称多处理,不同tasklet可以在不同cpu上同时运行)。

tasklet属于中断上下文,因此不能被阻塞,不能睡眠,不能被打断

workqueue机制特点是把中断下半部交给worker thead,因此下半部处于进程上下文,可以被重新调度,可以阻塞,也可以睡眠

通信协议

什么是异步传输和同步传输

异步传输:是一种典型的基于字节的输入输出,数据传输每次一个字节,传输速度低。

同步传输:需要外界的时钟信号进行通信。同步传输一般都是按帧传输。

RS232和RS485通讯接口有什么区别

1、传输方式。RS232采取单端通信传输,RS485采取差分信号传输。单端通信指只有一个信号引脚传输信号,适用短距离传输,抗干扰能力弱。RS485两根信号线,电压差形成显性电平和隐形电平,功耗较大抗干扰能力强适合远距离传输。

2、传输距离。RS232适合本地设备通信,传输距离一般不超过20m。RS485传输距离在几十米到上千米。

3、设备数量。RS232只允许一对一通信 ,而RS485接口在总线上允许连接多达128个收发器

4、连接方式。RS232,规定用电平表示数据 ,线路就是单线路 的,用两根线 才能达到全双工 的目的;RS485,用差分电平表示数据 ,要实现全双工 ,必须用4根线

RS232/RS485规定了电流在什么样的线路上流动,和信号的电平表达。

SPI 协议

SPI的应用

SPI 协议,是摩托罗拉公司提出的通信协议,即串行外围设备接口。是一种高速全双工的通信总线。所谓串行通信就是一根线按位发送数据。SPI总线可以直接与各个厂家生产的多种标准外围器件相连,包括FLASH、SRAM、网络控制器、LCD、A/D转换器和MCU等。

SPI接口

MOSI,主设备输出/从设备输入引脚。

MISO,主设备输入/从设备输出引脚。

**SCLK,时钟信号线。**两设备通信速率受限于低速设备。

**SS。片选信号线。**用来选择通信的从设备。
SPI连线

MOSI、MISO、SCLK这三根线是所有从设备共用。SS是被选中的从设备使用。

SPI时序

1、通信的起始和停止

选中CS信号线由高变低,是SPI通信的起始信号。

2、数据有效性。

SPI使用 MOSI、MISO来传输数据,使用SCK信号线进行数据同步。MOSI、MISO在 SCK的每个时钟周期传输一位数据 ,且数据的输入输出可以同时进行。通常高位先行

MOSI 及 MISO的数据在SCK的上升沿期间变化输出,在SCK的下降沿时被采样。即在SCK的下降沿时刻,MOSI 及 MISO的数据有效。

SPI每次数据传输可以8位或16位为单位,每次传输的单位数不受限制。

3、CPOL(时钟极性)/CPHA(时钟相位)及通讯模式

上图讲述的图中时序只是SPI中的一种通讯模式。SPI一共有四种通讯模式。SPI通讯模式的不同在于:总线空闲时 SCK的时钟状态以及数据采样时刻。

时钟极性 CPOL是指SPI总线空闲状态时,SCK时钟线的状态。

时钟相位 CPHA是指数据的采样时刻,SCK的奇数边沿采样还是偶数边沿采样。

时钟极性 和 时钟相位 组合起来四种状况,就是SPI的四种模式。

SPI总线空闲时SCK线是高/低电平+SCK下降沿奇数/偶数采样

IIC 协议

简介

IIC协议,两根线,时钟线SCL数据线SDA

IIC协议是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。是一个多主机的半双工通信方式。每个挂载在总线上的器件都有个唯一的地址。

IIC时序

1、空闲状态

空闲状态时,SDA和SCL同时处于高电平

2、起始信号

SCL高电平期间SDA由高到低跳变。起始信号只能由主机空闲状态发起。

3、停止信号

SCL高电平期间SDA由低到高跳变

4、传输数据格式

SCL低电平期间,SDA电平变化;SCL高电平期间,读取SDA电平,此时SDA电平必须稳定,否则就会变成起始/终止信号。如果主机在传输数据期间,碰到中断等情况,可以主动拉低SCL,使IIC进入等待状态 ,直到处理结束再释放SCL数据传输会继续

5、应答信号ACK

IIC总线上的数据都是以8位数据(字节) 进行的,当发送了8个数据后,发送方 会在第9 个时钟脉冲期间释放SDA数据,存到缓冲区,当接收方接收该字节成功,便会输出一个ACK应答信号,当接收方SDA为高电平,表示无效应答信号NACK;当SDA为低电平,表示有效应答信号ACK

6、完整的数据传输

发送起始信号 后,发送8位的设备地址 ,其中第8位是对设备的读写标志。后面紧跟的就是数据 ,直到发送停止信号终止

当我们第一次是读操作,然后想转换成写操作时,可以再发送一个起始信号,然后发送读的设备地址,不需要停止信号就能实现不同的地址转换。

IIC传输的数据格式

写操作

起始信号

7bit设备地址+1bit读/写操作

等待ACK应答

8bit数据

等待ACK应答

停止信号
IIC写操作

读操作

起始信号

设备地址+读/写操作

ACK应答

传输数据

ACK应答

停止信号

Linux驱动

指令

常用Linux指令

怎么查看当前进程?

列出当前进程: ps

查找特定进程:ps | grep 进程名

退出shell会话:exit

ls 命令的作用?

列出指定目录中的目录,以及文件

参数

-a 显示所有文件及目录 (. 开头的隐藏文件也会列出)

-l 除文件名称外,亦将文件型态、权限、拥有者、文件大小等资讯详细列出

-t将文件依建立时间之先后次序列出

-R 若目录下有文件,则以下之文件亦皆依序列出

mkdir 命令的作用?

mkdir 文件夹 创建一个文件夹,路径不存在则报错

mkdir -p 文件夹/子文件夹() 创建一个文件夹,路径不存在则创建

创建文件用什么命令?

vi/vim touch echo less、more、cat cd >/>>

vi/vim 直接创建并打开一个文本文件

touch 创建一个文件

echo "this is a new file" > file.txt 创建文件并将字符串写入,不存在则创建文件。> 指令为覆盖。

lessmorecat

三者都是将文件内容输出到标准输出,其中 less和 more可以分页显示。(less可以往前翻页)。cat 是显示全部。三者可以根据已经存在的文件创建新的文件。

cat/less/more 1.txt > 2.txt

cd

cd >/>> file3.txt#创建新的空文件

cd 最主要的作用是切换目录,在cd 后面跟>或>>再加上文件名就可创建一个空文件。它和echo的区别在于echo可以写文件内容,而cd不能。

复制文件用什么命令?

cp -r test/ newtest test下所有文件复制到新目录 newtest下

查看文件内容有哪些命令可以使用?

vi/vim cat more/less tail(仅查看尾部,可指定行数) head(仅查看头部,可指定行数)

怎么向屏幕输出带空格的字符串?

echo hello world

移动文件?改名?

mv

删除文件用哪个命令?删除非空目录?删除空文件夹?

rm -rf

rmdir -rf-rf代表递归强制

查找文件内容用哪个命令

#在当前目录中,查找后缀有 file 字样的文件中包含 字符串 的文件,并打印出该行

grep 字符串 *文件后缀
#找到目录中具有字符串内容的文件

grep -r 字符串 目录
#找到文件名包含文件名字符串b的文件,并查找不包含字符串a的行

grep -v 字符串a *文件名字符串b* -v表示反向匹配

查找文件用哪个命令

find ./ -name "*.c" #列出当前目录及子目录下所有文件后缀 .c 的文件

cat 命令

cat -n text1 #把 text1 的文档内容加上行号后输入到屏幕

cat -n text1 > text2 #把 text1 的文档内容加上行号后输入到 text2 文件里。

cat -b text1 text2 >> text3 #把text1、text2的文件内容加上行号后追加到 text3文件里。

cat /dev/null > /etc/text.txt #清空 text文档的内容

常用的GCC指令

GCC代表GNC编译器套件。

编译的流程是 预处理编译汇编链接

预处理 GCC -E -o .i文件

编译 GCC -S -o .s文件

汇编 GCC -c -o .o文件

链接 GCC xxx.o -o xxx 得到可执行文件

预处理

gcc -E test.c -o test.i#把预处理的结果导出到test.i文件

-E 代表对.c源码进行预处理(preprocess)。-o代表导出。

' .i ' 文件是指经过预处理后的源代码文件。

编译

gcc -S test.i -o test.s #编译器将test.i编译成汇编语言,导出到.s汇编文件

-S 代表对预处理后的 .i 文件进行编译(--assemble)。生成 .s 汇编文件。

汇编

gcc -c test.s -o test.o #将汇编代码编译为目标文件.o但不链接

-C 代表对汇编文件 .s 进行汇编(--compilation),生成目标文件 .o

链接

gcc test.o -o test #将目标文件test.o连接成可执行文件test

一步编译到位

gcc test.c -o test #将源文件直接 预处理、编译、汇编、链接 生成可执行文件

常用的GDB调试命令

gcc -g test.c -o test #编译时生成debug有关的程序信息

gdb test #启动调试

help #查看命令帮助,具体命令查询在gdb中输入help + 命令,简写 h

run #重新开始运行文件,简写 r

start #单步执行

list #查看原代码,list-n,从第n行查看原代码

set #设置变量的值

next #单步调试(逐过程,函数直接执行),简写n

step #单步调试(逐语句),简写s

backtrace#查看函数调用的栈帧和层级关系,简写bt

frame #切换函数的栈帧,简写f

info #查看函数内部局部变量的数值,简写i

finish #结束当前函数,返回到函数调用点

continue #继续运行,简写c

print #打印值及地址,简写p

quit #退出gdb,简写q

break+num #在第num行设置断点,简写b

info breakpoints #查看当前设置的所有断点

delete breakpoints num #删除第num个断点,简写d

display #追踪查看具体变量值

undisplay #取消追踪观察变量

watch #被设置观察点的变量发生修改时,打印显示

i watch #显示观察点

enable breakpoints #启用断点

disable breakpoints #禁用断点

x #查看内存x/20xw 显示20个单元,16进制,4字节每单元

run argv[1] argv[2] #调试时命令行传参

set follow-fork-mode child #Makefile项目管理:选择跟踪父子进程(fork())

常用的驱动开发指令

加载/卸载驱动

insmod/modprobe #加载驱动,xxx.ko文件,加载时执行驱动入口函数

rmmod #卸载驱动,卸载时执行驱动出口函数

驱动入口函数 static int __init 类型的自定义函数

驱动出口函数 staitc int __exit 类型的自定义函数

Linux驱动如何查看驱动模块中打印信息

dmesg

查看内核环形缓冲区中的所有消息

如何查看内核中已有的字符设备信息?

lsmod 和 modprobe,

lsmod可以查看模块的依赖关系。modprobe在加载模块时会加载其他模块的依赖项

如何查看正在使用的有哪些中断号?

cat /proc/interrupt

uboot

什么是bootloader

BootLoader是芯片出厂预设的小段程序,它在系统上电时开始运行,初始化时钟,看门狗,中断,SDRAM,等外设 。然后将LInux内核从FLASH拷贝到SDRAM中。最后启动Linux内核。

Bootloader和Linux的关系就像PC上的BIOS和Windos的关系一样。

uboot启动过程中做了哪些事

第一阶段

初始化时钟,关闭看门狗,关中断,启动 ICACHE,关闭 DCACHE和 TLB,关闭 MMU,初始化SDRAM,初始化NAND FLASH,重定位。
第二阶段

初始化一个串口,检测系统内存映射,将把内核映像和根文件系统映像从Flash读到SDRAM空间中,为内核设置启动参数,调用内核。

CPU和主存之间存在多级高速缓存,一般分为3级,分别是L1, L2和L3。代码由指令和数据组成。L1 Cache比较特殊,每个CPU会有2个L1 Cache。分别为:

指令高速缓存(Instruction Cache,简称iCache)

数据高速缓存(Data Cache,简称dCache)

L2和L3一般不区分指令和数据,可以同时缓存指令和数据。

uboot和内核如何完成参数传递

uboot启动后已经完成了基本的硬件初始化(如:内存、串口等),接下来,它的主要任务就是加载Linux内核到SDRAM,然后跳转到Linux内核所在的地址运行。

跳转时直接修改PC寄存器的值为Linux内核所在的地址。

在跳转到内核以前,uboot需要做好三件事:

1、CPU寄存器的设置

R0 = 0

R1 = 机器类型ID;

R2 = 启动参数标记列表在RAM中起始基地址。
2、CPU工作模式

必须禁止中断(IRQs和FIQs)。

CPU设置为SVC模式。
3、Cache和MMU设置

MMU必须关闭。

指令Cache可以打开也可以关闭。

数据Cache必须关闭。

当参数个数不超过4个时,使用r0~r3这4个寄存器来传递参数;如果参数个数超过4个,剩余的参数通过数据栈来传递。

为什么要给内核传递参数

uboot完成对硬件的初始化,但是内核并不了解当前的硬件环境,因此需要设置硬件参数告诉内核,让内核适应开发板。

uboot 如何给内核传递参数

R1把机器ID传递给内核 ,内核通过机器ID来判断是否支持当前机器。

R2存放块内存的基地址。内存中包括内存起始地址、内存大小、内核挂载文件系统的方式等信息。由于内存中有多个参数,因此要按照双方规定的地址参数结构存放。

内核以标记列表(tagged_list)的形式来传递启动参数。标记,是一种数据结构;标记列表,是连续存放的多个标记。标记列表以ATAG_CORE开始,以标记ATAG_NONE结束。

标记的数据结构为tag,它由一个tag_header结构和一个联合union组成。tag_header结构表示标记的类型和长度,比如是表示内存还是表示命令行等参数。union用来描述每个传递给内核的参数信息。

为什么uboot要关掉caches?

caches是cpu内部的缓存。CPU和主存之间存在3级高速缓存L1 , L2L3。每个CPU有两个L1,分别用来存储指令(iCache)和数据(dCache)。L2和L3都只有一个,可同时缓存指令和数据。

caches是通过协处理器CP15管理的。

上电的时候 iCache 可以不关闭,但 dCache 一定要关闭。否则可能导致刚开始的代码取数据的时候去数据缓存里面取,这时候的RAM中数据还没有缓存过来,导致数据异常。

文件系统

什么是根文件系统

根文件系统(rootfs)是内核启动时挂载的第一个文件系统,不仅具有普通文件系统存储数据文件的功能,还用来保存内核代码的映像文件。bootloader程序会在根文件系统挂载后把一些初始化脚本(如rcS,inittab)和服务加载到内存中去,里面包含Linux内核运行所必须的应用程序、库等。

文件系统和内核是完全独立的两个部分,但文件系统可用来加载内核。在嵌入式中移植的内核下载到开发板上,是没有办法真正启动Linux操作系统的,会出现无法加载文件系统的错误。

根文件系统为什么重要

根文件系统是加载其他文件系统的根。根文件系统包含系统启动时所必须的目录和关键性文件,以及使其他文件系统得以挂载(mount)所必要的文件。例如

  • init进程的应用程序必须运行在根文件系统上。
  • 根文件系统提供了根目录"/"
  • linux挂载分区时所依赖的信息存放于根文件系统 /etc/fstab这个文件中。
  • shell命令程序必须运行在根文件系统上,譬如 ls、cs等命令。

总之:一套linux体系,只有内核本身是不能工作的,必须要rootfs根文件系统(/etc/目录下的配置文件、/bin 、/sbin等目录下的shell命令,还有**/lib目录下的库文件**等)相互配合才能工作。

可执行映像文件通常由几部分组成

可执行映像文件是一种包含可执行程序的文件。WINDOS中可执行映像文件的后缀是PE,Linux操作系统中可执行映像文件的后缀通常是ELF。

可执行映像文件通常由三个部分构成。

  • 一个或多个代码段,代码段的属性为只读。
  • 零个或多个包含初始化数据的数据段,数据段的属性为可读写。
  • 零个或多个不包含初始化数据的数据段,数据段的属性为可读写。

Linux驱动模型

字符设备驱动模型

设备驱动模型

驱动初始化

相关推荐
w微信1501350781212 小时前
小华一级 代理商 HC32F005C6PA-TSSOP20 HC32F005系列
c语言·arm开发·单片机·嵌入式硬件
憧憬一下13 小时前
Pinctrl子系统中Pincontroller和client驱动程序的编写
arm开发·嵌入式·c/c++·linux驱动开发
上海知从科技1 天前
知从科技受邀出席ARM日产技术日
arm开发·科技
极客小张2 天前
基于STM32的智能温室环境监测与控制系统设计(代码示例)
c语言·arm开发·stm32·单片机·嵌入式硬件·物联网·毕业设计
TeYiToKu2 天前
笔记整理—linux驱动开发部分(6)platform平台总线
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件
飞腾开发者3 天前
飞腾平台Arm ComputeLibrary编译安装指南
linux·服务器·arm开发·后端·性能优化
CodingCos3 天前
【ARM Linux 系统稳定性分析入门及渐进 1.1 -- Crash 工具功能概述】
linux·arm开发·crash tools·linux crash·crash 工具使用
@haihi4 天前
IIC和SPI的区别和相同之处
arm开发·stm32·mcu
@@庆5 天前
FreeRTOS 数据传输方法(环形buffer,队列的本质)队列实验—多设备玩游戏
arm开发·stm32·单片机·嵌入式硬件·freertos
LensonYuan7 天前
信创环境模拟:X86架构下部署搭建aarch64的ARM虚拟机
arm开发·架构·aarch64·虚拟开发环境