实验二、嵌入式操作系统内核与驱动程序
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
~(MASK << (5<<2)) (1<< (5<<2))
MASK 0xF
对灯的控制,就是对数据寄存器 | 0x2000 灭灯 & 0xdfff 亮灯
GPL_DAT相应的位进行操作 1<<13 ~(1<<13)
4、实验原理
地址空Fra Baidu bibliotek映射
#define GPL_BASE_ADDR 0x7f008810 static void __iomem *led_base;
{ 删除设备节点,注销设备……
}
//声明模块加载与卸载时执行的函数 module_init(my_init); module_exit(my_exit);
4、实验原理
2) 打开与关闭函数
static int my_open( struct inode*inode, struct file*filp )
telnet工具
构建
运行
NFS
网络
虚拟机+ubuntu Windows平台
应用程序 网络文件系统
Linux内核 UBoot
4、实验原理
4.1 Linux设备分类
字符设备
以字节为单位逐个进行I/O操作 字符设备的缓存是可有可无 不支持随机访问 如:串口设备
块设备
块设备的存取是通过buffer、cache来进行 可以进行随机访问 如:IDE硬盘设备
5、实验操作步骤
5.4 编写程序
1) 重新打开一个控制台终端 注意,必须在ubuntu宿主机环境下进行以下操作。
2) 创建驱动程序子目录 root@ubuntu:~# mkdir /usr/local/src/drv
3) 进入相应的子目录 root@ubuntu:~# cd /usr/local/src/drv
/* 设备关闭函数 */ static int my_release(struct inode *inode, struct file *file) {
iounmap(led_base); return 0; }
驱动程序:Led_drv.c
/* 写函数 */ static ssize_t my_write(struct file *file, const char __user * buf, size_t n, loff_t* l) {
网络设备
通过BSD套接(socket)接口访问 如:以太网络
杂类设备
如LED、PWM等
4、实验原理
4.2 Linux设备文件
Linux抽象了对硬件的处理,所有硬件设备都可以作为文件一样来看待 ; 可以使用和操作文件相同的、标准的系统调用接口来进行打开、关闭 、读写和I/O控制操作; 对用户来说,设备文件与普通文件并无区别; 字符设备和块设备是通过文件节点访问的。在Linux的文件系统中,可 以找到(或者使用mknod创建)设备文件名,称这种文件为设备文件
#define DEVICE_NAME "myled“
驱动程序:Led_drv.c
/*
LED1 = GPL13
LED2 = GPN6 */
#define LED1_BASE_ADDR 0x7f008810 #define GPLCON0 0 #define GPLCON1 4 #define GPLDAT 8
5、实验操作步骤
5.1 准备宿主机PC 环境
1)PC加电,启动虚拟机及Ubuntu Linux操作系统; 2)打开Ubuntu控制台终端;
5.2 准备目标机环境
1)连接网络线,一端接PC机、另一端接实验箱开发板 2)目标机加电 3)等待目标机Linux启动运行,LCD屏显示企鹅Logo
5、实验操作步骤
4、实验原理
1)查看设备文件
4、实验原理
2)设备文件访问过程
open() fd
write()、read()、ioctl()、close() fd 系统调用接口
Linux内核 设备驱动 myopen()、 my_write()、my_read()、my_ioctl()、my_release()
4、实验原理
printk("<0> led write: %c\n", led_status); return n; }
驱动程序:Led_drv.c
/* 数据结构初始化 */
static struct file_operations dev_fops = { .owner = THIS_MODULE, .open = my_open, .read = my_read, .write = my_write, .ioctl = my_ioctl, .release = my_release,
4) 编辑程序文件 root@ubuntu:~# gedit led_drv.c
驱动程序:Led_drv.c
/* * 文件名:led_drv.c */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/miscdevice.h> #include <linux/moduleparam.h> #include <linux/uaccess.h>
};
static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops,
};
驱动程序:Led_drv.c
/* 加载函数 */ static int __init my_init(void) {
led_base = ioremap(GPL_BASE_ADDR , 16);
4、实验原理
内核空间与用户空间数据拷贝
1)将用户空间数据拷贝到内核空间
copy_from_user(void*dst, void* src, int len);
2)将内核空间数据拷贝到用户空间
copy_to_user( void* dst, void* src, int len);
static void __iomem *led_base;
驱动程序:Led_drv.c
/* 设备打开函数 */ static int my_open(struct inode *inode, struct file *file) {
led_base = ioremap(LED1_BASE_ADDR , 16); *((int*)(led_base + GPLCON1 )) &= ~(MASK << (5<<2)); *((int*)(led_base + GPLCON1 )) |= (0x1 << (5<<2)); *((short*)(led_base + GPLDAT )) |= (1<<13); return 0; }
unsigned char led_status;
copy_from_user((void*)&led_status, buf, 1); if (led_status == '1')
*((short*)(led_base + GPLDAT)) |= (1<<13); else
*((short*)(led_base + GPLDAT)) &= ~(1<<13);
实验二、 嵌入式操作系统内核与驱动程序
1
目录
1 实验目的与要求 2 实验内容 3 实验环境 4 实验原理 5 实验操作步骤 6 实验结果
1、实验目的与要求
1)了解Linux下设备驱动程序的基本架构; 2)熟悉在ARM-linux下设备驱动程序编写过程; 3)掌握设备驱动程序的应用测试方法。
2、实验内容
}
4、实验原理
4) 数据结构
/include/linux/fs.h
struct file_operations { struct module *owner; ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); ……
{ 初始化硬件,设备打开时的操作
}
static int my_release( struct inode*inode, struct file*filp )
{ 设备关闭时的操作
}
3) 读写函数
static int my_read( struct file*f, const char*buf, size_t count,
}
4、实验原理
第一步:查找资料 从《Real6410硬件手册1.2.pdf》,获悉LED灯的硬件控制电路图
。
LED LED1(EINT21) LED2(EINT6)
IO寄存器 GPL13 GPN6
CPU引脚 8 55
根据电路图查找《S3C6410X_UM_Rev1.10_080822.pdf》,获悉 EINT21信号引脚定义。
1)编写并注册一个文件名为myled的设备驱动程序,能够控制ARM 开发板上的LED1灯的亮与灭。 2)编写一个应用程序,验证驱动程序的正确性,并实现LED1灯每 秒闪烁2次。
3、实验环境
3.1 硬件环境
以太网
开发模式:宿主机(开发机)和目标机
3、实验环境
3.2 软件环境
编辑应用程序
控制台
交叉工具链
5.3 连接宿主机与目标机
1)在宿主机上打开一个终端窗口 点击界面菜单栏的按钮
也可以同时按 CTRL+ALT+T
5、实验操作步骤
2)在终端键入 telnet 192.168.1.20
3) login:root 4) 出现real6410#提示符,表明宿主机与目标机连接正常。 环境准备就绪。注意,该终端被目标机所有,不能编辑、构 建程序。
loff_t *ppos )
{ 设备读出时的操作
}
static int my_write(struct file*f, const char*buf, size_t count,
loff_t *ppos )
{ 设备读出时的操作
}
4、实验原理
4) 文件操作函数
static int my_ioctl ( struct inode *inode,struct file *filp, unsigned int cmd,unsigned long arg ) { 处理cmd与参数arg …… }
4、实验原理
4) 数据结构
/include/linux/fs.h
struct file{ … struct dentry *f_dentry; struct file_operations *f_op; mode_t f_mode; loff_t f_pos; void *private_data; …
4.3 Linux设备驱动程序结构
Linux 设备驱动程序的代码结构大致分为以下几个部分: 驱动程序的注册与注销、设备的打开与释放、设备的读与写、设备
的控制操作、设备的中断和轮询处理
1)注册与注销函数
static int __init my_init( void )
{ 注册设备,创建设备节点……
}
static void __exit my_exit( void)
4、实验原理
GPL 接口寄存器
4、实验原理
GPL 接口寄存器
4、实验原理
GPN 接口寄存器
4、实验原理
GPN 接口寄存器
4、实验原理
第二步:根据资料的说明完成寄存器参数设置,初始化。
GPL13 初始化为输出引脚,即对控制寄存器 GPL_CON1进行设置。
& 0xFF0FFFFF | 0x00100000