首页 > 代码库 > gpio操作(LS1B)

gpio操作(LS1B)

1、一般gpio_request 封装了mem_request(),起保护作用,最后要调用mem_free之类的,主要是告诉内核这个地址被占用了。当其他地方调用同一地址gpio_request就会报告错误,改地址已被申请。在/proc/mem 可以看到有地址占用表描述。

     这种用法的保护前提是大家都遵守先申请在访问,有一个地方没有遵守这个规则,这功能就失效了,就好比进程互斥,必须大家在访问临界资源的时候都先获取锁一样,其中一个没有遵守约定,代码报废;

     2、__gpio_set_value 和 gpio_set_value的区别

      一般的带有__这种操作的宏和函数是未保护的,对这种__操作的使用最好不用;主要是为了防止错误地址引用: __gpio_set_value是没有地址范围检测的,如果引用非法地址,有可能内核down掉;

//龙芯1b  buzzer.c

#include <linux/fs.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/gpio_keys.h>
#include <asm/gpio.h>

#define DEVNAME "buzzer_gpio"

#define BUZZER_MINOR 123

MODULE_AUTHOR("liangqx <liangqingxin-gz@loongson.cn>");
MODULE_DESCRIPTION("Drive the buzzer through the gpio");
MODULE_LICENSE("GPL");

static int major;
module_param(major, int, 0);

static struct gpio_keys_platform_data *pkb = NULL;


static int buzzer_set_value(struct file *filp, const char __user *buffer,
size_t count, loff_t *ppos)
{
char code[2];
int port,value;

copy_from_user(code, buffer, (count < 2)?count:2);

value = http://www.mamicode.com/code[0] - ‘0‘;

if(value >= pkb->nbuttons) return -ENOMEM;

port = pkb->buttons[value].gpio;
value = http://www.mamicode.com/code[1] - > printk("prot is %d, value is %d\n",port,value);
gpio_set_value_cansleep(port, value);

return count;
}

static int __devinit buzzer_gpio_probe(struct platform_device *pdev)
{
struct gpio_keys_platform_data *pdata = http://www.mamicode.com/pdev->dev.platform_data;
int i;

pkb = pdata;

for(i = 0;i < pkb->nbuttons;i++)
{
gpio_request(pkb->buttons[i].gpio,"buzzer");
gpio_direction_output(pkb->buttons[i].gpio, 0);
}

return 0;
}

static const struct file_operations buzzer_fops = {
.owner = THIS_MODULE,
.write = buzzer_set_value,
};

static struct miscdevice buzzer_misc_device = {
BUZZER_MINOR,
"buzzer_gpio",
&buzzer_fops,
};

struct platform_driver buzzer_device_driver = {
.probe = buzzer_gpio_probe,
.driver = {
.name = "buzzer_gpio",
}
};

static int __init buzzer_init(void)
{
if(misc_register(&buzzer_misc_device)){
printk(KERN_WARNING "buzzer:Couldn‘t register device 10, %d.\n", BUZZER_MINOR);
return -EBUSY;
}

return platform_driver_register(&buzzer_device_driver);
}

static void __exit buzzer_exit(void)
{
int i;
misc_deregister(&buzzer_misc_device);
for(i = 0;i < pkb->nbuttons;i++){
gpio_free(pkb->buttons[i].gpio);
}
}

module_init(buzzer_init);
module_exit(buzzer_exit);