美文网首页
itop4412驱动笔记1

itop4412驱动笔记1

作者: 嵌入式工作 | 来源:发表于2018-08-04 15:03 被阅读0次

    总纲

    image.png

    1. 物理地址找到虚拟地址方法(ioremap)

    2.cpu性能

    -ARM7 处理速度为0.9MIPS/MHz, 常见的主时钟一般为20MHz-133MHz
    – ARM9 处理速度为1.1MIPS/MHz, 常见的主时钟一般为100MHz-233MHz
    – CORTEX-A9 处理速度2.5 MIPS/MHz ,主时钟一般为1000MHz-1600MHz

    3.最简Linux驱动

    • Linux头文件位置
    include <linux/module.h>
    include <linux/init.h>

    – 入口函数module_init(x)
    – 出口函数module_exit(x)

    – MODULE_LICENSE("Dual BSD/GPL")添加遵循GPL协议,必须的!
    – MODULE_AUTHOR(“kerwin”)代码作者
    打印信息

    printk(KERN_EMERG "Hello World enter!\n");

    Makefile编写

    #通知编译器我们要编译模块的哪些源码
    #这里是编译itop4412_hello.c这个文件编译成中间文件itop4412_hello.o
    obj-m += mini_linux_module.o 
    
    #源码目录变量,这里用户需要根据实际情况选择路径
    #作者是将Linux的源码拷贝到目录/home/topeet/android4.0下并解压的
    KDIR := /home/topeet/android4.0/iTop4412_Kernel_3.0
    
    #当前目录变量
    PWD ?= $(shell pwd)
    
    #make命名默认寻找第一个目标
    #make -C就是指调用执行的路径
    #$(KDIR)Linux源码目录,作者这里指的是/home/topeet/android4.0/iTop4412_Kernel_3.0
    #$(PWD)当前目录变量
    #modules要执行的操作
    all:
        make -C $(KDIR) M=$(PWD) modules
            
    #make clean执行的操作是删除后缀为o的文件
    clean:
        rm -rf *.o
    

    4,kconfig makefile

    4.1kconfig文件,配置宏vim drivers/char/Kconfig

    config LEDS_CTL
            bool "Enable LEDS config"
            default y
            help
              Enable LEDS config
    

    4.2makeconfig文件,根据宏,添加源码

    vim drivers/char/Makefile

    obj-$(CONFIG_LEDS_CTL)          += itop4412_leds.o
    

    5.总线设备驱动注册流程

    一般的驱动是先注册设备再注册驱动
    热插拔的设备是先注册驱动后注册设备

    查看总线 ls /sys/bus 里面可以看到platform 总线
    查看设备号 cat /proc/devices

    5.1.设备注册方法

    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;
    };
    
    #define platform_get_device_id(pdev)    ((pdev)->id_entry)
    
    #define to_platform_device(x) container_of((x), struct platform_device, dev)
    
    extern int platform_device_register(struct platform_device *);
    extern void platform_device_unregister(struct platform_device *);
    

    注册设备。将设备结构体放到平台文件中,会自动注册设备,不用去调
    用注册设备的函数

    vim arch/arm/mach-exynos/mach-itop4412.c

    #ifdef CONFIG_HELLO_CTL
    struct platform_device s3c_device_hello_ctl =
    {
    .name = "hello",
    .id = -1,
    };
    #endif
    
    

    注册完之后在虚拟平台总线下可以查到注册的设备
    – ls /sys/devices/platform/

    5.2.驱动注册方法

    驱动注册使用结构体platform_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;
    };
    
    extern int platform_driver_register(struct platform_driver *);
    extern void platform_driver_unregister(struct platform_driver *);
    

    probe函数
    – platform_match函数匹配之后,驱动调用的初始化函数
    • remove函数
    – 移除驱动函数
    • suspend函数
    – 悬挂(休眠)驱动函数
    device_driver数据结构的两个参数
    – name和注册的设备name要一致
    – owner一般赋值THIS_MODULE

    #include <linux/init.h>
    #include <linux/module.h>
    
    
    /*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
    #include <linux/platform_device.h>
    
    #define DRIVER_NAME "hello"  //必须和设备注册的一致
    
    MODULE_LICENSE("Dual BSD/GPL");
    MODULE_AUTHOR("TOPEET");
    
    
    int hello_probe(struct platform_device *pdev)
    {
      printk(KERN_EMERG "hello_probe call \n");
      return 0;
      
    }
    
    int hello_remove(struct platform_device *pdev)
    {
        printk(KERN_EMERG"remove call \n");
        return 0;
    }
    void hello_shutdown(struct platform_device *pdev)
    {
       printk(KERN_EMERG"shutdown call \n");
    }
    int hello_suspend(struct platform_device *pdev, pm_message_t state)
    {
         printk(KERN_EMERG"suspend call \n");
        return 0;
    }
    int hello_resume(struct platform_device * pdev)
    {
        
         printk(KERN_EMERG"resume call \n");
        return 0;
    }
    
    struct platform_driver  stu_hello={
            .probe=hello_probe,
            .remove=hello_remove,
            .shutdown=hello_shutdown,
            .suspend=hello_suspend,
            .resume=hello_resume,
           .driver={
               .name = DRIVER_NAME,
               .owner = THIS_MODULE,
           },
        
    };
    
    static int hello_init(void)
    {
        int err;
        printk(KERN_EMERG "hello world enter\n");
        err=platform_driver_register(&stu_hello);
         printk(KERN_EMERG "register result:%d\n",err);
        return 0;
    }
    
    static void hello_exit(void)
    {
        printk(KERN_EMERG "hello world exit\n");
        platform_driver_unregister(&stu_hello);
    
    }
    module_init(hello_init);
    module_exit(hello_exit);
    
    
    
    

    相关文章

      网友评论

          本文标题:itop4412驱动笔记1

          本文链接:https://www.haomeiwen.com/subject/qgapvftx.html