天天看点

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>

<linux/cdev.h>

#include <linux/io.h>

<linux/errno.h>

#include <linux/platform_device.h>

<linux/miscdevice.h>

#include <linux/gpio_keys.h>

<asm/gpio.h>

#define devname "buzzer_gpio"

#define buzzer_minor 123

module_author("liangqx

<[email protected]>");

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 = code[0] - ‘0‘;

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

port = pkb->buttons[value].gpio;

value = code[1] -

‘0‘;

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 =

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)

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);

继续阅读