做網(wǎng)站大圖片東莞關(guān)鍵詞排名推廣
目錄
- 1.脈沖編碼器設(shè)備基類(lèi)
- 2.脈沖編碼器設(shè)備基類(lèi)的子類(lèi)
- 3.初始化/構(gòu)造流程
- 3.1設(shè)備驅(qū)動(dòng)層
- 3.2 設(shè)備驅(qū)動(dòng)框架層
- 3.3 設(shè)備io管理層
- 4.總結(jié)
- 5.使用
1.脈沖編碼器設(shè)備基類(lèi)
此層處于設(shè)備驅(qū)動(dòng)框架層。也是抽象類(lèi)。
在/ components / drivers / include / drivers 下的pulse_encoder.h定義了如下脈沖編碼器設(shè)備基類(lèi)
struct rt_pulse_encoder_device
{
struct rt_device parent;
const struct rt_pulse_encoder_ops *ops;
enum rt_pulse_encoder_type type;
};
脈沖編碼器設(shè)備基類(lèi)的方法定義如下
struct rt_pulse_encoder_ops
{
rt_err_t (*init)(struct rt_pulse_encoder_device *pulse_encoder);
rt_int32_t (*get_count)(struct rt_pulse_encoder_device *pulse_encoder);
rt_err_t (*clear_count)(struct rt_pulse_encoder_device *pulse_encoder);
rt_err_t (*control)(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args);
};
抽象出來(lái)共性成為脈沖編碼器設(shè)備基類(lèi)的方法。
2.脈沖編碼器設(shè)備基類(lèi)的子類(lèi)
各個(gè)脈沖編碼設(shè)備基類(lèi)的子類(lèi)已經(jīng)是在bsp的驅(qū)動(dòng)層來(lái)實(shí)現(xiàn)了,例如
/ bsp / stm32 / libraries / HAL_Drivers / drivers 下的drv_pulse_encoder.c定義的stm32脈沖編碼器類(lèi),這些都是可以實(shí)例化的終類(lèi)。其他芯片廠家如此這般一樣。
3.初始化/構(gòu)造流程
以stm32為例,從設(shè)備驅(qū)動(dòng)層、設(shè)備驅(qū)動(dòng)框架層到設(shè)備io管理層從下到上的構(gòu)造/初始化流程如下
3.1設(shè)備驅(qū)動(dòng)層
此層是bsp層,可以實(shí)例化的終類(lèi)地。
c文件:
/ bsp / stm32 / libraries / HAL_Drivers / drivers 下的drv_pulse_encoder.c。
定義了stm32脈沖編碼器類(lèi)
struct stm32_pulse_encoder_device
{
struct rt_pulse_encoder_device pulse_encoder;
TIM_HandleTypeDef tim_handler;
IRQn_Type encoder_irqn;
rt_int32_t over_under_flowcount; char *name;
};
實(shí)例化了stm32的脈沖編碼器設(shè)備:
static struct stm32_pulse_encoder_device stm32_pulse_encoder_obj[] ;
重寫(xiě)了脈沖編碼器設(shè)備基類(lèi)的方法:
static const struct rt_pulse_encoder_ops _ops =
{
.init = pulse_encoder_init,
.get_count = pulse_encoder_get_count,
.clear_count = pulse_encoder_clear_count,
.control = pulse_encoder_control,
};
hw_pulse_encoder_init中開(kāi)啟stm32脈沖編碼器設(shè)備的初始化:
調(diào)用/ components / drivers / misc /pulse_encoder.c的rt_device_pulse_encoder_register函數(shù)來(lái)初始化脈沖編碼器設(shè)備基類(lèi)對(duì)象:
stm32_pulse_encoder_obj[i].pulse_encoder.ops = &_ops;
rt_device_pulse_encoder_register(&stm32_pulse_encoder_obj[i].pulse_encoder, stm32_pulse_encoder_obj[i].name, RT_NULL) ;
注意,重寫(xiě)了脈沖編碼器設(shè)備基類(lèi)的方法。
3.2 設(shè)備驅(qū)動(dòng)框架層
/ components / drivers / misc 下的pulse_encoder.c實(shí)現(xiàn)了設(shè)備驅(qū)動(dòng)框架層接口rt_device_pulse_encoder_register,它是脈沖編碼器設(shè)備驅(qū)動(dòng)框架層的入口,開(kāi)啟脈寬編碼器設(shè)備基類(lèi)的構(gòu)造流程。
它主要重寫(xiě)了脈沖編碼設(shè)備基類(lèi)的父類(lèi)——設(shè)備基類(lèi)——的方法:
#ifdef RT_USING_DEVICE_OPS
device->ops = &pulse_encoder_ops;
#else
device->init = rt_pulse_encoder_init;
device->open = rt_pulse_encoder_open;
device->close = rt_pulse_encoder_close;
device->read = rt_pulse_encoder_read;
device->write = RT_NULL;
device->control = rt_pulse_encoder_control;
#endif
并最終調(diào)用設(shè)備基類(lèi)的初始化/構(gòu)造函數(shù)rt_device_register。
3.3 設(shè)備io管理層
在/ components / drivers / core 下的device.c中實(shí)現(xiàn)了rt_device_register,它是io管理層的入口。
它將stm32 脈沖編碼器設(shè)備對(duì)象放到對(duì)象容器里管理。
4.總結(jié)
整個(gè)設(shè)備對(duì)象的構(gòu)造/初始化流程其實(shí)是對(duì)具體設(shè)備對(duì)象也就是結(jié)構(gòu)體進(jìn)行初始化賦值——它這個(gè)結(jié)構(gòu)體是包含一個(gè)個(gè)的結(jié)構(gòu)體——模擬的是面向?qū)ο蟮睦^承機(jī)制。跟套娃似的,層層進(jìn)行初始化。這樣的好處是什么?每層有每層的初始化(構(gòu)造)函數(shù),就模擬了面向?qū)ο蟮臉?gòu)造函數(shù)——按照先調(diào)用子類(lèi)構(gòu)造/初始化函數(shù),再調(diào)用父類(lèi)的構(gòu)造/初始化函數(shù)方式——其實(shí)也是子類(lèi)構(gòu)造/初始化函數(shù)調(diào)用父類(lèi)構(gòu)造/初始化函數(shù)的流程,來(lái)完成設(shè)備對(duì)象的初始化/構(gòu)造。最終放到對(duì)象容器里來(lái)管理。
這樣的好處是可擴(kuò)展,如搭積木似的,也是對(duì)內(nèi)封閉,對(duì)外開(kāi)放,擴(kuò)展性好,模擬的是面向?qū)ο蟮睦^承多態(tài)機(jī)制。
其實(shí)每個(gè)類(lèi)的注冊(cè)函數(shù)模擬的是面向?qū)ο蟮臉?gòu)造函數(shù)。
5.使用
文檔