实验三 嵌入式Linux驱动(1)
更新时间:2024-06-21 20:55:01 阅读量: 综合文库 文档下载
- 实验三中推荐度:
- 相关推荐
实验三嵌入式Linux驱动(1)
一、 【实验目的】
1) 熟悉嵌入式Linux驱动程序编写框架。
2) 了解七段数码管驱动程序的工作原理,熟练掌握该驱动程序在嵌入式开
发平台的移植和注册使用。
二、 【实验内容】
1) 学习Linux驱动源代码,分析代码中各个函数模块的功能作用。 2) 在宿主机上交叉编译七段数码管驱动程序,然后移植到目标机上。 3) 在目标机上注册驱动程序,验证驱动的功能。
三、 【实验步骤】
1. 了解七段数码管工作原理
七段数码管是显示数字的电子元件,因为借助七个发光二极管以不同组合来显示数字,所以称为七段数码管(如图1)。七段数码管分为共阴极和共阳极,共阳极的七段数码管的正极(或者阳极)为八个发光二极管的共有正极,其他接点为独立发光二极管的负极(或者阴极),使用者只需要把正极接电,不同的负极接地就可以控制七段数码管显示不同的数字。共阴极的七段数码管与共阳极的只是接电的接法相反而已。
图1
2. 开发板七段数码管电路介绍
开发板上有四个七段共阴数码管,2个一组,第一组七段数码管使用系统LED_CS2作为其位选使能信号,两个数码管的段选信号分别使用数据总线的D0~D7位和D8~D15位,如图2所示。
图2
第二组七段数码管使用系统LED_CS3作为其位选使能信号,两个数码管的段选信号分别使用数据总线的D0~D7位和D8~D15位,如图3所示。
图3
分析可知,对七段数码管的操作主要是对其位选和段选信号的控制。其 中位选信号决定显示哪个七段数码管,段选信号决定其显示的字型信息(共阴极七段数码管段选控制信息如表1),这也是驱动程序和硬件关联的主要部分。 字型 0 1 2 3 4 5 6 7 8 9 A B C D
D7 Dp 0 0 0 0 0 0 0 0 0 0 0 0 0 0 D6 G 1 0 1 1 1 1 1 0 1 1 1 1 0 1 D5 F 1 0 0 0 1 1 1 0 1 1 1 1 1 0 D4 E 1 0 1 0 0 0 1 0 1 0 1 1 1 1 D3 D 1 0 1 1 0 1 1 0 1 1 0 1 1 1 D2 C 1 1 0 1 1 1 1 1 1 1 1 1 0 1 D1 B 1 1 1 1 1 0 0 1 1 1 1 0 0 1 D0 A 1 0 1 1 0 1 1 1 1 1 1 0 1 0 编码 0X3F 0X06 0X5B 0X4F 0X66 0X6D 0X7D 0X07 0X7F 0X6F 0X77 0X7C 0X39 0X5E
E F 0 0 1 1 1 1 1 1 表1
1 0 0 0 0 0 1 1 0X79 0X71 3. 七段数码管驱动程序分析
1) 添加驱动程序所需的头文件和变量:SEG_CS1和SEG_CS2就是上面硬
件接口所提及的两组七段数码管的位选使能信号,LED[10]数组中保存的就是在共阴极数码管上面显示0~9的段选信号。Seg这个结构体用于保存4个数码管即时显示的数字的段选信号。
#include
#include #include
MODULE_LICENSE(\//用于声明描述内核模块的许可权限,如果不声明LICENSE,模块被加载时将收到内核被污染(kernel tainted)的警告 char LED_MODULE=0;
#define DEVICE_NAME \#define SEG_CS1 0x10300000 #define SEG_CS2 0x10400000
static char LED[10]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7F, 0x6F}; unsigned long *CS1_Address, *CS2_Address; structseg { char LED1_Val; char LED2_Val; char LED3_Val; char LED4_Val; char negative; };
2) 同时更新所有七段数码管驱动显示函数:CS1_address对应第一组七段数
码管的位选信号,该组第一个数码管的段选信号保存在short变量的低8位,该组第二个数码管的段选信号保存在short变量的高8位。CS2_address对应第二组七段数码管,其余操作和第一组的七段数码管一
致。
static void Updateled(struct seg *seg_7) { unsigned short buff=0x00; buff=seg_7->LED1_Val; buff=buff|( seg_7->LED2_Val <<8); writew(buff,CS1_Address); buff=0x00; buff=seg_7->LED3_Val; buff=buff|( seg_7->LED4_Val<<8); writew(buff,CS2_Address); return; }
3) 写具体某位七段数码光驱动管显示函数:position对应的是4个七段数码
管的相对位置,value就是需要更新的七段数码管要显示数字的段选信号值。
voidvalue_seting(struct seg *seg_7, char position, char value) { if (seg_7->negative==0) value=~value & ~(0x1<<7); else value=(0x1<<7)|value; if (position==1) seg_7->LED1_Val=value; else if(position==2) seg_7->LED2_Val=value; else if(position==3) seg_7->LED3_Val=value; else if(position==4) seg_7->LED4_Val=value; }
4) 实现七段数码管驱动写操作函数:把用户写入的数码管显示更新数据,
转换成为要显示数字对应的段选信号,并且保存在led_forall数组中,并且调用Value_setting更新显示数据,最后调用Updateled()更新实际的数码管显示信息。
staticssize_t seg7_write(struct file *file, const char *buffer, size_t count, loff_t *
printf(\ [3] All Display\\n\ printf(\ [4] Clear Display\\n\ printf(\ [5] Write Display\\n\ printf(\ [C] Close Device\\n\ printf(\ [x] Exit Test\\n\ printf(\ ***********************\\n\ printf(\ }
int main(intargc, char **argv) { intfd=-1; intnum=0; charch=0x00; unsigned char led[4]; display_menu(); while(1) {
ch=getchar();
switch(ch) { case '0': if(fd>0) { printf(\ } else { fd = open(SEG_DEV, O_RDWR); if(fd< 0) printf(\ else printf(\ } display_menu(); break; case '1': if(fd>0) { appear_same(fd); clear_led(fd); }
else
printf(\ display_menu(); break; case '2': if(fd>0) { appear_roll(fd); clear_led(fd); } else
printf(\display_menu(); break; case '3': if(fd>0) display_led(fd); else printf(\display_menu(); break; case '4': if(fd>0) clear_led(fd); else printf(\display_menu(); break; case '5': if(fd>0) { printf(“please input a number(0 <= number <=9999):”); scanf(“%d”, &num); if (num<0 || num> 9999) printf(“can not display this number.\\n”); else { led[0]=num/1000; led[1]=(num00)/100; led[2]=(num0)/10; led[3]=num; write(fd,led,4); } } else
printf(\display_menu(); break; case 'c': case 'C': if(fd>0) { clear_led(fd); sleep(1); close(fd); printf(\ fd=-1; } display_menu(); break; case 'x': case 'X': if(fd>0) { clear_led(fd); sleep(1); close(fd); } exit(0); break; } } return(0); }
2) 测试程序的Makefile文件内容: seg7_test:seg7_test.c arm-linux-gcc seg7_test.c -o seg7_test clean: rm -f seg7_test
5. 七段数码管驱动的交叉编译
1) 进入目录/root/Backup/source下,解压缩驱动源代码到指定路径。
图4
2) 交叉编译驱动:进入/root/Backup/Driver/xidian_seg7目录下,编译源程序。
图5
3) 在确认测试代码和Makefile文件编写无误之后,交叉编译测试代码。
图6
4) 调用file命令查看文件格式,编译出来的可执行程序seg7_test是ARM
的ELF文件。
图7
6. 驱动程序的移植、注册与测试
1) 首先确认实验板和主机的网络连通,然后调用scp命令将测试程序和驱
动程序模块拷贝到目标机上(目标机root用户的密码为“xidian”)。
图8
拷贝成功后,驱动和测试程序保存在目标机的/opt目录下面,如图9所示:
图9
2) 在目标机上利用mknod命令建立设备文件节点;并利用insmod命令动
态加载驱动模块,同时利用lsmod命令查看驱动模块的加载情况。
图10
执行完以上三条命令后,驱动模块成功添加进内核中,完成注册。 3) 在目标机的/opt目录下执行驱动测试程序。
图11
首先在实验板终端驱动测试程序中输入0,打开设备,如果设备成功打开,会在终端打印出提示信息如图12所示。
图12
然后依次调用选项1,2,3,4等,观察实验板上七段数码管执行的结果,分析之前的驱动测试程序各个函数模块的功能,最后在测试程序执行完毕之后,键入dmesg命令,查看驱动测试程序在测试和加载中的输出信息(如图13所示),分析驱动代码,加深对其的理解。
图13
4) 4)卸载驱动程序,删除设备文件。
图14
正在阅读:
实验三 嵌入式Linux驱动(1)06-21
临床药理学与治疗学习题集lchylx04-04
人美版一年级下册美术教学计划(最新整理)07-22
流动人口计划生育工作条例释义05-23
斜拉桥维修加固08-12
学校安全工作领导小组及分工情况12-09
糖代谢习题07-06
工程竣工档案编制细则05-17
蚊子和狮子续写02-20
高一数学两角和与差的正弦、余弦、正切205-16
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 嵌入式
- 驱动
- 实验
- Linux