当前位置:文档之家› 最新Linux设备驱动程序

最新Linux设备驱动程序

中断服务程序
LED设备驱动程序的例子
CPU
struct file_operations LED_fops =
{ read:
LED_read,
write: open: release:
LED_write,
程序列表 (1) LED_open,
LED_release,
};
int LED_init_module(void) { SET_MODULE_OWNER(&LED_fops);
module_init(LED_init_module); module_exit(LED_cleanup_module);
程序列表 (2)
int LED_open(struct inode *inode, struct file *filp) { printk("LED_open()\n");
MOD_INC_USE_COUNT; return 0; }
Linux设备驱动程序
内容
• 设备分类 • 设备驱动程序的框架 • 字符型设备 • 网络设备 • 文件系统
– User Space File System
• USB设备 • FrameBuffer例子和使用 • Debug原理和Debug方法 • 常用设备/fb/ram/loopback/zero
字符设备 vs 块设备
字符设备
块设备
• 字符设备发出读/写请 求时,对应的硬件I/O 一般立即发生。
• 数据缓冲可有可无
• 利用一块系统内存作 缓冲区,一般读写由 缓冲区直接提供,尽 量减少IO操作
• 针对磁盘等慢速设备
• ADC/DAC、按钮、LED、 传感器等
可装卸的设备驱动程序和 静态连接到内核的设备驱动程序
int LED_release(struct inode *inode, struct file *filp) { printk(“LED_release()\n“);
MOD_DEC_USE_COUNT; return 0; }
程序列表 (3)
ssize_t LED_read (struct file *filp, char *buf, size_t count, loff_t *f_pos) { int i;
ioperm(BASEPORT, 3, 0)); // give up
exit(0); • ioperm(from,num,turn_on)
}
• 用ioperm申请的操作端口地址在0x000~0x3FF,利用iopl()
可以申请所有的端口地址
• 必须以root运行
• 用 “gcc -02 –o xxx.elf xxx.c” 编译
for (i=0; i<count; i++) *((char*)(buf+i)) = LED_Status;
return count; } ssize_t LED_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) { int i;
直接访问IO端口(/dev/port)
port_fd = open("/dev/port", O_RDWR); lseek(port_fd, port_addr, SEEK_SET); read(port_fd, …); write(port_fd, …); close(port_fd);
用open/read/write/close 等命令访问
设备 文件
用mknod 命令创建
用户程序
通过主设备号 找到设备驱动
设备驱动程序
用insmod命令安装, 或直接编译到内核中
驱动程序 代码结构
驱动程序注册与注销
设备文件的操作函数 (*open)() (*write)() (*flush)()
(*llseek)() …
#include <asm/io.h>
#define BASEPORT 0x378 // printer
int main()
{
ioperm(BASEPORT, 3, 1)); // get access permission
outb(0, BASEPORT);
usleep(100000);
printf("status: %d\n", inb(BASEPORT + 1));
设备驱动程序内访问设备地址
• 设备驱动程序可以通过指针访问设备地址
• 设备驱动程序接触到的还是虚拟地址,但 对于外界设备有固定的设备地址映射(设 备的地址在移植Linux时候确定)
设备驱动程序
设备驱动程序
虚拟地址映射 设备地址映射
虚拟地址映射 设备地址映射
物理内存地址空间 设备地址空间直接访问IO端口 vs 设备驱动程序
LED_major = register_chrdev(0, "LED", &LED_fops); LED_off(); LED_status=0; return 0; }
void LED_cleanup_module(void) { unregister_chrdev(LED_major, "LED"); }
• 静态连接到内核的设备驱动程序
–修改配置文件、重新编译和安装内核
• 可装卸的设备驱动程序
– insmod 装载
– rmmod
卸载
– lsmod
查询
Linux对硬件设备的抽象
设备文件
• Open/Close/Read/Write • 例子
–/dev/mouse –/dev/lp0
驱动程序与设备文件
IO直接访问 • 用户态 • 程序编写/调试简单 • 查询模式,响应慢 • 设备共享管理困难
设备驱动访问
• 核心态 • 编程调试困难 • 可用中断模式访问、

• 设备共享管理简单 (由内核帮助完成)
设备分类
• 字符设备
–鼠标、串口、游戏杆
• 块设备
–磁盘、打印机
• 网络设备
–由BSD Socket访问
• 注意:不能用fopen/fread/fwrite/fclose因 为它们有数据缓冲,对读写操作不是立即 完成的
outb()/outw()/inb()/inw()函数
#include <stdio.h> #include <unistd.h>
• outb(value, port); inb(port); // 8-bit • outw(value, port); inw(port); // 16-bit • 访问时间大约1us
相关主题