• rtc驱动框架 与 新的字符设备驱动注册方式


    首先来了解新的字符设备驱动注册方式。

    对于Linux字符设备驱动注册方式

      2.4及其之前的内核:

                register_chrdev(0,"hello",hello_fops);

                该函数所注册的字符设备是以主设备号为单位的,一个主设备号只能对应一个fops,只能支持256个驱动

      2.4以后的内核  :

                alloc_chrdev_region/register_chrdev_region  /* 如果主设备号为0,用alloc,否则用register  */

                                        /*  主设备号与次设备号一起,用于建立新的设备号区域(devid) */

                                        /* 一个设备区域对应一个fops        */

                cdev_init                   /*  把fops封装成cdev  */

                cdev_add                   /*  建立cdev与设备号devid对应关系  */

                可支持的主设备号有2的12次方个,次设备号有2的20次方个,即4G个驱动

      后面的函数比register_chrdev所支持的字符设备驱动数目大大增多,因此推荐用后面的方法。

     

    rtc,即real-time clock,实时芯片时钟

    一般的计算机系统,当我们关机后,板子上的小电池能保证实时时钟的继续运行,所以开机后会继续显示正确的时间信息。

    rtc驱动就是一个应用了新的字符设备驱动的一个实例。

     

    本驱动基于s3c2440

    rtc驱动起始于drivers\rtc\rtc-s3c.c

    以下为驱动流程

    1.先对对系统总线进行驱动注册,如果发现同名设备则调用probe函数

    2.probe函数内部调用rtc_device_register,其中的参数有底层的操作函数结构体,用于操作rtc寄存器

    3.rtc_device_register函数内部调用

                    rtc_dev_prepare(rtc)    //内部调用cdev_init,

                    rtc_dev_add_device(rtc)   //内部调用cdev_add

    4.rtc内部有成员devid,在另外一个文件(driver/rtc/Rtc-dev.c)用alloc_chrdev_region进行初始化

     其中rtc_device_register就是用于连接上层接口与底层硬件(操作函数)

     

    rtc的open与ioctl调用过程:

     

    app: open("/dev/rtc0");
    -------------------------------------------
    kernel: sys_open
        rtc_dev_fops.open
            rtc_dev_open
                // 根据次设备号找到以前用"rtc_device_register"注册的rtc_device
                struct rtc_device *rtc = container_of(inode->i_cdev,struct rtc_device, char_dev);
                const struct rtc_class_ops *ops = rtc->ops;
                err = ops->open ? ops->open(rtc->dev.parent) : 0;
                               s3c_rtc_open


    app: ioctl(fd, RTC_RD_TIME,...)
    -------------------------------------------
        kernel: sys_ioctl
            rtc_dev_fops.ioctl
                rtc_dev_ioctl
                      struct rtc_device *rtc = file->private_data;
                      rtc_read_time(rtc, &tm);
                          err = rtc->ops->read_time(rtc->dev.parent, tm);
                                      s3c_rtc_gettime

     

    由于mini2440板子默认是没有设置rtc设备的,当驱动通过总线去寻找同名设备的时候会没法找到,因此驱动无法使用

    所以,需要修改内核:

    首先  

    修改arch\arm\plat-s3c24xx\common-smdk.c
    static struct platform_device __initdata *smdk_devs[] = {
    &s3c_device_nand,
    &smdk_led4,
    &smdk_led5,
    &smdk_led6,
    &smdk_led7,
    改为(在数组smdk_devs里加上s3c_device_rtc):
    static struct platform_device __initdata *smdk_devs[] = {
    &s3c_device_nand,
    &smdk_led4,
    &smdk_led5,
    &smdk_led6,
    &smdk_led7,
    &s3c_device_rtc,

     

    然后  make uImage

    最后   使用新内核启动

     

    测试:

    ls /dev/rtc* -l

    date /* 显示系统时间 */
    date 112916302012.30 /* 设置系统时间 date [MMDDhhmm[[CC]YY][.ss]] */
    hwclock -w /* 把系统时间写入RTC */

    短电,重启,执行date

  • 相关阅读:
    Android组件化框架设计与实践
    浅谈Android进阶之路
    Android APP 性能优化的一些思考
    有关 Hybrid 开发模式实践总结
    开发人员必备的技能——单元测试
    有关Android插件化思考
    人生的意义到底是什么?
    Asp.Net Core 3.1学习-读取、监听json配置文件(7)
    Asp.Net Core 3.1学习-依赖注入、服务生命周期(6)
    Asp.Net Core 3.1学习- 应用程序的启动过程(5)
  • 原文地址:https://www.cnblogs.com/TaigaCon/p/2795124.html
Copyright © 2020-2023  润新知