model)之平台总线(bus),驱动(driver),设备((3)

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/irq.h>

#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>

/* [cgw]: 设置四个按键的键码,按键io,激活状态,按键名,按键类型 */
static struct gpio_keys_button keys_buff[4] = {
    {
        KEY_A,
        S3C2410_GPF0,
        1,
        "A",
        EV_KEY
    },
   
    {
        KEY_B,
        S3C2410_GPF2,
        1,
        "B",
        EV_KEY
    },

{
        KEY_C,
        S3C2410_GPG3,
        1,
        "C",
        EV_KEY
    },

{
        KEY_D,
        S3C2410_GPG11,
        1,
        "D",
        EV_KEY
    },
};


static struct gpio_keys_platform_data keys_dev = {
    .buttons = &keys_buff[0],
    .nbuttons = ARRAY_SIZE(keys_buff)
};

static void keys_dev_release(struct device * dev)
{
    printk("keys_dev_release! \n");
}

/* [cgw]: 分配一个平台设备 */
static struct platform_device keys_platform_dev = {
    .name        = "gpio-keys",
    .id          = -1,
    .dev = {
        .release = keys_dev_release,
        .platform_data = (void *)&keys_dev,
    },
};


static int keys_dev_init(void)
{
    /* [cgw]: 注册keys_platform_dev平台设备 */
    platform_device_register(&keys_platform_dev);
    return 0;
}

static void keys_dev_exit(void)
{
    /* [cgw]: 注销keys_platform_dev平台设备 */
    platform_device_unregister(&keys_platform_dev);
}

module_init(keys_dev_init);
module_exit(keys_dev_exit);

MODULE_LICENSE("GPL");

应用测试程序:

platform_test.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

#include <linux/input.h>

int fd;

void my_signal_fun(int signum)
{
    struct input_event buttons_event;

/* [cgw]: 异步通知产生时返回的数据 */
    read(fd, &buttons_event, sizeof(struct input_event));

/* [cgw]: 打印事件类型,事件码,事件值 */
    printf("type: 0x%x code: 0x%x value: 0x%x\n",
          buttons_event.type,
          buttons_event.code, 
          buttons_event.value);
}

int main(int argc, char **argv)
{
    int ret, arg;
    struct pollfd fds[1];
    unsigned long ver = 0;

fd = open("/dev/event1", O_RDWR | O_NONBLOCK);
   
    if (fd < 0)
    {
        printf("can't open!\n");
    }

ioctl(fd, EVIOCGVERSION, &ver);
    printf("Ver:0x%x \n", ver);

/* [cgw]: 设置文件标识符 */
    fds[0].fd    = fd;
    /* [cgw]: 设置应用程序要响应的事件 */
    fds[0].events = POLLIN;

while (1)
    {
        /* [cgw]: 休眠5S */
        ret = poll(fds, 1, 5000);
       
        /* [cgw]: 唤醒或超时 */
        //printf("wake up!\n");
        if (ret == 0)
        {
            printf("time out\n");
        }
        else
        {
            my_signal_fun(arg);
        }
    }

close(fd);
   
    return 0;
}

平台设备(platform_device) keys_platform_dev 是怎样找到与之匹配的平台驱动(platform_driver) gpio_keys_device_driver的呢?

因为他们都注册到了平台总线(platform_bus)上。平台驱动(platform_driver)和平台设备(platform_device)会相互查找彼此是否匹配,匹配的条件就是,

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/348d13bcdc011a59def9fa43377be116.html