嵌入式系统的定义
IEEE的定义:嵌入式系统是“用于控制、监视或者辅助操作机器和设备的装置”
一般定义:以应用为中心,以计算机技术为基础,其软硬件可配置,对功能、可靠性、成本、体积、功耗有严格约束的
一种专用系统,所用的计算机称为嵌入式计算机。
嵌入式系统与PC相比具有的特点:
嵌入式系统的开发模式
嵌入式系统的软件使用交叉开发平台进行开发。
-系统软件和应用软件在主机开发平台上开发
-系统软件和应用软件在嵌入式硬件平台上运行。
宿主机(Host)是用来开发嵌入式软件的系统。
目标机(Target)是被开发的目的嵌入式系统。
交叉编译器(Cross-compiler)是进行交叉平台开发的主要软件工具。它是运行在一种处理器体系结构上,但是可以生成在另一种不同的处理器体系结构上运行的目标代码的编译器。
嵌入式系统开发用到的几种通信方式
windows和linux:通过安装虚拟机工具vmwaretools设置共享
NFS服务:NFS可以将远程文件系统载入在本地文件系统下。远程的硬盘、目录和光驱都可以变成本地主机目录树中的一个子目录。载入后与处理自己的文件系统一样使用即可。不只方便,也节省了重复保存文件的空间、传输文件的时间及网络带宽。
NFS中挂载共享目录:mount -t nfs 主机ip:共享目录 挂载点
配置IP:ifconfig etho0 192.168.0.10
启动服务:service nfs restart
Samba服务:同样可以实现Windows和Linux不同系统间交换文件共享。
访问服务器:\\192.168.0.10
交叉编译环境
交叉编译器:arm-linux-gcc-3.4.1 编译后的目标代码要放在arm设备上运行。
GCC的处理过程:
1.预处理:对头文件(include)、预编译语句(如define等)进行分析[预处理器cpp] -E
2.编译: 将预处理后的文件转换成汇编语言,生成文件.s[编译器ccl] -S
3.汇编:由汇编变为目标代码(机器代码),生成.o的文件[汇编器as] -c
4.连接:连接目标代码,生成可执行程序[链接器ld]
Make工具及Makefile文件
Make工具可以自动完成编译工作,并且可以只对上次编译后修改过的部分进行编译,因此利用Make工具可以提高开
发效率。
Makefile的编写:
一般的格式为:
目标:依赖关系
<Tab键> 命令
定义变量: CC=gcc 定义了一个变量CC,其值为gcc。如果要使用变量,将变量用()包含,并且在前面写上$即可。
例如:$(CC)
Makefile文件的三个内部变量:
$@:扩展成当前规则的目标文件名;
$<:扩展成依赖列表中的第一个依赖文件
$^:扩展成整个依赖的列表
注释:以#开始的都是注释行。
clean: rm: *.o hello clean通常放在文件尾部,用于清除编译生成的文件,它没有需要依赖的文件。
通过命令 #make clean 就可以删除生成的中间文件和可执行文件。
Make工具的使用:
#make all :自动查找当前目录下的Makefile或makefile文件,如果存在就处理,否则报错。all 是需要处理的对象。
如果make命令后不使用任何参数,默认情况下处理的是Makefile中的第一个目标(即第一个用“:”标志的对象)。
#make -f maketest :通过-f 参数指定描述文件,例如这里的Makefile文件名为maketest。
引导加载程序 BootLoader:
在嵌入式系统中,主要使用flash作为系统的存储煤介,很少用磁盘,因此整个系统的加载启动任务就完全由引导程序
(也称为Bootloader)来完成。
BootLoader的烧写方式:
1.通过JTAG口
2.通过以太网口
3.通过串口
BootLoader的两种操作模式:
1.启动加载模式:BootLoader将操作系统从存储设备上加载到内存中运行。无需用户干预。
2.下载模式:这种模式下,目标机上的BootLoader将通过串口连接或网络连接等其他各种通信手段从主机下载文件。
BootLoader的结构框架分文两部分:
stage1:用汇编语言来实现;
stage2:用C语言实现;
几种流行的Linux BootLoader:
1.U-Boot 2.BLOB 3. RedBoot 4.VIVI
内核的裁剪
Linux内核的编译选项:
make config: 进入命令行,可以一行一行的配置
make menuconfig:进入开发人员比较熟悉的menuconfig配置菜单 (最常用的)
make xconfig:在2.4X及以前版本中的xconfig图形配置菜单
菜单选项的几种选择(3种):(用空格切换)
1. M:M表示以模块方式编译进内核,内核启动后,需要手工执行insmod命令才能使用该选项
2. *: *表示直接编译进内核
3. 空表示不编译进内核。
内核的编译:
1.在内核的当前目录下,输入make clean命令,删除已生成的模块和目标文件,即在编译进新内核之前将环境清除干
净。
2.输入make zImage命令,生成经压缩以后的内核映像文件zImage。存放在./arch/arm/boot/目录下。
根系统文件
有了Linux内核,还要构建跟文件系统,这样才能使用内核、存取文件等。
BusyBox工具:
利用cramfs工具创建根文件系统映像文件:
在/home目录下,执行如下命令: #mkcramfs rootfs root.cramfs 生成root.cramfs映像文件,可以将其下载到开发板
上运行。
驱动与QT
驱动程序:应用程序与硬件之间的一个中间软件层;
驱动程序应该为应用程序展现硬件的所有功能,不应该强加其他的约束,对于硬件使用的权限和限制应该由应用程序
层控制。
驱动程序有时会被多个进程同时使用,这时我们要考虑如何处理并发的问题,就需要调用一些内核的函数使用互斥量
和锁等机制。
设备驱动程序的分类:3种
1.字符设备:所有能够像字节流一样访问的设备 eg:串口、并口、触摸屏、虚拟控制台、AD
2.块设备:指可以容纳文件系统的存储设备 eg:磁盘、内存、Flash
3.网络接口设备:网络接口设备比较复杂,通常它们指的是硬件设备,但有时也可是一个软件设备(如回环接口
loopback) eg:eth0
linux驱动编译和加载方式:
一种是直接编译进内核,当内核启动后,新的驱动程序随之运行。
二是编译为模块,动态加载运行。
对模块的操作:
insmod:将编译的模块直接插入内核
rmmod:从内核中卸载模块
lsmod:显式已安装的模块
linux内核模块的基本框架:
#include <linux/module.h> //所有模块都需要的头文件
#include <linux/init.h> //init和exit相关宏
printk() //打印函数 相当于pringf()
驱动程序与应用程序的区别:
1.应用程序一般有一个main 函数,从头到尾执行一个任务;
驱动程序却不同,它没有main 函数,通过使用宏module_init(初始化函数名),将初始化函数加入内核全局初始化函
数列表中。通过宏module_exit(退出处理函数名)注册退出处理函数。
2.应用程序可以和GLIBC 库连接,因此可以包含标准的头文件,比如<stdio.h>、<stdlib.h>等,;
在驱动程序中是不能使用标准C 库的,因此不能调用所有的C 库函数, 只能调用内核的函数,