一、处理器的基本概念
1、微处理器与微控制器
A、微控制器(microcontroller):除了中央处理器(CPU)之外还集成了部分内存和外设。
B、微处理器(microprocessor)
2、寄存器
A、通用寄存器(General Purpose Register,GPR):作用包括执行指令、进行整型数据和逻辑运算。
通用寄存器中存在:程序计数器(Program Counter,PC),栈指针寄存器(Stack Pointer,SP)。
B、浮点寄存器(Floating Point Register,FPR):用于运算具有小数点的数据。
3、处理器的启动
处理器在上电后,由硬件决定读取的第一条指令。
4、中断
A、轮询
B、中断
a、为了支持中断,处理器需要初始化好中断控制器,并安装好对应的中断服务程序或称为ISR(Interrupt Service Routine)。
b、中断服务程序的实现:从外设读取中断状态寄存器的值;为了告诉外设处理器已经处理完了所需做的工作,处理器需要通过一定的方式通知外设芯片;清除处理器的中断信号标识。
c、中断触发方式有:电平触发、上升沿触发和下降沿触发。
d、与外设相关的中断称为硬中断,需要外设一定要用到处理器的中断信号线;通过执行处理器的指令触发的中断称为软中断或陷阱(trap)。
5、字节序
A、小端模式(little endian):低位字节存放在低地址。
B、大端模式(big endian):高位字节存放在低地址。
6、边界对齐
边界对齐(boundary alignment)是处理器为了提高处理性能而对存取数据的起始地址所提出的要求。
7、程序断点和数据断点
A、程序断点(program breakpoint):指处理器的指令断点,程序运行到某函数的某个地方就会停下来;分为软件程序断点和硬件程序断点。
B、数据断点(data breakpoint):与硬件程序断点类似,查看当一个变量的值被改变时能自动停下来。
处理器一般都提供了硬件程序断点,但是数据断点未必提供。
8、内存管理单元
内存管理单元(Memory Management Unit,MMU):
操作系统通过内存管理单元实现以下功能:
A、虚拟内存:可以在处理器上运行比实际物理内存大的应用程序;需要设置一个交换分区(通常是硬盘),通过将内存中不活跃的数据放入交换分区以腾出物理内存来为其他的程序服务。
B、内存保护:可以将特定的内存块设置为读、写和可执行属性。
内存管理单元存在页的概念,对于所有与内存保护相关的操作都是以页的大小来进行的,比如,在常用的32位x86处理器上,页的大小是4KB。
在设置内存块的读写属性时,内存块的开始地址必须是页的整数倍,或者说地址必须是以页大小作为边界对齐的。
9、缓存
A、缓存位于处理器内部,为了解决处理器在运行的过程中需要频繁地使用内存,而处理器的运行速率远远高于外部内存的访问速度。
B、缓存命中:当处理器需要从外部内存获取数据时,先从缓存中查找数据是否以前存进来过,如果在缓存中找到了,则称为缓存命中。
C、如果没有找到,这需要从外部内存中获取,在这种情况下,并不是要一个字节就读一个字节,而是一次性地采用突发方式(burst mode,内存芯片支持的一种存取方式)从内存中读入一行缓存行。一行缓存行可能是64字节,视不同的处理器而不同。
D、但处理器需要向内存写数据时,需要根据我们对缓存的配置进行不同的操作。其中一种模式是数据先写入缓存,然后由处理器在合适的时间将缓存中的数据回写到外部内存中;另一种模式是数据直接回写到外部内存中。
E、缓存的设计基于这样一种思想,即指令和数据的适应具有很强的局部性。
F、在处理器中我们可以配置各地址空间是否需要使能缓存功能,或者说缓存并非只针对内存,还可以针对其他的存储器,如闪存。如果对应的空间是闪存,那么对闪存进行编程(又称为烧写)时一定要禁用缓存功能。这是因为在对闪存芯片进行编程时需要一定的写命令序列,如果闪存所在的空间使能了缓存功能,那么编程写命令序列有可能不会立即发送给闪存芯片,而是存放在缓存中,结果就是不能正常地进行闪存编程操作了。
G、在一些高端处理器上还提供了缓存锁定功能,使得某块缓存区中的数据不会因为腾出空间的需要而变成无效。
二、工具
A、makefile
B、gcc:分为预处理(preprocessing)、编译(compilation)、汇编(assembly)和链接(linking)。
a、预处理的目的是展开源文件中的所有宏指令(#include,#define);
b、编译生成.s文件;
c、汇编生成.o文件;
d、链接需要.o文件和C库文件,生成.exe文件。
使用gcc产生映射文件方法:gcc -Wl,-Map=main.map main.c -o main.exe(-Wl中的l不是数字1,而是指字符l,多个选项的时候使用’,‘隔开)。
使用gcc生成依赖关系的方法:gcc -M main.c(包含系统头文件);gcc -MM main.c(不包括系统头文件)。
C、addr2line,指令地址翻译器。
D、ar,静态库生成器。
E、nm,符号显示器:nm -n main.exe。
F、objdump,信息查看器:了解生成的文件中的段信息,或者查看C语言对应的汇编代码,objdump -h main.exe。
G、objcopy,段剪辑器:可以对程序文件中的段进行过滤。
H、ranlib,库索引生成器:用于在档案文件中生成文件索引。
I、size,段大小观察器:查看程序文件中各段的大小。
J、strings,字符串窥视器:查看程序文件中的可显示字符。
K、strip,程序文件瘦身器:用于去除程序文件中的调试信息以便减小程序文件的大小。
三、链接器
链接器的(linker)的功能是将一个可执行程序所需的目标文件和库最终整合为一体。
重定向(relocation):链接生成的可执行程序时,需要根据每一个符号所对应的真实地址而更新相应的指令,从而实现真正的函数调用和变量引用功能。
四、GDB
A、backtrace命令可以查看程序的调用栈;info locals可以查看函数的所有局部变量的值;info args可以查看函数参数的值;info frame可以查看当前当前栈帧的信息。
五、程序结构
程序是被分成段(section)加以管理的。
A、段:.test段、.data段和.bss段。
B、栈作用:当中断发生时用于保存处理器寄存器的值,以便中断返回时通过退栈回到被中断点继续程序的运行;用作函数参数和局部变量的存储空间。
C、堆作用:为整个系统提供动态分配内存的空间。
六、数组和指针
1、数组的内存模型
C语言中数组变量的名可以认为代表了数组的开始地址,从数组的开始地址处每一个数组元素是按程序中出现的顺序依次排列的。
2、指针的内存模型
七、关键字volatile作用就是不然编译器进行代码优化。
八、bootloader(系统启动引导)
1、完成最小系统的初始化:
A、对处理器进行初始化,包括处理器的工作时钟频率设置;各片选空间的时序和地址空间的配置;内存控制器的初始化;中断控制器的初始化;栈寄存器的初始化等等。
B、对外设和相关的软件模块进行初始化:串口硬件和命令行管理模块进行初始化。
2、加载并执行应用程序。
九、内存管理
1、动态内存是通过调用函数而获得的,来源可以是堆或内存池。当从堆中获得内存时,所需内存大小通过函数的参数加以指定,但从内存池中获得内存时,所获得内存的大小是固定的,其数值在内存池初始化时就决定了。
2、静态内存,其通过定义全局或静态(数组)变量的方式获得,无需调用函数。
十、设备管理
1、字符设备:数据以字符流形式被访问,如串口、键盘;
2、块设备:能够随机访问固定大小的数据片,如硬盘、闪存;
3、网络设备:一帧一帧发送和接受数据包的,如以太网接口。