Linux驱动编写入门-新解
1.驱动编写后是一个C文件,通过make命令对其进行编译,生成 .KO文件,这个文件就是可执行的驱动文件,通过使用insmod xx.ko即可执行此驱动文件。如下为一个完整的驱动程序C文件。(用的是讯为开发板教程文件)
#include <linux/init.h>
#include <linux/module.h>
/*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
#include <linux/platform_device.h>
#define DRIVER_NAME "hello_ctl"
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("TOPEET");
static int hello_probe(struct platform_device *pdv){
printk(KERN_EMERG "\tinitialized\n");
return 0;
}
static int hello_remove(struct platform_device *pdv){
return 0;
}
static void hello_shutdown(struct platform_device *pdv){
;
}
static int hello_suspend(struct platform_device *pdv){
return 0;
}
static int hello_resume(struct platform_device *pdv){
return 0;
}
struct platform_driver hello_driver = {
.probe = hello_probe,
.remove = hello_remove,
.shutdown = hello_shutdown,
.suspend = hello_suspend,
.resume = hello_resume,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
}
};
static int hello_init(void)
{
int DriverState;
printk(KERN_EMERG "HELLO WORLD enter!\n");
DriverState = platform_driver_register(&hello_driver);
printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
return 0;
}
static void hello_exit(void)
{
printk(KERN_EMERG "HELLO WORLD exit!\n");
platform_driver_register(&hello_driver);
}
module_init(hello_init);
module_exit(hello_exit);
2.程序运行步骤如下 :注册驱动 insmod 命令->module_init(hello_init)函数->static int hello_init(void),
->platform_driver_register(&hello_driver)->hello_probe函数;
删除驱动 :rmmod命令->module_exit(hello_exit)->static void hello_exit(void)->platform_driver_register(&hello_driver);
3.上面的操作只能注册驱动,如何让应用来调用驱动呢?这就得注册设备节点,有了设备节点,应用程序就能像打开文件一样打开节点,然后对其操控。完整程序如下:
#include <linux/init.h>
#include <linux/module.h>
/*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
#include <linux/platform_device.h>
/*注册杂项设备头文件*/
#include <linux/miscdevice.h>
/*注册设备节点的文件结构体*/
#include <linux/fs.h>
#define DRIVER_NAME "hello_ctl"
#define DEVICE_NAME "hello_ctl123"
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("TOPEET");
static long hello_ioctl( struct file *files, unsigned int cmd, unsigned long arg){
printk("cmd is %d,arg is %d\n",cmd,arg);
return 0;
}
static int hello_release(struct inode *inode, struct file *file){
printk(KERN_EMERG "hello release\n");
return 0;
}
static int hello_open(struct inode *inode, struct file *file){
printk(KERN_EMERG "hello open\n");
return 0;
}
static struct file_operations hello_ops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
.unlocked_ioctl = hello_ioctl,
};
static struct miscdevice hello_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &hello_ops,
};
static int hello_probe(struct platform_device *pdv){
printk(KERN_EMERG "\tinitialized\n");
misc_register(&hello_dev);
return 0;
}
static int hello_remove(struct platform_device *pdv){
printk(KERN_EMERG "\tremove\n");
misc_deregister(&hello_dev);
return 0;
}
static void hello_shutdown(struct platform_device *pdv){
;
}
static int hello_suspend(struct platform_device *pdv,pm_message_t pmt){
return 0;
}
static int hello_resume(struct platform_device *pdv){
return 0;
}
struct platform_driver hello_driver = {
.probe = hello_probe,
.remove = hello_remove,
.shutdown = hello_shutdown,
.suspend = hello_suspend,
.resume = hello_resume,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
}
};
static int hello_init(void)
{
int DriverState;
printk(KERN_EMERG "HELLO WORLD enter!\n");
DriverState = platform_driver_register(&hello_driver);
printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
return 0;
}
static void hello_exit(void)
{
printk(KERN_EMERG "HELLO WORLD exit!\n");
platform_driver_unregister(&hello_driver);
}
module_init(hello_init);
module_exit(hello_exit);
4.注册设备节点的过程如下:
insmod 命令->module_init(hello_init)函数->static int hello_init(void),
->platform_driver_register(&hello_driver)->hello_probe函数-> misc_register(&hello_dev);
就是在hello_probe函数增加了misc_register(&hello_dev);注册成功可在dev目录下看到hello_dev结构体中定义的设备节点名。
5.设备节点怎么用呢?代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
main(){
int fd;
char *hello_node = "/dev/hello_ctl123";
/*O_RDWR只读打开,O_NDELAY非阻塞方式*/
if((fd = open(hello_node,O_RDWR|O_NDELAY))<0){
printf("APP open %s failed",hello_node);
}
else{
printf("APP open %s success",hello_node);
ioctl(fd,1,6);
}
close(fd);
}
6.运行上面的程序,open函数打开设备节点,ioctl函数操作设备节点,open函数和ioctl函数通过结构体
static struct file_operations hello_ops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
.unlocked_ioctl = hello_ioctl,
};
映射到驱动程序的hello_open,hello_ioctl函数。而close(fd)就会映射hello_release函数。
注:以上程序源码都是用的讯为开发板程序代码。
Linux驱动编写入门-新解相关推荐
- linux驱动编写(入门)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 在我离职之前,工作内容几乎不涉及到驱动方面的知识.我所要做的内容就是把客户对设备的请求拆分成一 ...
- Linux驱动快速入门
本公众号分享的所有技术仅用于学习交流,请勿用于其他非法活动,如果错漏,欢迎留言指正 应用层:<LUNIX环境高级编程第二版> <Linux程序设计(第四版)> 内核层:< ...
- linux驱动编写--2--应用程序控制led闪烁
本系列教程的上一篇: linux驱动编写--1--点亮led 目标:编写一个驱动程序,实现上一篇没写的 "接口".并编写一个测试程序,透过驱动来控制led闪烁. 硬件:micro ...
- linux驱动编写(虚拟字符设备编写)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 昨天我们说了一些简单模块编写方法,但是终归没有涉及到设备的编写内容,今天我们就可以了解一下相关 ...
- linux驱动编写(设备树)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 对于linux的开发者来说,设备树其实比较熟悉.但是为什么要有设备树,很多人不了解,其实本质来说 ...
- linux驱动编写(看门狗)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 看门狗是linux驱动的一个重要环节.某些特殊的设备,有时候需要放在一些环境恶劣的地方,比如电信 ...
- linux驱动编写(platform总线和网卡驱动)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 对于linux驱动来说,一般的架构还是按照bus-host-device的形式来进行的.比如就拿 ...
- disk磁盘管理与Linux驱动编写
磁盘管理 一.关于硬盘接口 安装linux red hat系统,到分区时发现硬盘驱动器设备 /dev/sda #sata接口设备名 /dev/sda1#sda对应的物理分区 /d ...
- linux 驱动编写(sd卡驱动)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 随着sd卡的流行,sd卡在嵌入式设备上使用的场景也越来越多.那下面我们可以看一下,linux驱动 ...
最新文章
- PyTorch 常用代码段示例整理
- 23种设计模式C++源码与UML实现--访问者模式
- spring boot 中json数据处理
- 用ASP.NET 2.0设计网络在线投票系统
- ListView与Button共存问题
- dynamic的一些使用心得
- 用MATLAB解决实际数学问题,用matlab解决一道数学问题
- Keras Datasets 国内下载镜像
- 网站运营直通车——7天精通SEO
- 190325每日一句
- html登陆滑动验证,js实现登录时的滑动验证【原创】
- 谷歌浏览器离线安装包下载
- 服务器ie浏览器总是未响应怎么办,电脑ie浏览器老是无响应怎么办
- ubuntu18.04修改ip地址
- [转]PCI与PCIe
- 软件测试员工作经验分享
- (官网)虚幻3--基础游戏快速入门
- 什么是JDK、JRE
- Java基础题36:(多选题)下列有关于变量的命名正确的是 A.可以由字母、数字、下划线、”$”组成; 头
- 【深度之眼Python基础+数据科学入门训练营】第四章 组合数据类型
热门文章
- 转载:2014 Top Security Tools as Voted by ToolsWatch.org Readers
- 有源与无源晶振的区别
- .NET Framework各个版本(3.0 - 3.5)
- 谁先量子计算机谁就,G、IBM、中科院,比一比谁先实现量子计算霸权?
- Linux命令之top命令查看服务器CPU与内存占用
- 【开发工具】 我居然可以使用Office Tool Plus 安装上Office 真的是太不可思议了
- 十进制转32位二进制(Java)
- 数据库系统(PostgreSQL)
- markdown写公式的角标与下标
- mouseover和mouseout区别