1.CPU刚开始初始化的时候,还未设置栈,所以先使用汇编代码,构造异常向量表,然后设置cpu为svc(管理模式),同时关闭FIQ和IRQ(防止突发中断程序跑飞了)。
2.对cp15协处理器进行设置,主要是关闭了MMU和cache
3.进入板级初始化阶段,对时钟、内存、串口的初始化。最后关闭看门狗。
4.接下来是设置栈,为c语言代码准备环境,调用board_init_f,填充gd结构体。
5.对代码进行重定位,搬到内存中去,搬运之后,跳转到内存中去执行board_init_r,这里就可以开启cache了。然后初始化其他设备。
6.执行main_loop
uboot启动流程如下:
Caches是CPU内部的一个2级缓存,它的作用是将常用的数据和指令放在CPU内部。Caches是通过CP15管理的,刚上电的时候,CPU还不能管理Caches。上电的时候指令Cache可关闭,也可不关闭,但数据Cache一定要关闭,否则可能导致刚开始的代码里面,去取数据的时候,从Cache里面取,而这时候RAM中数据还没有Cache过来,导致数据预取异常 。
两种芯片的结构不同,norflash支持XIP(片上运行),有sram接口,cpu发送一个地址过来,norflash就能给一个数据给cpu,中间不需要额外的处理。
而NAND Flash不一样,Nand Flash的地址、数据、命令是公用IO口的,cpu把地址发出来之后并不能直接得到数据,还需要控制线的操作才能完成。
没什么问题,它和while(1)
一样都是死循环的意思。
前者先执行代码再判断条件是否通过,后者先判断条件再执行代码。
#include <stdio.h>
main()
{
int a,b,c,d;
a=10;
b=a++;
c=++a;
d=10*a++;
printf("b,c,d:%d,%d,%d",b,c,d);
return 0;
}
b = 10,c = 12,d = 120
字符设备是可以向字节流(类似文件)一样被访问的设备,对它的读写都是以字节为单位的,由字符驱动程序来实现这种特性。字符设备驱动程序通常至少实现open,close,read,write
系统调用。字符终端、串口、鼠标、键盘、摄像头、声卡和显卡等就是典型的字符设备。
块设备:和字符设备类似,块设备也是通/dev目录下的文件系统节点来访问的。块设备驱动程序除了向用户层提供与字符设备一样的接口外,还要向内核其他部件提供一些接口,这些接口是用户看不到的。块设备上能容纳文件系统,如:u盘、sd卡、磁盘等。
1、查看驱动打印信息的命令:dmesg
2、查看内核中已有的字符设备信息:lsmod
3、查看正在使用的中断号:cat /proc/interrupt
首先,模块是预显注册自己以便服务于将来某个请求,然后他的初始化函数就立即结束(insmod的时候会调用初始化函数)。换句话说,模块初始化函数额度任务就是为以后调用函数预先作准备。
好处:
1.应用程序在退出时,可以不管资源额度释放或其他的清除工作,但是模块的退出函数却必须撤销初始化函数所作的一切。
2.该机制有助于缩短模块的开发周期。
[A] 内存保护
[B] 地址转换
[C] 加快存取速度
[D] 安全保密
[E] 内存分配
答案 : AB
[A]占用CPU
[B]占用总线
[C]不占用CPU
[D]不占用总线
答案: BC
1.FIQ优先级比IRQ高,不会被中断
2.FIQ有自己的专属寄存器:r8-r12,不用对通用寄存器入栈保护,可以加快速度。
3.FIQ位于异常向量表的末尾0x1C,故无需跳转,可以在这里直接放置异常处理函数。
内存分配有三种:静态存储区、堆区、栈区。他们的功能不同、使用方法也不同。
1.静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。主要存放全局变量(全局数据,.bss
存放未初始化的变量,.data
存放已初始化的全局变量)、静态变量(静态数据)、常量。
2.栈区:在执行函数时。函数(包括main函数)内局部变量的存储单元都可以在栈上创建,函数执行结束时,这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。(任何局部变量都处于栈区)。
3.堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,并立即将指针置位NULL,防止产生野指针。
并发指的是多个执行单元同时被执行,而并发的执行单元对共享资源(硬件资源和软件上的全局变量、静态变量等)的访问则很容易导致竞态。解决竞态问题的途径是保证对共享资源的互斥访问,所谓互斥访问就是指一个执行单元在访问共享资源的时候,其他的执行单元都被禁止访问。访问共享资源的代码区域被称为临界区,临界区需要以某种互斥机制加以保护、中断屏蔽、原子操作、自旋锁和信号量都是linux设备驱动中可以采用的互斥途径。
并发是多线程中的名词,多线程发生的过程是:多线程是通过线程轮流切换来获取CPU执行时间的。
并发是指一个处理器同时处理多个任务。 并行是指多个处理器或者是多核的处理器同时处理多个不同的任务。
并发是逻辑上的同时发生(simultaneous),而并行是物理上的同时发生。
来个比喻:并发是一个人同时吃三个馒头,而并行是三个人同时吃三个馒头。
手动创建:mknod /dev/led c 250 0
其中dev/led 为设备节点 c 代表字符设备 250代表主设备号 0代表次设备号。
还有UDEV/MDEV
自动创建设备文件的方式,UDEV/MDEV
是运行在用户态的程序,可以动态管理设备文件,包括创建和删除设备文件,运行在用户态意味着系统要运行之后。在 /etc/init.d/rcS
脚本文件中会执行mdev -s
自动创建设备节点。
static struct class *seconddrv_class;
static struct class_device *seconddrv_class_dev;
int major;
static int second_drv_init(void)
{
major = register_chrdev(0, "second_drv", &sencod_drv_fops);
seconddrv_class = class_create(THIS_MODULE, "second_drv");
seconddrv_class_dev = class_device_create(seconddrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */
return 0;
}
中断处理例程应该尽量短,把能放在后半段的任务尽量放在后半段。
写一个中断服务程序要注意快进快出,在中断服务程序里面尽量快速采集信息,包括硬件信息,然后退出中断,要做其它事情可以使用工作队列或者tasklet方式。也就是中断上半部和下半部。
第二:中断服务程序中不能有阻塞操作。应为中断期间是完全占用CPU的(即不存在内核调度),中断被阻塞住,其他进程将无法操作;
第三:中断服务程序注意返回值,要用操作系统定义的宏做为返回值,而不是自己定义的OK,FAIL之类的。
上半部是不能中断的
下半部是可以中断的
对于适时要求高的,必须放在上半部
下半部的实现主要是通过软中断 ,tasklet,和工作队列来实现的.
使用自旋锁的进程不能睡眠,使用信号量而定进程可以睡眠。
中断服务程序中的互斥使用的是自旋锁,原因是在中断处理函数中,硬中断是关闭的,但是要注意这样会丢失可能到来的中断。
1.进程是资源分配的最小单位、线程是程序执行的最小单位,也是处理器调度的基本单位,但线程不是,两者均可并发执行。
2.一个进程有一个或多个线程组成,线程是一个进程中代码而定不同执行路线。
3.进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段,数据集、堆等)及一些进程级的资源(如打开文件和信号等),某进程内的线程在其他进程不可见。
4.调度和切换:线程上下文切换比进程上下文切换要快得多。
1.TCP面向连接,而UDP面向无连接的,即发送数据之前不需要建立连接。
2.TCP提供可靠的服务。它通过校验和、丢包时的重传控制等实现可靠的传输 。而UDP尽最大努力交付,即不保证可靠交付。
3.UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性较高而定通信和广播场景。
4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信方式。
5.TCP对系统资源要求较多,UDP对系统资源要求较少。
1.复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,列如字符数组、整形、结构体等。
2.复制的方法不同。strcpy不需要指定长度,它遇到被复制的字符串结束符’\0’才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3.用途不同。通常复制字符串的时候用strcpy,而复制其他类型而定数据时则一般用memcpy。
1.互斥:是指某一资源同时只允许一个访问则对其进行访问,具有唯一性和排他性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
2.同步:是指互斥的基础上(大多数情况下),通过其他机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。
1.互斥锁(量)用于线程的互斥,信号量用于线程的同步。
2.互斥量值只能为0/1,信号量值可以为非负的整数。也就是说,一个互斥了只能用于一个资源的互斥访问,他不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量时,也可以完成一个资源的互斥访问。
3.互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程,另一个线程得到。
1.预处理:预处理相当于根据预处理命令组装成新的C程序,不过常以i为扩展名。
2.编译:将得到的i文件翻译成汇编代码.s文件
3.汇编:将汇编文件翻译成机器指令,并打包成可重定位目标程序的O文件。该文件是二进制文件。
4.链接:将引用的其他O文件并入到我们程序所在的o文件中,处理得到最终的可执行文件。