嵌入式实验 IO drivers文档格式.docx
- 文档编号:21354997
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:27
- 大小:561.95KB
嵌入式实验 IO drivers文档格式.docx
《嵌入式实验 IO drivers文档格式.docx》由会员分享,可在线阅读,更多相关《嵌入式实验 IO drivers文档格式.docx(27页珍藏版)》请在冰豆网上搜索。
charLED3_Val;
charLED4_Val;
charnegative;
};
(2)同时更新所有七段数码光驱动管显示函数
staticvoidUpdateled(structseg*seg_7)
unsignedshortbuff=0x00;
buff=seg_7->
LED1_Val;
buff=buff|(seg_7->
LED2_Val<
<
8);
writew(buff,CS1_Address);
buff=0x00;
LED3_Val;
LED4_Val<
writew(buff,CS2_Address);
return;
}
(3)写具体某位七段数码光驱动管显示函数
voidvalue_seting(structseg*seg_7,charposition,charvalue)
{
if(seg_7->
negative==0)
value=~value&
~(0x1<
7);
else
value=(0x1<
7)|value;
if(position==1)
seg_7->
LED1_Val=value;
elseif(position==2)
LED2_Val=value;
elseif(position==3)
LED3_Val=value;
elseif(position==4)
LED4_Val=value;
(4)实现七段数码光驱动写操作函数
staticssize_tXSB_Seg_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos)
inti;
structseg*seg_7=file->
private_data;
charled_forall[4];
printk(KERN_EMERG"
TheModuleiswritten,XSB_Seg_write\n"
if(count!
=4)
{
printk(KERN_EMERG"
thecountofinputisnot4!
!
"
return0;
}
if(copy_from_user(led_forall,buffer,4))
for(i=1;
i<
=4;
i++)
{
value_seting(seg_7,i,LED[led_forall[i-1]]);
}
Updateled(seg_7);
}
return0;
(5)实现七段数码管驱动IOCTL操作函数
staticintXSB_Seg_ioctl(structinode*ip,structfile*fp,unsignedintcmd,unsignedlongarg)
charval=0x00;
structseg*seg_7=fp->
if(!
arg)
return-EINVAL;
if(copy_from_user(&
val,(int*)arg,sizeof(char)))
return-EFAULT;
switch(cmd){
case1:
value_seting(seg_7,1,val);
break;
case2:
value_seting(seg_7,2,val);
case3:
value_seting(seg_7,3,val);
case4:
value_seting(seg_7,4,val);
case0:
seg_7->
negative=LED_MODULE;
default:
printk(KERN_EMERG"
ioctlparametererror,pleaseinputnumber0-4"
Updateled(seg_7);
(6)实现七段数码管驱动打开操作函数
staticintXSB_Seg_open(structinode*inode,structfile*filp)
structseg*seg_7;
TheModuleisopen,XSB_Seg_open\n"
seg_7=kmalloc(sizeof(structseg),GFP_KERNEL);
filp->
private_data=seg_7;
(7)实现七段数码管驱动释放函数
staticintXSB_Seg_release(structinode*inode,structfile*filp)
TheModuleisrelease,XSB_Seg_release\n"
kfree(filp->
private_data);
(8)七段数码管驱动文件结构体定义
staticstructfile_operationsEmdoor_fops={
open:
XSB_Seg_open,
write:
XSB_Seg_write,
release:
XSB_Seg_release,
ioctl:
XSB_Seg_ioctl,
owner:
THIS_MODULE,
(9)实现七段数码管驱动初始化函数
staticint__initXSB_Seg_init(void)
intret;
TheModuleisInit,XSB_Seg_init\n"
CS1_Address=ioremap(SEG_CS1,4);
CS2_Address=ioremap(SEG_CS2,4);
ret=register_chrdev(61,DEVICE_NAME,&
Emdoor_fops);
if(ret<
0){
printk(DEVICE_NAME"
can'
tgetmajornumber\n"
returnret;
(10)实现七段数码管驱动模块退出函数与模块描述
staticvoid__exitXSB_Seg_exit(void)
TheModuleisExit,XSB_Seg_exit\n"
iounmap(CS1_Address);
iounmap(CS2_Address);
unregister_chrdev(61,DEVICE_NAME);
module_init(XSB_Seg_init);
module_exit(XSB_Seg_exit);
MODULE_AUTHOR("
Ben.li,ben.li@"
MODULE_DESCRIPTION("
Thisisa8SegmentLeddriverdemo"
2,编写用于编译xsb_seg.c驱动架构Makefile文件
#Makefileforthe8Segment_LedDriver.#
CFLAGS+=$(DEBFLAGS)-Wall
ifneq($(KERNELRELEASE),)
obj-m:
=xsb_seg.o
else
KERNELDIR?
=~/useful/linux-2.6.22.10
PWD:
=$(shellpwd)
ALL:
$(MAKE)$(CFLAGS)-C$(KERNELDIR)M=$(PWD)modules
endif
clean:
rm–fr*.o*.ko*~core.depend.*.cmd*.mod.c.tmp_versions
3,运行Make命令编译驱动,用ls命令查看编译后的结果,在该目录中应该生成xsb_seg.ko模块文件,利用file命令查看xsb_seg.ko文件的格式,应为ARM格式的ELF文件。
ustb@ustb-desktop:
~/workspace/driver$sudomake
4,编写用于测试驱动的程序代码(见seg_test.c文件);
/************************************************
*************************************************/
stdio.h>
fcntl.h>
unistd.h>
typedefunsignedcharu8;
#defineSEG_DEV"
/dev/xsb_seg"
charnumber[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7F,0x6F};
voidclear_led(intfd)
charval=0;
for(i=1;
ioctl(fd,i,&
val);
sleep
(1);
voiddisplay_led(intfd)
charval=0x7f;
voidappear_same(intfd)
chari,j,base=0;
for(j=0,base=0;
j<
=9;
j++,base++){
i<
i++)
ioctl(fd,i,number+base);
voidappear_roll(intfd)
chari,j,base=0;
for(j=0,base=0;
j<
j++,base++){
ioctl(fd,i,number+(base+i-1)%10);
voiddisplay_menu()
printf("
*****ChoiceMenu*********\n"
[0]OpenDevice\n"
[1]DisplaySame\n"
[2]RollDisplay\n"
[3]AllDisplay\n"
[4]ClearDisplay\n"
[5]WriteDisplay\n"
[C]CloseDevice\n"
[x]ExitTest\n"
***********************\n"
Pleaseinputyourchoise:
"
intmain(intargc,char**argv)
intfd=-1;
charch=0x00;
unsignedcharled[4]={2,0,0,8};
display_menu();
while
(1){
ch=getchar();
switch(ch)
case'
0'
:
if(fd>
0)
printf("
##SEGDevicehasbeenopen##%d\n"
fd);
else{
fd=open(SEG_DEV,O_RDWR);
if(fd<
0)
printf("
####SEGDeviceopenFail####\n"
else
####SEGDeviceopenSuccess####%d\n"
display_menu();
break;
1'
0){
appear_same(fd);
clear_led(fd);
else
##SEGDeviceisNOTopen##\n"
case'
2'
appear_roll(fd);
clear_led(fd);
break;
3'
display_led(fd);
4'
5'
write(fd,led,4);
c'
C'
0){
sleep
(1);
close(fd);
printf("
##SEGDeviceisclosedsuccess##\n"
fd=-1;
x'
X'
clear_led(fd);
exit(0);
return(0);
5,编写一个用于编译seg_test.c的Makefile文件;
其中CC=/opt/arm-linux-4.2.1/bin/arm-linux-gcc为交叉编译工具所在的路径位置,INCLUDEDIR=/opt/arm-linux-4.2.1/arm-linux/include为头文件所在的路径
CC=/opt/arm-linux-4.2.1/bin/arm-linux-gcc
INCLUDEDIR=/opt/arm-linux-4.2.1/arm-linux/include
CFLAGS=-I..-I$(INCLUDEDIR)
TARGET_TEST=seg_test
OBJ_TEST=$(TARGET_TEST)
SOURCE_TEST=$(TARGET_TEST).c
$(CC)$(CFLAGS)-o$(OBJ_TEST)$(SOURCE_TEST)
rm-rf$(OBJ_TEST)
注:
上述五步骤所需代码可从实验目录中拷贝到工作区。
~$sudocp-fr/mnt/hgfs/sysc/lab5/driver/~/workspace/
~$sudocp-fr/mnt/hgfs/sysc/lab5/test/~/workspace/
6,用make命令对seg_test.c进行编译,编译后应该会生成一个名为seg_test的文件,利用file命令查看seg_test文件格式,应为ARM格式的ELF文件。
~/workspace/test$sudomake
7,配置内核,在内核源代码根目录/home/ustb/useful/linux-2.6.22.10运行makemenuconfig命令,进入Loadablemodulesupport选项,选上Enableloadablemodulesuport和module_unloading,然后退出,运行makezImage编译内核。
8,将编译好的内核映像zImage和光盘提供的文件系统下载。
9,在minicom终端下,用串口传输方式将编译好的驱动模块xsb_seg.ko和测试驱动的程序seg_test下载到实验箱上;
10,在目标平台终端利用利用insmod命令动态加载驱动模块,然后运行cat/proc/devices命令查看设备号,并用mknod命令建立设备文件节点,然后利用lsmod命令查看驱动模块的加载情况;
11,在目标平台终端运行八段数码驱动测试程序seg_test,在平台终端将显示驱动测试程序菜单。
12,在平台终端显示驱动测试程序菜单输入提示输入数字“0”。
驱动测试程序将通过open函数打开设备文件,同时内核调用驱动程序的xxx_open函数,在平台终端可以查看驱动和测试程序调试输出信息。
如上图。
13,在平台终端显示驱动测试程序菜单输入提示分别输入数字“1”、“2”、“3”、“4”,查看平台4个7段数码管的显示情况,并分析测试程序通过调用什么函数与驱动进行通信?
14,在平台终端显示驱动测试程序菜单输入提示分别输入数字“5”、查看平台4个7段数码管的显示情况,并分析测试程序通过调用什么函数与驱动进行通信?
15,在平台终端显示驱动测试程序菜单输入提示分别英文字符“C”或“c”,然后再输入“1~5”任何数字,查看测试程序的输出情况,并分析测试程序通过调用什么函数与驱动进行通信?
16,在平台终端显示驱动测试程序菜单输入提示分别英文字符“X”或“x”,退出测试程序。
17,在平台终端输入dmesg命令,查看驱动程序在加载和测试过程中输出消息,并分析驱动代码,查看输出信息。
用直接编译进内核的方式加载LED灯驱动:
1,利用vi编辑器或者gedit编写驱动代码(见/mnt/hgfs/sysc/lab5/driver/xsb_led.c文件);
linux/miscdevice.h>
linux/init.h>
asm/hardware.h>
linux/ioport.h>
linux/device.h>
asm/delay.h>
linux/major.h>
xsb_Led"
#defineSEG_LED0x10500000
#defineLed_MAJOR60
staticcharLed_Buff=0x0;
unsignedlong*Led_Address;
(2)控制LED点亮函数
staticvoidUpdateled(void)
writew(Led_Buff,Led_Address);
(3)实现LED驱动写操作函数
staticssize_tLed_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos)
=1)
thecountofinputisnotone!
copy_from_user(&
Led_Buff,buffer,1);
Updateled();
return1;
(4)实现LED驱动的打开、释放函数以及文件操作结构体
staticintLed_open(structinode*inode,structfile
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式实验 IO drivers 嵌入式 实验