单片机开发中最熟悉的就是定时器开发了,定时器有软件和硬件之分,这里我们主要以硬件定时器为主来进行介绍,一般的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如何实现的,感谢阅读~!