本文主要是介绍rtt的io设备框架面向对象学习-硬件rtc设备,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
- 1.硬件rtc设备基类
- 2.硬件rtc设备基类的子类
- 3.初始化/构造流程
- 3.1设备驱动层
- 3.2 设备驱动框架层
- 3.3 设备io管理层
- 4.总结
- 5.使用
硬件rtc和软件rtc设备是互斥的。因为它们的名字都叫"rtc",在对象容器中不允许重名。
1.硬件rtc设备基类
此层处于设备驱动框架层。此层的类是抽象类。
在/ components / drivers / include / drivers 下的rtc.h定义了如下rtc设备基类
typedef struct rt_rtc_device
{
struct rt_device parent;
const struct rt_rtc_ops *ops;
} rt_rtc_dev_t;
rtc设备基类继承自设备基类,然后增加私有方法成为新的类——rtc设备基类。
rtc设备基类的方法定义如下
struct rt_rtc_ops
{
rt_err_t (*init)(void);
rt_err_t (*get_secs)(time_t *sec);
rt_err_t (*set_secs)(time_t *sec);
rt_err_t (*get_alarm)(struct rt_rtc_wkalarm *alarm);
rt_err_t (*set_alarm)(struct rt_rtc_wkalarm *alarm);
rt_err_t (*get_timeval)(struct timeval *tv);
rt_err_t (*set_timeval)(struct timeval *tv);
};
2.硬件rtc设备基类的子类
此层是设备驱动层,此类是实现类,由各个bsp实现。例如
/ bsp / stm32 / libraries / HAL_Drivers / drivers 下的drv_rtc.c定义的stm32 rtc类。
其他芯片厂家如此这般一样。
3.初始化/构造流程
以stm32为例,从设备驱动层、设备驱动框架层到设备io管理层从下到上的构造/初始化流程如下
3.1设备驱动层
此层是bsp层,可以实例化的终类地。
文件:
/ bsp / stm32 / libraries / HAL_Drivers / drivers 下的drv_rtc.c。
定义了stm32的硬件rtc设备类
struct rtc_device_object
{
rt_rtc_dev_t rtc_dev;
#ifdef RT_USING_ALARM
struct rt_rtc_wkalarm wkalarm;
#endif
};
stm32的硬件rtc设备类继承自rtc设备基类,如果menuconfig开启了rtc的闹钟,还得加上闹钟结构体。
struct rt_rtc_wkalarm
{
rt_bool_t enable; /* 0 = alarm disabled, 1 = alarm enabled /
rt_int32_t tm_sec; / alarm at tm_sec /
rt_int32_t tm_min; / alarm at tm_min /
rt_int32_t tm_hour; / alarm at tm_hour /
rt_int32_t tm_mday; / alarm at tm_mday /
rt_int32_t tm_mon; / alarm at tm_mon /
rt_int32_t tm_year; / alarm at tm_year */
};
实例化了stm32的硬件rtc设备:
static struct rtc_device_object rtc_device;
只有一个rtc设备对象,只支持一个rtc。
重写了硬件rtc设备基类的方法:
static const struct rt_rtc_ops stm32_rtc_ops =
{
stm32_rtc_init,
stm32_rtc_get_secs,
stm32_rtc_set_secs,
stm32_rtc_get_alarm,
stm32_rtc_set_alarm,
stm32_rtc_get_timeval,
RT_NULL,
};
int rt_hw_rtc_init中开启stm32的硬件rtc设备的初始化:
重写rtc设备基类的方法
rtc_device.rtc_dev.ops = &stm32_rtc_ops;
然后调用/ components / drivers /rtc/rtc.c的rt_hw_rtc_register对rtc设备基类进行初始化。
rt_hw_rtc_register(&rtc_device.rtc_dev, “rtc”, RT_DEVICE_FLAG_RDWR, RT_NULL);
3.2 设备驱动框架层
/ components / drivers /rtc 下的rtc.c实现了设备驱动框架层接口rt_hw_rtc_register,是硬件rtc设备驱动框架层的入口,开启rtc设备基类的构造/初始化流程。
该层重写了rtc设备基类的父类——设备基类——的方法:
#ifdef RT_USING_DEVICE_OPS
device->ops = &rtc_core_ops;
#else
device->init = rt_rtc_init;
device->open = rt_rtc_open;
device->close = rt_rtc_close;
device->read = RT_NULL;
device->write = RT_NULL;
device->control = rt_rtc_control;
#endif /* RT_USING_DEVICE_OPS */
并最终调用设备基类的构造函rt_device_register。
3.3 设备io管理层
在/ components / drivers / core 下的device.c中实现了rt_device_register,它是io管理层的入口。
它将stm32 硬件rtc设备对象放到对象容器里管理。
4.总结
整个设备对象的构造/初始化流程其实是对具体设备对象也就是结构体进行初始化赋值——它这个结构体是包含一个个的结构体——模拟的是面向对象的继承机制。跟套娃似的,层层进行初始化。这样的好处是什么?每层有每层的初始化(构造)函数,就模拟了面向对象的构造函数——按照先调用子类构造/初始化函数,再调用父类的构造/初始化函数方式——其实也是子类构造/初始化函数调用父类构造/初始化函数的流程,来完成设备对象的初始化/构造。最终放到对象容器里来管理。
这样的好处是可扩展,如搭积木似的,也是对内封闭,对外开放,扩展性好,模拟的是面向对象的继承多态机制。
其实每个类的注册函数模拟的是面向对象的构造函数。
5.使用
文档
这篇关于rtt的io设备框架面向对象学习-硬件rtc设备的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!