Linux设备驱动学习一 设备和驱动的注册

使用iTOP-4412开发板,用的是SCP 1G的板子。

记录的内容来自于迅为的视频学习,主要是对驱动的学习,有些基础步骤省略没有记录。

首先是对外部设备的操作的三部曲:

1.通过原理图找到设备连接的PIN脚 (处理器的数据手册)

2.通过PIN脚找到控制这个引脚的相关寄存器,并找到寄存器对应的物理地址

3.编写程序实现设备的操作

 

1. 设备和驱动的注册流程

    一般都是先注册设备,再注册驱动。现在引入的热插拔设备是先注册的驱动。

    1)注册设备使用结构体platform_device,结构体中有name和id(vim include/linux/platform_device.h)

struct platform_device {
        const char      * name;
        int             id;
        struct device   dev;
        u32             num_resources;
        struct resource * resource;

        const struct platform_device_id *id_entry;

        /* MFD cell pointer */
        struct mfd_cell *mfd_cell;

        /* arch specific additions */
        struct pdev_archdata    archdata;
};

    2)注册驱动使用结构体platform_driver,结构体中包括probe,suspend,remove,driver等(vim include/linux/platform_device.h)

struct platform_driver {
        int (*probe)(struct platform_device *);
        int (*remove)(struct platform_device *);
        void (*shutdown)(struct platform_device *);
        int (*suspend)(struct platform_device *, pm_message_t state);
        int (*resume)(struct platform_device *);
        struct device_driver driver;
        const struct platform_device_id *id_table;
};

    3)驱动的注册需要platform_match来判断设备和驱动name是否相同,不同则注册失败。否则probe然后初始化注册设备节点等。(只有name匹配才会到probe这一步)

2. 查看设备或驱动的几个主要命令

    1)insmod,rmmod

    2)lsmod=cat /proc/modules

    3)查看设备节点的命令cat /proc/devices  (0~254)

    4)查看注册的设备:ls /sys/devices/

    5)查看总线:ls /sys/bus  (platform虚拟总线,上面挂很多驱动和设备,通过两个结构体)

    6)查看杂项设备号的命令:cat /proc/misc

3. 案例学习的流程

      其中ITOP4412的设备程序在arch/arm/mach-exynos/mach-itop4412.c(mach-itop4412.c为板级的文件),使用的结构体为linux/platform_device.h中的两个。

       通过hello_ctl的案例梳理设备和驱动注册 

1)首先配置Koncifg,让menuconfig能够识别:

选用的是/driver/char/Kconfig,tristate:可编译成模块
config HELLO_CTL
    tristate "Enable HELLO config"
    default y
    help
        Enable HELLO config

2)增加注册设备的结构体调用。

 /* 选用的是/arch/arm/mach-exynos/mach-itop4412.c  */
 #ifdef CONFIG_HELLO_CTL
 struct platform_device s3c_device_hello_ctl = {
     .name = "hello_ctl",
     .id = -1,
 };
 #endif
 //上面几行注册设备使用的是函数:platform_add_devices(主要使用platform_device_register)
 
#ifdef CONFIG_HELLO_CTL
  &s3c_device_hello_ctl,
#endif

 3)重新编译内核

 make menuconfig   # 查找/driver/char下的HELLO_CTL  用/可以直接搜索
 make zImage       #生成的zImage在/arch/arm/boot目录下

   4)烧写内核 (我用的烧写方法是通过SD卡挂载到开发板)

将zImage拷贝到SD卡的update目录下
在板子的uboot中运行
​​​​​​​# sdfuse flash kernel zImage
# reset

    5)登录板子查看注册完成的设备 

# ls /sys/devices/platform
hello_ctl

至此,设备注册完成。 
驱动注册
    6)写一个新的驱动文件probe_linux_module.c,其中包含platform_driver结构体中的probe等 ,头文件要包含linux/platform_device.h

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#define DEVICE_NAME "hello_ctl"

static int hello_probe(struct platform_device *pdv){
        printk(KERN_EMERG "probe hello_probe\n");
        return 0;
}

static int hello_remove(struct platform_device *pdv){
        return 0;
}
static int hello_suspend(struct platform_device *pdv){
       // 参数不太正确,这个测试主要看probe,不影响
        return 0;
}
static int hello_resume(struct platform_device *pdv){
        return 0;
}
static void hello_shutdown(struct platform_device *pdv){
        ;
}

struct platform_driver hello_driver = {
        .probe = hello_probe,
        .remove = hello_remove,
        .shutdown = hello_shutdown,
        .suspend = hello_suspend,
        .resume = hello_resume,
        .driver = {
                .name = DEVICE_NAME,
                .owner = THIS_MODULE,
        }
};

static int hello_init(void)
{
        int DriverState;
        printk("init!\n");
        DriverState = platform_driver_register(&hello_driver);
        printk(KERN_EMERG "initialized is %d.\n", DriverState);
        return 0;
}

static void hello_exit(void)
{
        printk("exit!\n");
        platform_driver_unregister(&hello_driver);
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("NANZH");
# Makefile
obj-m += probe_linux_module.o

KDIR := /home/topeet/Android/itop4412/iTop4412_Kernel_3.0

PWD ?= $(shell pwd)

all:
  make -C $(KDIR) M=$(PWD) modules

clean:
  rm -rf *.o

注:Makefile中-C调用的库需要是编译之后的,否则会找不到某些文件。

    7)编译,将ko文件拷贝到板子中执行 

依次打印hello_init中的printk,然后probe,然后hello_init中register之后的内容。
如果设备没有注册,则probe内容不会被打印。
结果在dmesg中查看。(ismod,rmmod)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值