第二学期嵌入式复习提纲.docx
《第二学期嵌入式复习提纲.docx》由会员分享,可在线阅读,更多相关《第二学期嵌入式复习提纲.docx(18页珍藏版)》请在冰豆网上搜索。
![第二学期嵌入式复习提纲.docx](https://file1.bdocx.com/fileroot1/2023-1/27/afd18df4-f287-4f6c-b1d2-b0a246c0b893/afd18df4-f287-4f6c-b1d2-b0a246c0b8931.gif)
第二学期嵌入式复习提纲
嵌入式复习提纲
第一节、嵌入式系统的概念
●嵌入式系统定义:
嵌入式系统是以应用为中心,以计算机技术为基础,且软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。
它一般由以下几部分组成:
嵌入式微处理器,外围硬件设备,嵌入式操作系统,特定的应用程序
特点:
应用的特定性和广泛性,技术、知识、资金的密集性,高效性,较长的生命周期,高可靠性,软硬一体,软件为主,无自举开发能力。
三要素:
嵌入、专用、计算机
⏹嵌入式系统的组成部分
⏹嵌入式微处理器的分类(体系及应用)
⏹ARM微处理器的类型
⏹ARM9的流水线结构
⏹S3C2440的引脚分类
⏹S3C2410应用系统的AD处理器功能可以提供多达个引脚输入,AD转换精度可达位。
⏹S3C2410的中断控制寄存器类型以及工作模式
第二节、基本命令及操作(配套实验,实验一)
主要掌握命令的使用
Cp,mv,tar,cd,ls,mkdir,man,pwd,rm,mount,chmod,find,gzip,ifconfig,ping
第三节、vi以及gcc(配套实验,实验一)
●Vi编辑器,包括vi编辑器的几种模式,vi编辑器中几种模式之间的转换,保存,退出等命令的使用
●Gcc编译器:
包括四种编译阶段,各个阶段所针对的文件后缀等
●在给定参数情况下,能够使用GCC命令编译简单的源代码
第四节、gdb及make(配套实验,实验一)
●Gdb,包括gdb各种命令的使用
●Make工具的定义
●Makefile包含的内容:
Linux中Makefile包括以下内容:
(1)需要由make工具创建的项目,通常是目标文件和可执行文件。
通常使用“目标(target)”一词来表示要创建的项目。
(2)要创建的项目依赖于哪些文件。
(3)创建每个项目时需要运行的命令。
●Makefile的编写规则
●Make的编译规则
(一)附录:
Makefile编写实例
1)edit:
main.okbd.ocommand.o//定义目标文件edit和源文件main.o等
gcc-oeditmain.okbd.ocommand.o//定义edit的编译方法
main.o:
main.cdefs.h//定义目标文件main.o和源文件main.cdefs.h
gcc-cmain.c//定义main.o的编译方法
kbd.o:
kbd.cdefs.hcommand.h//定义目标文件kbd.o和源文件
gcc-ckbd.c//定义kbd.o的编译方法
command.o:
command.cdefs.hcommand.h//定义目标文件command.o和源文件
gcc-ccommand.c
clean:
//定义伪目标
rmeditmain.okbd.ocommand.odisplay.oinsert.o//删除目标文件
2)CC=/opt/host/armv4l/bin/armv4l-unknown-linux-gcc//定义gcc
LD=/opt/host/armv4l/bin/armv4l-unknown-linux-ld//定义ld
CFLAGS=-I/HHARM9-EDU/kernel/include/linux-Wall//定义编译选项
led.o:
led.c//定义目标和源文件
$(CC)$(CFLAGS)-gled.c-oled//编译方法
cpled.o/-f//复制led.o到/
.PHONY:
clean//定义伪目标
clean:
//定义clean
-rm-f*.o//删除中间文件
第五节、交叉编译环境的搭建【配套实验,实验二】
●什么是交叉编译环境,为什么要搭建交叉编译环境
●搭建交叉编译环境的方法【配套实验,实验二】
⏹搭建交叉编译工具(EABI4.3.3)
⏹通讯(PC---ARM)
◆串口(minicom\超级终端)【要求掌握minicom及超级终端的设置方法步骤】
◆网络(NFS\TFTP)【要求掌握NFS及TFTP的设置方法步骤】
◆JTAG
第六节、引导程序bootloader、内核、文件系统【配套实验,实验三、四】
●引导程序bootloader
⏹什么是bootloader以及bootloader的作用
⏹Bootloader启动的两个阶段
⏹安装U-boot的过程
●内核
⏹内核的基本定义
⏹内核静态编译的大致内容及过程
●文件系统
⏹什么是文件系统
⏹根目录结构
⏹利用mount命令挂载文件系统的方法
⏹利用busybox创建文件系统的方法【实验三】
第七节、驱动程序【实验四】
⏹设备管理的总体结构
⏹设备驱动的定义
⏹设备驱动的存在形式
⏹设备驱动的分类及其代表
⏹设备驱动的开发流程
⏹字符设备驱动代码的结构
⏹字符设备驱动程序的编写
实例1、
1)staticstructfile_operationskeybd_fops={
open:
keybd_open,
read:
keybd_read,
release:
keybd_release,};//
intkeybd_open(structinode*inode,structfile*filp)//
{printk("openok\n");
return0;}
ssize_tkeybd_read(structfile*fp,char*buf,//
size_tsize)
{……}
intkeybd_release(structinode*inode,structfile*filp)//
{printk("releaseok\n");//
return0;}
ssize_tled_write(structfile*fp,char*buf,//
size_tsize)
{……}
int__initkeybd_init(void)//
{……}
staticvoid__exitkeybd_exit(void)//
{devfs_unregister(devfs_keybd);}//
module_init(keybd_init);//
module_exit(keybd_exit);//
实例2、
2)LED灯的驱动程序:
/*driver/char/led.c
*thisisaledchardevicedriver.
*Anyproblemplscontactsupport@*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"led_ioctl.h"
#defineLED_MAJOR139
#defineLED_2(LED_1+1)
#defineLED_3(LED_1+2)
#defineLED_4(LED_1+3)
#defineLED_5(LED_1+4)
#defineLED_6(LED_1+5)
#defineled_sle(*(volatileunsignedlong*)LED_GPACON)
#defineled_sle_data(*(volatileunsignedlong*)LED_GPADATA)
devfs_handle_tdevfs_led;
unsignedlongLED_1;
unsignedlongLED_GPACON;
unsignedlongLED_GPADATA;
unsignedlongled_write_addr;
intled_open(structinode*,structfile*);
intled_release(structinode*,structfile*);
intled_ioctl(structinode*,structfile*,unsignedint,unsignedlong);
ssize_tled_read(structfile*,char*,size_t);
ssize_tled_write(structfile*,char*,size_t);
staticstructfile_operationsled_fops={
open:
led_open,
read:
led_read,
write:
led_write,
ioctl:
led_ioctl,
release:
led_release,
};
/**Open/closecodeforrawIO.*/
intled_open(structinode*inode,structfile*filp)
{
led_sle|=0x2000;//chip_selectenable
led_sle_data&=(~0x2000);//0-->chip_select
printk("openok\n");
return0;
}
ssize_tled_read(structfile*fp,char*buf,size_tsize)
{
return1;
}
ssize_tled_write(structfile*fp,char*buf,size_tsize)
{
charkey;
if(get_user(key,buf))
return-EFAULT;
(*(volatileunsignedchar*)led_write_addr)=key;
return1;
}
intled_release(structinode*inode,structfile*filp)
{
//led_sle&=(~0x2000);//chip_selectdisable
//led_sle_data|=0x2000;
printk("releaseok\n");
return0;
}
intled_ioctl(structinode*inode,structfile*flip,unsignedintcommand,unsignedlongarg)
{
interr=0;
switch(command){//judgewhichledwanttolight
caseIOCTRL_LED_1:
led_write_addr=LED_1;
break;
caseIOCTRL_LED_2:
led_write_addr=LED_2;
break;
caseIOCTRL_LED_3:
led_write_addr=LED_3;
break;
caseIOCTRL_LED_4:
led_write_addr=LED_4;
break;
caseIOCTRL_LED_5:
led_write_addr=LED_5;
break;
caseIOCTRL_LED_6:
led_write_addr=LED_6;
break;
default:
err=-EINVAL;
}
returnerr;
}
int__initled_init(void)
{
printk("*********************led_init**************\n");
LED_GPACON=ioremap(0x56000000,4);
LED_GPADATA=ioremap(0x56000004,4);
LED_1=ioremap(0x10000000,8);
devfs_led=devfs_register(NULL,"led",DEVFS_FL_DEFAULT,LED_MAJOR,0,
S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP,
&led_fops,NULL);
return0;
}
staticvoid__exitled_exit(void)
{
devfs_unregister(devfs_led);
}
module_init(led_init);
module_exit(led_exit);
⏹测试程序的编写
实例1、LED灯测试程序【实验四中附录】
实例2、ADC测试程序
#include
#include
#include
int main(int argc, char **argv)
{
int fd; //以阻塞方式打开设备文件,非阻塞时flags=O_NONBLOCK
fd = open("/dev/my2440_adc", 0);
if(fd < 0)
{
printf("OpenADCDeviceFaild!
\n");
exit
(1);
}
while
(1)
{
int ret;
int data //读设备
ret = read(fd, &data, sizeof(data));
if(ret !
= sizeof(data))
{
if(errno !
= EAGAIN)
{
printf("ReadADCDeviceFaild!
\n");
}
continue;
}
else
{
printf("ReadADCvalueis:
%d\n", data);
}
}
close(fd);
return 0;
}
第八节、中断
⏹中断的定义及种类
⏹CPU响应中断的方式
⏹中断相关数据结构的定义
⏹中断程序的编写
实例1、#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
voidtestirq_interrupt(int,void*,structpt_regs*);
staticinttestirq_init(void);
/**********************************************************/
//InterruptFunction
voidtestirq_interrupt(intirq,void*d,structpt_regs*regs)
{
/*clearinterruptregisterforEINT5*/
SRCPND&=(~0x00000010);//bit4
INTPND=INTPND;
EINTPEND&=(~0x00000020);//bit5
printk("Enteredaninterrupt!
Beginninginterruptservice!
\n");
}
/****************************************************/
//InitializeFunction
staticint__inittestirq_init(void)
{
staticintresult;
unsignedlonggpfup;
//longpullup;
set_external_irq(IRQ_EINT5,EXT_FALLING_EDGE,GPIO_PULLUP_DIS);
gpfup=ioremap(0x56000058,4);//pull_upforportf
(*(volatileunsignedlong*)gpfup)=0;
disable_irq(IRQ_EINT5);
enable_irq(IRQ_EINT5);
result=request_irq(IRQ_EINT5,&testirq_interrupt,SA_INTERRUPT,"testirq",NULL);
if(result)
{
printk("Can'tgetassignedirq%d,result=%d\n",IRQ_EINT5,result);
returnresult;
}
printk("Testirqinterruptregisteredok!
!
!
\n");
return0;
}
staticvoid__exittestirq_exit(void){
disable_irq(IRQ_EINT5);
free_irq(IRQ_EINT5,NULL);
printk("exitok\n");
}
module_init(testirq_init);
module_exit(testirq_exit);
第九节、模块加卸载【实验四、五】
⏹模块加卸载的方式(静态编译、动态加载)
⏹模块静态编译的方法(已有GPIO.C如何添加进内核)【实验四】
⏹模块动态加载的定义
⏹模块动态加载的优缺点
⏹模块动态加载的方法【实验五】
第十节、minigui的安装【实验六】
第十一节、综合实例(ADC)
(三)S3C2440中AD转换器驱动程序
1、建立驱动程序文件my2440_adc.c,实现驱动的初始化和退出
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*定义了一个用来保存经过虚拟映射后的内存地址*/
static void __iomem *adc_base;
/*保存从平台时钟队列中获取ADC的时钟*/
static struct clk *adc_clk;
/*申明并初始化一个信号量ADC_LOCK,对ADC资源进行互斥访问*/
DECLARE_MUTEX(ADC_LOCK);
static int __initadc_init(void)
{
int ret;
/*从平台时钟队列中获取ADC的时钟,这里为什么要取得这个时钟,因为ADC的转换频率跟时钟有关。
系统的一些时钟定义在arch/arm/plat-s3c24xx/s3c2410-clock.c中*/
adc_clk = clk_get(NULL, "adc");
if (!
adc_clk)
{
/*错误处理*/
printk(KERN_ERR "failedtofindadcclocksource\n");
return -ENOENT;
}
/*时钟获取后要使能后才可以使用,clk_enable定义在arch/arm/plat-s3c/clock.c中*/
clk_enable(adc_clk);
/*将ADC的IO端口占用的这段IO空间映射到内存的虚拟地址,ioremap定义在io.h中。
注意:
IO空间要映射后才能使用,以后对虚拟地址的操作就是对IO空间的操作,
S3C2410_PA_ADC是ADC控制器的基地址,定义在mach-s3c2410/include/mach/map.h中,0x20是虚拟地址长度大小*/
adc_base = ioremap(S3C2410_PA_ADC, 0x20);
if (adc_base == NULL)
{
/*错误处理*/
printk(KERN_ERR "Failedtoremapregisterblock\n");
ret = -EINVAL;
goto err_noclk;
}
/*把看ADC注册成为misc设备,misc_register定义在miscdevice.h中
adc_miscdev结构体定义及内部接口函数在第②步中讲,MISC_DYNAMIC_MIN