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

gpio操作(LS1B),码迷,mamicode.com

时间: 2024-10-30 13:59:04

gpio操作(LS1B)的相关文章

linux 标准 GPIO 操作

Linux 提供了GPIO 操作的 API,具体初始化及注册函数在 driver/gpio/lib_gpio.c 中实现. #include int gpio_request(unsigned gpio, const char *label); 获得并占有 GPIO port 的使用权,由参数 gpio 指定具体 port.非空的label指针有助于诊断.主要告诉内核这块地址被占用了.当其他地方调用同一地址的gpio_request就会报告错误,该地址已经被申请.在/proc/mem有地址占用表

TI CC2530基础实验(普通GPIO操作——按一下按键亮一下灯)

有关CC2530的GPIO基本知识.普通GPIO操作有关寄存器的介绍.IAR Embedded Workbench IDE软件使用:TI CC2530基础实验(普通GPIO操作--点亮led灯) 电路原理图: 分析:需要按一下按键亮一下灯,并且不采用中断方式,即我们需要实时去监测按下是否被按下(P0_4为低电平表示按下,高电平表示松开). 设置: 灯LED1对应的P1_0引脚为普通I/O.方向为输出 按键S1对应的P0_4引脚为普通I/O.方向为输入 程序: /*****************

DA14683开发:GPIO操作

DA14683GPIO操作 勤基科技  陈杰明 添加GPIO初始化函数 在main.c中,添加以下子函数,初始化GPIO口,按键的引脚设置为输入,LED灯的引脚设置为输出. /*按键GPIO设置*/ void key_led_init() { hw_gpio_set_pin_function(HW_GPIO_PORT_1,HW_GPIO_PIN_6, HW_GPIO_MODE_INPUT, HW_GPIO_FUNC_GPIO);//按键 hw_gpio_set_pin_function(HW_G

树莓派高级GPIO库,wiringpi2 for python使用笔记(三)GPIO操作

GPIO库的核心功能,当然就是操作GPIO了,GPIO就是"通用输入/输出"接口,比如点亮一个LED.继电器等,或者通过iic spi 1-wire等协议,读取.写入数据,这都是GPIO的用处,可以说没有GPIO,树莓派只能当小电脑用,有了GPIO,就升级成一个控制器了.先来说说怎么操作一个数字量(高低电平). 先看代码: import wiringpi2 as gpio from wiringpi2 import GPIO gpio.wiringPiSetup() #初始化 gpio

tcc893x基于Linux内核的普通GPIO操作总结

采用非平台方式进行配置GPIO引脚 采用非平台方式进行配置gpio引脚,是直接对其gpio组寄存器进行读写.由于不能直接对寄存器物理地址进行操作,所有需要利用ioremap将gpio寄存器的物理地址映射成虚拟地址 写寄存器:writel(value,对应寄存器的虚拟地址); 读寄存器:value = readl(对应寄存器的虚拟地址); 采用tcc893x平台方式进行配置GPIO引脚 tcc已经帮我们实现一些函数来配置gpio对应引脚功能,常用的4个函数: 定义于:arch/arm/mach-t

【嵌入式Linux+ARM】GPIO操作

1.GPIO介绍 GPIO(general purpose i/o ports)意思为通用输入/输出端口,通俗的说就是一些引脚. 我们可以通过它们输出高低电平 或 读入引脚的状态. s3c2440中有130个I/O端口,分为A~J共9组,GPA.GPB...... GPJ 2.GPIO寄存器 既然要操作GPIO,必须对相应的寄存器进行操作,2440中gpio寄存器有: GPxCON--选择引脚功能(输入.输出.保留等) GPxDAT--用来读写引脚 GPcUP --某一位是1时,相应的引脚无内部

LM3S6911 GPIO操作

最新在学习LM3S6911开发板子.和经典程序 Hello World! 程序是一样的,拿到开发板的第一个程序就是写一个流水灯的程序. 但是这个板子有个问题,使用板载的ISP来下载编译好的.bin文件很奇怪,能下载进去,但是现象不是想要的.但是改用ULinK2的时候就万事大吉了.好的就不废话了,先直接上代码. #include "hw_memmap.h" #include "hw_types.h" #include "debug.h" #incl

一、GPIO操作

1.1 硬件原理图 四个引脚接到LED上,跟别是GPF4,GPF5,GPF6和GPF7,前三个引脚分别控制三个LED,GPF7此引脚作为DM9000网卡的中断. 发光二极管的正极接3.3V电源,负极接在MCU上,当MCU的对应的引脚给一个低电平的时候,电路导通,发光二极管发光. 芯片手册,GPIO配置,如下图,控制LED的属于GPF管脚: GPF的寄存器如下图: GPFCON:GPF管脚的控制寄存器 GPFDAT:GPF管脚的数据寄存器 GPFUP:GPF上拉使能的寄存器 GPF4-GPF6对应

STM32基本GPIO操作:按键输入(扫描+外部中断)

(涉及专有名词较多,难免解释不到位,若有错误还请指出,谢谢!) 硬件连接图如下: 一.扫描 思路是在main函数中通过死循环来扫描端口电平状态检测,以此判断按键是否按下.实现较为简单. 1.初始化(注意C语言中变量声明需放在函数开头) 以下是初始化PB5端口(LED灯)的代码,每一条语句的含义在我另一篇博客里 GPIO_InitTypeDef GPIO_Init1; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_Init1.