gpio导出,以及模块之间变量可见模块驱动实例

一 驱动实例

#include <linux/delay.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/suspend.h>
#include <linux/poll.h>

/*GPIO3_3:用于检测串口是否出现overrun状态*/
#define SERIAL_STATES_GPIO  67

/*导出符号让其他内核模块可见,然后还需要在相应的.h文件中声明(extern volatile unsigned long serial_states;)*/
volatile unsigned long serial_states;
EXPORT_SYMBOL_GPL(serial_states);

static int serial_states_open(struct inode *inode, struct file *file)
{
    return 0;
}

static int serial_states_release(struct inode *inode, struct file *file)
{
    /*note: releasing the wdt in NOWAYOUT-mode does not stop it */
    return 0;
}

static int serial_states_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
    if (!buf || count < 1)
        return 0;

    if (count > 4)
        count = 4;

    serial_states = 1;

    if (copy_to_user(buf, (void*)&serial_states, count)) {
        printk(KERN_ERR"serial_states copy_to_user failed.");
        return -EFAULT;
    }
    return count;
}

static int serial_states_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
    serial_states = 0;
    return count;
}

static const struct file_operations serial_states_fops = {
    .owner = THIS_MODULE,
    .open = serial_states_open,
    .release = serial_states_release,
    .read = serial_states_read,
    .write = serial_states_write,
};

static struct miscdevice serial_states_device = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = "serial_states",
    .fops = &serial_states_fops,
};


static int __init u9500_init(void)
{
    int ret = -1;

    /*注册misc设备*/
    ret = misc_register(&serial_states_device);
    if (ret != 0) {
        printk(KERN_ERR "register serial_states_device miscdevice error");
        goto err1;
    }

    /*判断该gpio是否有效*/
    ret = gpio_is_valid(SERIAL_STATES_GPIO);
    if (0 == ret) {
        printk(KERN_ERR "serial states gpio is invalid!\n");
        goto err2;
    } 

    /*请求gpio:其他地方就不能用了*/
    ret = gpio_request(SERIAL_STATES_GPIO, "serial_states_gpio");
    if (0 != ret)
        goto err2;

    /*设置gpio方向,以及设置输出值*/
    ret = gpio_direction_output(SERIAL_STATES_GPIO, 0);
    if (0 != ret)
        goto err3;

    /*设置gpio输出值*/
    gpio_set_value(SERIAL_STATES_GPIO, 0);

    printk("serial states module probe sucsecc!\n");
    return 0;

err3:
    gpio_free(SERIAL_STATES_GPIO);

err2:
    misc_deregister(&serial_states_device);

err1:
    return ret;
}
module_init(u9500_init);


static void __exit u9500_exit(void)
{
    int ret = -1;
    ret = gpio_is_valid(SERIAL_STATES_GPIO);
    if (0 == ret)
        gpio_free(SERIAL_STATES_GPIO);

    misc_deregister(&serial_states_device);
}
module_exit(u9500_exit);


MODULE_AUTHOR("vector");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("serial_states driver");

二 Makefile 实例

serialstates-objs := serial_states.o
obj-m := serialstates.o 

PWD  := $(shell pwd)
KDIR := /home/vec/mydisk1/soure/kernel/obj
all:
    $(MAKE) -C $(KDIR) M=$(PWD) 
clean:
    rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions modules.order Module.symvers
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值