RTC模块驱动开发总结

一、RTC模块驱动开发

1、RTC模块的设备驱动模型


 
2、I2C模块的驱动模型

           
   
 
 
   
 

 RTC模块驱动开发总结_第1张图片


3、RTC模块涉及的文件和数据结构

(1)、相关的文件:

     934x.c :该文件为系统的硬件平台文件,定义了RTC模块用到的硬件资源,包括内存地址空间,GPIO,中断资源,并将RTC设备注册进内核的设备链表中。

    rtc-ds1307.c:该文件为RTC模块的设备驱动文件,实现了对RTC硬件的操作接口,并将该设备驱动注册进内核的设备驱动链表中。

/driver/rtc/class.c:该文件实现RTC设备驱动模型的核心,包括创建rtc类,注册rtc设备

/driver/rtc/rtc-dev.c:该文件初始化一个file_operation,并实现结构体内的函数

/driver/rtc/interface.h:该文件实现file_operation中ioctl中对应命令的函数实现。

/driver/rtc/rtc-sysfs.c:该文件主要实现和sysfs相关的操作,在sysfs目录下创建设备属性组。

/driver/rtc/rtc-proc.c:该文件提供RTC的proc文件系统接口。

   i2c-gpio.c :该文件为GPIO模拟I2C适配器的设备驱动文件,实现了对I2C适配器的操作接口,并将该I2C适配器的驱动注册进内核,

  i2c-core.c :该文件是i2c的核心,提供i2c模块相关的公共接口,包括i2c设备注册 i2c适配器注册,以及和文件系统相关的操作。

  i2c-algo-bit.c :该文件时I2C协议的实现,通过该文件提供的接口,完成对I2C设备的访问。

     gpio.c: 该文件实现了对GPIO的操作接口,包括对GPIO的配置,读写操作。

gpiolib.c: 该文件实现了和GPIO相关的接口。

(2)、RTC模块涉及的数据结构:

//RTC设备

  struct rtc_device  

  {  

      struct device dev;  

      struct module *owner;  

         int id;  

      char name[RTC_DEVICE_NAME_SIZE]; 

      const struct rtc_class_ops *ops;  

      struct mutex ops_lock;  

      struct cdev char_dev;  

     unsigned long flags;  

     unsigned long irq_data;  

     spinlock_t irq_lock;  

     wait_queue_head_t irq_queue;  

      struct fasync_struct *async_queue;  

      struct rtc_task *irq_task;  

     spinlock_t irq_task_lock;  

      int irq_freq;  

      int max_user_freq;  

 #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL   

      struct work_struct uie_task;  

      struct timer_list uie_timer;  

     /* Those fields are protected by rtc->irq_lock */  

     unsigned int oldsecs;  

     unsigned int uie_irq_active:1;  

     unsigned int stop_uie_polling:1;  

     unsigned int uie_task_active:1;  

     unsigned int uie_timer_active:1;  

  #endif   

  };

//RTC设备的操作接口

struct rtc_class_ops {

    int (*open)(structdevice *);

    void (*release)(structdevice *);

    int (*ioctl)(struct device *, unsigned int, unsigned long);

    int (*read_time)(struct device *, struct rtc_time *);

    int(*set_time)(struct device *, struct rtc_time *);

    int (*read_alarm)(struct device *, struct rtc_wkalrm *);

    int(*set_alarm)(struct device *, struct rtc_wkalrm *);

    int (*proc)(structdevice *, struct seq_file *);

    int (*set_mmss)(structdevice *, unsigned long secs);

    int(*irq_set_state)(struct device *, int enabled);

    int(*irq_set_freq)(struct device *, int freq);

    int(*read_callback)(struct device *, int data);

    int(*alarm_irq_enable)(struct device *, unsigned int enabled);

    int(*update_irq_enable)(struct device *, unsigned int enabled);

};

//代表了时间与日期,从RTC设备读回的时间和日期就保存在这个结构体中

 struct rtc_time 

{   int tm_sec;  

       int tm_min;  

       int tm_hour;  

       int tm_mday;  

       int tm_mon;  

       int tm_year;  

       int tm_wday;  

       int tm_yday;  

       int tm_isdst;  

};  

(3)、I2C模块涉及的数据结构

    //记录i2c设备的信息

    struct i2c_board_info {

    char     type[I2C_NAME_SIZE];//I2C_client芯片的型号

    unsigned short    flags;//I2C_client的标志位

    unsigned short    addr;//I2C_client的地址

    void     *platform_data;//I2C_client的平台数据

    struct dev_archdata   *archdata;// I2C_client的物理数据

    int      irq;//中断

};

//记录i2c总线适配器的平台信息

struct i2c_gpio_platform_data {

    unsigned int sda_pin;

    unsigned int scl_pin;

    int      udelay;

    int      timeout;

    unsigned int sda_is_open_drain:1;

    unsigned int scl_is_open_drain:1;

    unsigned int scl_is_output_only:1;

};

//i2c设备驱动

struct i2c_driver {

    int id;

    unsigned int class;

    int(*attach_adapter)(struct i2c_adapter *);

    int (*detach_adapter)(structi2c_adapter *);

    /* Standard drivermodel interfaces */

    int (*probe)(struct i2c_client *, const struct i2c_device_id *);

    int(*remove)(struct i2c_client *);

    /* driver modelinterfaces that don't relate to enumeration */

    void (*shutdown)(structi2c_client *);

    int (*suspend)(structi2c_client *, pm_message_t mesg);

    int (*resume)(structi2c_client *);

    int (*command)(structi2c_client *client, unsigned int cmd, void *arg);

    struct device_driver driver;

    const struct i2c_device_id *id_table;

    /* Device detectioncallback for automatic device creation */

    int (*detect)(structi2c_client *, int kind, struct i2c_board_info *);

    const structi2c_client_address_data *address_data;

    struct list_headclients;

};

 

//I2C总线的协议算法实现

struct i2c_algorithm {

    int(*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);

    int (*smbus_xfer)(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write,

                u8 command, int size, union i2c_smbus_data*data);

    u32 (*functionality)(struct i2c_adapter *);

};

//i2c总线适配器

struct i2c_adapter {

    struct module *owner;

    unsigned intid;

    unsigned int class;        /* classes to allow probing for */

    const struct i2c_algorithm *algo; /* the algorithm to access thebus */

    void *algo_data;

    /* data fields that arevalid for all devices   */

    u8 level;             /* nesting level for lockdep */

    struct mutex bus_lock;

    int timeout;          /* in jiffies */

    int retries;

    struct device dev;        /* the adapter device */

    int nr;

    char name[48];

    struct completiondev_released;

};

//GPIO控制器

struct gpio_chip {

    const char        *label;

    struct device         *dev;

    struct module         *owner;

    int (*request)(struct gpio_chip*chip,unsigned offset);

    void (*free)(struct gpio_chip *chip,unsignedoffset);

    int (*direction_input)(struct gpio_chip*chip,unsigned offset);

    int (*get)(struct gpio_chip *chip,unsigned offset);

    int (*direction_output)(structgpio_chip *chip,unsigned offset, int value);

    void (*set)(struct gpio_chip *chip,unsigned offset,int value);

    int (*to_irq)(struct gpio_chip*chip,unsigned offset);

    void (*dbg_show)(struct seq_file *s,structgpio_chip *chip);

    int          base;

    u16          ngpio;

    char         **names;

    unsigned     can_sleep:1;

    unsigned     exported:1;

};

4、RTC模块驱动重要代码和流程分析

(1)代码分析:参见SVN源码,注释处有声明

    rtc-dev.c-->interface.c-->rtc-ds1307

 

    rtc-dev.c: 该文件最终生成/dev/rtc,为应用层提供操作RTC的标准接口

    interface.c:接口文件,对驱动接口进行封装,给上层提供统一的接口,屏蔽芯片的差异性。

    rtc-ds1307.c:直接和硬件交互的驱动接口的文件

    class.c:提供子RTC子系统一些公共函数,将RTC驱动注册集成到linux内核中,是一个粘合剂。

    hctosys.c:系统起来后,读RTC硬件中的时间,更新系统时间。

   

      2.函数的实现

       

    (2)流程分析:

设备端: 定义并初始化RTC设备结构体,并将其注册进内核设备链表中,(设备的类型和地址)

        定义并初始化I2C总线适配器的结构体,并以平台设备注册进内核的设备链表中,

 

设备驱动端:实现对RTC设备的操作接口,定义并初始化RTC设备驱动结构体,注册进内核设备驱动链表,匹配设备和驱动,成功后调用设备初始化函数对设备进行初始化。

 

 

5、开发过程中遇到的问题

(1)对GPIO配置的问题

   GPIO的IO基地址设置错误,GPIO的function寄存器未设置。

(2)对I2C适配器参数设置的问题,(使用硬件资源的配置,硬件参数配置、延迟和超时的配置,满足I2C协议和硬件特性的要求)


你可能感兴趣的:(驱动开发,框架和结构分析)