当前位置:文档之家› 嵌入式系统设计实验五

嵌入式系统设计实验五

实验名称: 姓名: 学号:装订线P.1实验报告课程名称: 嵌入式系统设计 指导老师:马永昌 成绩:________________实验名称:实验五Linux 字符驱动开发 实验类型:验证型 同组学生姓名:__孙凡原_______ 一、实验目的和要求(必填) 二、实验内容和原理(必填) 三、主要仪器设备(必填) 四、操作方法和实验步骤 五、实验数据记录和处理 六、实验结果与分析(必填) 七、讨论、心得一、实验目的和要求1.掌握字符设备驱动程序的基本结构和开发方法2.掌握用户空间调用设备驱动的方法二、实验内容和原理1.编写字符驱动实现按键驱动,控制LED2.编写应用程序调用驱动三、主要仪器设备 树莓派、PC 机四、操作方法和实验步骤1编译运行所给样例驱动程序,验证实验现象,熟悉驱动开发过程。

编译时注意修改Makefile 中的相关路径 1)将编译得到的可执行文件demo 和模块demo.ko 放入树莓派SD 卡 2)将树莓派SD 卡中的内核镜像文件kernel7.img 替换为第二次实验所编译得到的内核镜像 3)运行树莓派,用串口或SSH 登录到树莓派,使用insmod 命令加载模块 4)将8按键模块和LED 灯接到相应的GPIO 口,运行demo 观察现象2修改样例驱动程序,实现对超声波传感器的控制,并编写相应的应用程序读取超声波传感器的数据,显示距离。

五、实验数据记录和处理1.超声波传感器驱动demo.c#include <linux/init.h> #include <linux/module.h> #include <linux/device.h> #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/cdev.h> #include <linux/ioctl.h> #include <linux/fs.h>专业:测控技术与仪器姓名:颜睿 学号:3130103850日期:2018.3.28地点:创客空间装订线#include <linux/delay.h>#include <linux/time.h>#include <asm/uaccess.h>#define DRIVER_NAME "Demo"#define DEVICE_NAME "Demo"static dev_t demo_devno; //设备号static struct class *demo_class;static struct cdev demo_dev;static struct gpio_config{int trig_num;int echo_num;long time;}config;//结构体用于用户态和内核态之间传递数据static int flag = 0;struct timeval tv1;struct timeval tv2;//open 函数,应用程序调用open系统调用时会调用本函数static int demo_open(struct inode *inode,struct file *filp){printk(KERN_INFO"Demo open\n");return 0;}//release 函数,应用程序调用close系统调用时会调用本函数static int demo_release(struct inode *inode, struct file *filp){if(flag){gpio_free(config.trig_num);gpio_free(config.echo_num);flag = 0;}printk(KERN_INFO"Demo release\n");return 0;}//ioctl 控制函数,应用程序调用ioctl系统调用时会调用本函数装订线static long demo_ioctl(struct file *filp,unsigned int cmd,unsigned long arg){int err = 0;long start;long stop;switch(cmd){case 0://0 表示命令号,一般都用宏定义来控制//GPIO口进行初始化{if(copy_from_user(&config,(void *)arg,sizeof(struct gpio_config))){ //从用户程序中获取配置数据printk(KERN_ERR"[%s %d] : copy_from user failed !\n",__func__,__LINE__);return -EFAULT;}printk(KERN_INFO"[%s %d]: Get trig gpio num: %d and echo gpio num: %d\n ",__func__,__LINE__,config.trig_num,config.echo_num);err = gpio_request_one(config.trig_num,GPIOF_IN,"Trig");if(err){printk(KERN_ERR"[%s %d]:Request trig gpio failed\n",__func__,__LINE__);return -EFAULT;}err = gpio_request_one(config.echo_num,GPIOF_OUT_INIT_LOW,"Echo");if(err){printk(KERN_ERR"[%s %d]:Request echo gpio failed\n",__func__,__LINE__);gpio_free(config.trig_num);}flag = 1;break;}case 1:{gpio_direction_output(config.trig_num,0);//设置GPIO口方向gpio_direction_input(config.echo_num);gpio_set_value(config.trig_num,0);//根据传感器时序图进行操作udelay(10);gpio_set_value(config.trig_num,1);udelay(20);gpio_set_value(config.trig_num,0);while(gpio_get_value(config.echo_num)==0){}do_gettimeofday(&tv1);//获取声波开始时间while(gpio_get_value(config.echo_num)==1){}装订线do_gettimeofday(&tv2);//获取声波返回时间start=_sec*1000000+_usec;//数据转换为微妙stop= _sec*1000000+_usec;config.time=stop-start;if(copy_to_user((void *)arg,&config,sizeof(struct gpio_config))){printk(KERN_ERR"[%s %d] : copy to user failed !\n",__func__,__LINE__);//数据由内核传送至用户return -EFAULT;}flag=1;break;}default:printk(KERN_INFO"[%s %d]:Invalid cmd", __func__,__LINE__);break;}return 0;}static struct file_operations demo_fops = {.owner = THIS_MODULE,.open = demo_open,.release = demo_release,.unlocked_ioctl = demo_ioctl,};static int __init demo_init(void){int err;printk(KERN_INFO"Demo Init \n");err = alloc_chrdev_region(&demo_devno,0,1,DRIVER_NAME);if(err < 0){goto err;}cdev_init(&demo_dev,&demo_fops);err = cdev_add(&demo_dev,demo_devno,1);if(err < 0)装订线{printk(KERN_ERR"[%s,%d]add cdev failed\n",__func__,__LINE__);goto FREE_DEVNO;}//自动生成设备文件在/dev目录下,文件名为DEVICE_NAMEdemo_class = class_create(THIS_MODULE,DEVICE_NAME);if(IS_ERR(demo_class)){printk(KERN_ERR"[%s,%d]class create failed\n",__func__,__LINE__);goto DEV_FREE;}device_create(demo_class,NULL,demo_devno,NULL,DEVICE_NAME);return 0;DEV_FREE:cdev_del(&demo_dev);FREE_DEVNO:unregister_chrdev_region(demo_devno, 1);err:return err;}static void demo_exit(void){if(flag){gpio_free(config.trig_num);gpio_free(config.echo_num);}device_destroy(demo_class,demo_devno);class_destroy(demo_class);cdev_del(&demo_dev);unregister_chrdev_region(demo_devno, 1);printk(KERN_INFO"Demo exit\n");}module_init(demo_init);module_exit(demo_exit);MODULE_AUTHOR("yrjj");MODULE_DESCRIPTION("HC-SR04 Driver");MODULE_LICENSE("GPL");2.应用程序demo.c装订线#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/time.h>#include <sys/ioctl.h>#include <errno.h>#include <fcntl.h>struct gpio_config{int trig_num;int echo_num;long time;};int main(int argc, char **argv){int fd;float dis;struct gpio_config config;config.trig_num = 2;config.echo_num = 3;fd = open("/dev/Demo", O_RDWR);if (fd < 0) {perror("/dev/Demo");exit(0);}ioctl(fd,0,&config);//初始化驱动while(1){printf("\npress any key to start the program!\n");system("stty -echo");//键盘输入不打印显示getchar();system("stty echo");//取消键盘输入不打印显示ioctl(fd,1,&config);//执行驱动操作获取传感器数据dis=(float)(config.time)/1000000*34000/2;//时间差转换为距离printf("time: %d us\n",config.time);装订线printf("distance: %0.2f cm\n",dis);}close(fd);return 0;}3.makefile修改a用户程序makefile更改gcc路径为本机路径:CC := /home/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc b.驱动程序makefile修改linux文件夹路径KERNELDIR:=/home/linux/4.硬件接线5.编译加载运行a.环境变量b.编译c.拷贝d.加载运行六、实验结果与分析装订线实验完成七、讨论、心得实验涉及软件和硬件调试,找bug找到凌晨,不过最终还是完成了。

相关主题