單片機開發中最熟悉的就是定時器開發了,定時器有軟件和硬件之分,這里我們主要以硬件定時器為主來進行介紹,一般的MCU都有3~15個不等的硬件定時器,HWTIMER(Hardware Timer)設備驅動開發主要是講硬件定時器外設功能對街道設備框架上。先來看下HWTIMER設備驅動 框架的層級結構:
這里最主要是要理解兩層的概念,HWTIMER設備驅動框架層,這是一層通用的軟件抽象層,與具體的硬件無關,框架代碼為hwtimer.c,提供以下功能:
- 向I/O設備管理層提供統一的接口供其調用。
- 向設備驅動層提供具體的設備操作方法入口(函數指針)由其進行實現。
- 提供注冊接口管理API,讓驅動層與框架層產生聯系。 我們具體要實現的事HWTIMER設備驅動層,一般命名為drv_hwtimer.c,也就是構架中紅線的部分。
接下來創建一個HWTIMER設備,這個設備對象要與構架產生了聯系,所以必須由rt_hwtimer_device結構中派生出新的對象:
struct stm32_hwtimer
{
rt_hwtimer_t time_device; /*HWTIMER設備基類*/
TIM_HandleTypeDef tim_handle; /*STM32定時器控制句柄*/
IRQn_Type tim_irqn; /*STM32定時器中斷類型*/
char *name; /*STM32定時器名稱*/
};
MCU一般不會只開一個定時器,以最常用的需要開多個定時器為例,所以我們實現上要建立的也是一個定時器列表:
#ifdef BSP_USING_TIM1
#ifndef TIM1_CONFIG
#define TIM1_CONFIG \
{ \
.tim_handle.Instance = TIM1, \
.tim_irqn = TIM1_IRQn, \
.name = "timer1", \
}
#endif /* TIM1_CONFIG */
#endif /* BSP_USING_TIM1 */
static struct stm32_hwtimer stm32_hwtimer_obj[] =
{
#ifdef BSP_USING_TIM1
TIM1_CONFIG,
#endif
#ifdef BSP_USING_TIM2
TIM2_CONFIG,
#endif
#ifdef BSP_USING_TIM3
TIM3_CONFIG,
#endif
#ifdef BSP_USING_TIM4
TIM4_CONFIG,
#endif
......
}
這里并沒有初始化stm32_hwtimer_obj對象的所有字段,它并不完整,需要再后續的開發中進行賦值比如調用ops中相應函數進行進一步的初始化:
struct rt_hwtimer_ops
{
void (*init)(struct rt_hwtimer_device *timer, rt_uint32_t state);
rt_err_t (*start)(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode);
void (*stop)(struct rt_hwtimer_device *timer);
rt_uint32_t (*count_get)(struct rt_hwtimer_device *timer);
rt_err_t (*control)(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args);
};
真正的驅動開始需要實例化這些ops,下篇詳細講解關于ops如何實現的,感謝閱讀~!