版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wr132/article/details/78565243
驱动模块编写步骤:
- 查找并调用所需的内核函数,同时为所需的结构体命名
- 补全所需的结构体,使用vim -t查找结构体声明
- 通过结构体声明所在的文件补全头文件
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h> //gpio_request
#include <plat/gpio-cfg.h> //s3c_gpio_cfgpin
#include <mach/gpio.h> //GPIO 宏
#include <linux/fs.h>
#define DRIVER_NAME "led_test"
#define DEVICE_NAME "led_dev"
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("[email protected]");
//避免出现struct declared inside parameter list
struct platform_deivce;
struct miscdevice;
static int led_plat_probe(struct platform_device *pdev);
static int led_plat_remove(struct platform_deivce *pdev);
struct platform_driver led_pdri = {
.probe = led_plat_probe,
.remove = led_plat_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
}
};
static int led_open(struct inode *inode, struct file *filp);
static int led_release(struct inode *inode, struct file *filp);
static long led_ioctl(struct file *filp, unsigned int cmd, unsigned int arg);
struct file_operations led_fops = {
.open = led_open,
.release = led_release,
.unlocked_ioctl = led_ioctl,
};
struct miscdevice led_mdev = {
.minor = 10,
.name = DEVICE_NAME,
.fops = &led_fops,
};
/*define file operation functions*/
static int led_open(struct inode *inode, struct file *filp)
{
printk("led open\n");
return 0;
}
static int led_release(struct inode *inode, struct file *filp)
{
printk("led release\n");
return 0;
}
static long led_ioctl(struct file *filp, unsigned int cmd, unsigned int arg)
{
printk("led ioctl\n");
switch(cmd) {
case 0:
gpio_set_value(EXYNOS4_GPL2(0), 0);
break;
case 1:
gpio_set_value(EXYNOS4_GPL2(0), 1);
break;
default:
printk("wrong cmd\n");
}
return 0;
}
/*define platform driver functions*/
static int led_plat_probe(struct platform_device *pdev)
{
int error;
printk("led platform driver probe\n");
error = gpio_request(EXYNOS4_GPL2(0), "led1");
if(error < 0)
goto err_gpio_request;
s3c_gpio_cfgpin(EXYNOS4_GPL2(0), S3C_GPIO_OUTPUT);
misc_register(&led_mdev);
return 0;
err_gpio_request:
printk("fail to request gpio\n");
return error;
}
static int led_plat_remove(struct platform_deivce *pdev)
{
printk("led platform driver remove\n");
misc_deregister(&led_mdev);
gpio_free(EXYNOS4_GPL2(0));
return 0;
}
static int led_mod_init(void)
{
int error;
printk("led module init\n");
printk("register led platform driver\n");
error = platform_driver_register(&led_pdri);
if(error < 0)
goto error_register_platform_driver;
printk("register platform driver success\n");
return 0;
error_register_platform_driver:
printk("fail to register platform driver\n");
return -1;
}
static void led_mod_exit(void)
{
printk("led module exit\n");
printk("unregister led platform driver\n");
platform_driver_unregister(&led_pdri);
}
module_init(led_mod_init);
module_exit(led_mod_exit);