RT5350 GPIO

默认分类 | 2015-07-22 19:23:06 | 2558次阅读 | 0评

fd = open("/dev/gpio", O_RDONLY);

if (ioctl(fd, RALINK_GPIO_SET_DIR_IN, RALINK_GPIO(0)) < 0) // 这里能看到对gpio号0设置输入模式

 

3. 使能gpio的中断功能;

if (ioctl(fd, RALINK_GPIO_ENABLE_INTP) < 0)

4. 注册进程的进程号到相应的gpio号,用来接收相应引脚发生中断时,接收来自中断处理程序发个应用进程一个信号。

info.pid = getpid();
info.irq = 0;

if (ioctl(fd, RALINK_GPIO_REG_IRQ, &info) < 0)

在ralink_gpio驱动中,维护了一个全局数组,ralink_gpio_reg_info ralink_gpio_info[RALINK_GPIO_NUMBER];,这个数组记录了,相应引脚对应的应用层的进程号。

RALINK_GPIO_REG_IRQ命令就是用来在数组[0]中加入进程号。

在gpio驱动中,先为gpio注册中断,这个中断理解为为所有的gpio引脚的中断。

在ralink_gpio.c中ralink_gpio_init_irq函数,

void __init ralink_gpio_init_irq(void)

{
setup_irq(SURFBOARDINT_GPIO, &ralink_gpio_irqaction); // SURFBOARDINT_GPIO为中断号6,ralink_gpio_irqaction为中断处理结构,struct irqaction。
}

struct irqaction ralink_gpio_irqaction = {

.handler = ralink_gpio_irq_handler, // 这是中断处理函数
.flags = SA_INTERRUPT,

.name = "ralink_gpio", //   ?
};

进入ralink_gpio_irq_handler 函数,在这个函数中首先获取是在哪个引脚(gpio号)发生了中断。这里有个关键的寄存器,gpio中断状态寄存器,这个寄存器记录了所有gpio引脚的中断状态,如果有中断发生,则相应的位置1.

ralink_gpio_save_clear_intp();// 这个函数里ralink_gpio_intp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIOINT)); RALINK_REG_PIOINT这个则就是gpio中断状态寄存器// 的地址,这里ralink_gpio_intp  就是获取了这个寄存器的值

for (i = 0; i < 24; i++) { // ralink5350一共有24个gpio引脚

if (! (ralink_gpio_intp & (1 << i)))   // 判断从0-23 相应的位是否是为1,为1则相应的引脚发生了中断。

continue;

  .......

很多路由器上,按键是复用的(比如长按恢复出厂,短按打开或者关闭无线),按键需要判断长按还是短按,则要判断相应gpio的上升沿和下降沿的时间差;

有一个结构体

struct gpio_time_record {
unsigned long falling;

unsigned long rising;
};

随后的代码则是对这些进行判断(按照需求,去修改代码)。

在判断长按短按后,通过void ralink_gpio_notify_user(int usr) 函数向应用层进程发送一个信号,这个函数很简单,流程一看就明白,参数usr 则是发送的信号值。

引用层的代码会安装相应的信号处理函数,来处理不同的动作。

 

博友评论,共0条
浏览68022次