电子科技大学微机实验报告 实验5_电子科技大学微机实验
电子科技大学微机实验报告 实验5由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“电子科技大学微机实验”。
实验五 基于ARM的模块方式驱动程序实验 【实验目的】 1.掌握Linux 系统下设备驱动程序的作用与编写技巧 2.掌握Linux 驱动程序模块加载和卸载的方法 3.了解Linux 内核中的makefile和kconfig文件
【实验内容】
1.基于s3c2440 开发板编写led 驱动程序。2.将编写好的led驱动加入linux内核中,修改makefile和kconfig文件,配置和编译内核。3.编写关于led 的测试程序,交叉编译后运行,控制led 灯的亮灭。
【预备知识】
1.了解ARM9处理器结构和Linux 系统结构
2.熟练掌握C语言。
【实验设备和工具】
硬件:ARM嵌入式开发平台,PC机Pentium100 以上。
软件:PC机Linux操作系统+MINICOM+AMRLINUX 开发环境
【实验原理】
linux设备驱动程序 驱动的模块式加载和卸载
编译模块
装载和卸载模块
led 驱动的原理
在本开发板上有八个led指示灯,从下往上分别为LED0-LED7。这八个led灯都是接的芯片上的gpio口(通用功能输入输出口)。在本实验的开发板硬件设计中,当led 灯对应的gpio的电平为低时,led灯被点亮;当led灯对应的gpio的电平为高时,led灯灭。本驱动的作用就是通过设置对应gpio口的电平来控制led 的亮灭。
因为ARM 芯片内的GPIO口都是复用的,即它可以被配置为多种不同的功能,本实
验是使用它的普通的I/O口的输出功能,故需要对每个GPIO口进行配置。在内核中已经定义了对GPIO口进行配置的函数,我们只需要调用这些函数就可以完成对GPIO口的配置。
【实验步骤】实验程
序运行效果:
程序会提示:“pleaseenterthe led status”
输入与希望显示的led状态对应的ledstatus值(输入十进制值即可),观察led 的显示情况。例如:
输入数字“3”,对应的二进制数字为00000011
故点亮LED2~LED7
输入数字“4”,对应的二进制数字为00000100
故点亮LED0,LED1,LED3~LED7
【实验结果和程序】
C语言程序:
#include #include #include #include #include #include #include #include #include #include #include #include #include#defineDEVICE_NAME “s3c2440-led”
static intLedMajor=231;
staticintLedMinor=0;
static charledstatus=0xff;staticstructcla*s3c2440_cla;staticstructcdev *s3c2440_led_cdev;
/*
******************************************************************************* ************************
** Function name:Update_led()**Descriptions **Input :NONE **Output :NONE :update the led status
******************************************************************************* ************************
*/ staticvoid Update_led(void)
{
if(ledstatus&0x01)
s3c2410_gpio_setpin(S3C2410_GPC7,1);//LED0灭
else
s3c2410_gpio_setpin(S3C2410_GPC7,0);//LED0亮
if(ledstatus&0x02)
s3c2410_gpio_setpin(S3C2410_GPC5,1);//LED1灭
else
s3c2410_gpio_setpin(S3C2410_GPC5,0);//LED1亮
if(ledstatus&0x04)
s3c2410_gpio_setpin(S3C2410_GPH9,1);//LED2灭
else
s3c2410_gpio_setpin(S3C2410_GPH9,0);//LED2亮
if(ledstatus&0x08)
s3c2410_gpio_setpin(S3C2410_GPB4,1);//LED3灭
else
s3c2410_gpio_setpin(S3C2410_GPB4,0);//LED3亮
if(ledstatus&0x10)
s3c2410_gpio_setpin(S3C2410_GPG5,1);//LED4灭
else
s3c2410_gpio_setpin(S3C2410_GPG5,0);//LED4亮
if(ledstatus&0x20)
s3c2410_gpio_setpin(S3C2410_GPG6,1);//LED5灭
else
s3c2410_gpio_setpin(S3C2410_GPG6,0);//LED5亮
if(ledstatus&0x40)
s3c2410_gpio_setpin(S3C2410_GPG7,1);//LED6灭elses3c2410_gpio_setpin(S3C2410_GPG7,0);//LED6亮
if(ledstatus&0x80)
s3c2410_gpio_setpin(S3C2410_GPG8,1);//LED7灭
else
s3c2410_gpio_setpin(S3C2410_GPG8,0);//LED7亮
}
staticize_ts3c2440_Led_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos){
copy_from_user(&ledstatus,buffer,sizeof(ledstatus));
Update_led();
printk(“write: led=0x%x,count=%dn”,ledstatus,count);returnsizeof(ledstatus);} staticints3c2440_Led_open(structinode*inode,struct file *filp)
{
printk(“led device openn”);
return 0;
} staticints3c2440_Led_release(structinode*inode,struct file*filp)
{
printk(“led device releasen”);
return 0;} staticstructfile_operation3c2440_fops={.owner=THIS_MODULE,.open=s3c2440_Led_open,.write=s3c2440_Led_write,.release=s3c2440_Led_release, };
staticintinits3c2440_Led_init(void)
{
dev_ts3c2440_leds_devno;
/*configure the gpiofor leds*/
s3c2410_gpio_cfgpin(S3C2410_GPG5,S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPG6,S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPG7,S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPG8,S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPC7,S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPC5,S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPH9,S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPB4,S3C2410_GPIO_OUTPUT);
Update_led();/*registerthe devnumber*/ s3c2440_leds_devno=MKDEV(LedMajor,LedMinor);ret=register_chrdev_region(s3c2440_leds_devno, 1,DEVICE_NAME);
/*registerthe chardevice*/
s3c2440_led_cdev=cdev_alloc();if
(s3c2440_led_cdev!= NULL)
{ cdev_init(s3c2440_led_cdev, &s3c2440_fops);s3c2440_led_cdev->owner=THIS_MODULE;if(cdev_add(s3c2440_led_cdev, s3c2440_leds_devno, 1))
printk(KERN_NOTICE “Something wrong when addings3c2440_led_cdev!n”);
else
printk(“Succe addings3c2440_led_cdev!n”);} /*create the device node in /dev*/ s3c2440_cla =cla_create(THIS_MODULE, “led_cla”);cla_device_create(s3c2440_cla, NULL, s3c2440_leds_devno, NULL, DEVICE_NAME);
printk(DEVICE_NAME “ initializedn”);
return 0;
}
staticvoid exits3c2440_Led_exit(void)
cdev_del(s3c2440_led_cdev);cla_device_destroy(s3c2440_cla, MKDEV(LedMajor,LedMinor));cla_destroy(s3c2440_cla);printk(DEVICE_NAME “ removedn”);
}
module_init(s3c2440_Led_init);
module_exit(s3c2440_Led_exit);
【思考题】
1.设备驱动程序的功能是什么?答:设备驱动的功能就是将系统提供的调用映射到作用于实际硬件的和设备相关的操作上。
2.模块化的最大优点是什么?答:可以在系统正在运行着的时候给内核增加模块
提供的功能(也可以移除功能)。
3.如果在驱动模块中删除module_exit(s3c2440_Led_exit);后会有什么影响?
答:这个模块将不能被移除。
4.驱动代码中调用的宏MKDEV 的作用是什么?答:获取设备在设备表中的位置。输入主设备号,从设备号,返回位置号。
【实验结论】
本实验实现了linux环境下的led灯驱动的添加。