RT-Thread 4.0.0

访问硬件定时器设备

应用程序通过 RT-Thread 提供的 I/O 设备管理接口来访问硬件定时器设备,相关接口如下所示:

函数 描述
rt_device_find() 查找定时器设备
rt_device_open() 以读写方式打开定时器设备
rt_device_set_rx_indicate() 设置超时回调函数
rt_device_control() 控制定时器设备,可以设置定时模式(单次/周期)/计数频率,或者停止定时器
rt_device_write() 设置定时器超时值,定时器随即启动
rt_device_read() 获取定时器当前值
rt_device_close() 关闭定时器设备

RT-Thread 提供的 I/O 设备硬件定时器,示例仅提供最通用简单的定时功能,其他定时器高级功能需自行在control中添加;

下面对基于CubeMX、Hal库的BSP的硬件定时器的使用做简单描述。

配置CubeMX

配置之后生成代码,

在 stm32f4xx_hal_conf.h 中 会实现 hal模块驱动

#define HAL_TIM_MODULE_ENABLED

修改工程目录下的 Kconfig

在 Kconfig 中添加对 TIM的支持

    menuconfig BSP_USING_TIM
bool "Enable Hardware TIM"
default n
select RT_USING_HWTIMER
if BSP_USING_TIM
config BSP_USING_TIM1
bool "Enable TIM1"
default n config BSP_USING_TIM2
bool "Enable TIM2"
default n config BSP_USING_TIM3
bool "Enable TIM3"
default n config BSP_USING_TIM4
bool "Enable TIM4"
default n config BSP_USING_TIM5
bool "Enable TIM5"
default n config BSP_USING_TIM6
bool "Enable TIM6"
default n

然后使用Env工具 menuconfig 中使能 TIM3、TIM4

然后 scons --target=mdk5

用keil打开工程后在 tim_config.h 中 添加 TIM3、TIM4的配置

#ifdef BSP_USING_TIM3
#ifndef TIM3_CONFIG
#define TIM3_CONFIG \
{ \
.tim_handle.Instance = TIM3, \
.tim_irqn = TIM3_IRQn, \
.name = "timer3", \
}
#endif /* TIM3_CONFIG */
#endif /* BSP_USING_TIM3 */ #ifdef BSP_USING_TIM4
#ifndef TIM4_CONFIG
#define TIM4_CONFIG \
{ \
.tim_handle.Instance = TIM4, \
.tim_irqn = TIM4_IRQn, \
.name = "timer4", \
}
#endif /* TIM4_CONFIG */
#endif /* BSP_USING_TIM4 */

然后就可以在应用中直接操作设备名为 "timer3" 和 "timer4" 的设备了。

设备驱动分析

定时器设备 I/O 实现

hwtimer.c  hwtimer.h

定时器底层驱动实现(操作Hal库)

drv_hwtimer.c  drv_hwtimer.h

下面主要追踪以下定时器设备的注册及其初始化

在 drv_hwtimer.c 中  定时器自动初始化,并注册设备

static int stm32_hwtimer_init(void)

INIT_BOARD_EXPORT(stm32_hwtimer_init);

其中 hwtimer_ops.rt_hwtimer_init 会 调用 timer_init

static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
{
uint32_t prescaler_value = ;
TIM_HandleTypeDef *tim = RT_NULL;
struct stm32_hwtimer *tim_device = RT_NULL; RT_ASSERT(timer != RT_NULL);
if (state)
{
tim = (TIM_HandleTypeDef *)timer->parent.user_data;
tim_device = (struct stm32_hwtimer *)timer; /* time init */
#if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
if (tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11)
#elif defined(SOC_SERIES_STM32L4)
if (tim->Instance == TIM15 || tim->Instance == TIM16 || tim->Instance == TIM17)
#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0)
if ()
#endif
{
#ifndef SOC_SERIES_STM32F0
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK2Freq() * / ) - ;
#endif
}
else
{
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK1Freq() * / ) - ;
}
tim->Init.Period = - ;
tim->Init.Prescaler = prescaler_value;
tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (timer->info->cntmode == HWTIMER_CNTMODE_UP)
{
tim->Init.CounterMode = TIM_COUNTERMODE_UP;
}
else
{
tim->Init.CounterMode = TIM_COUNTERMODE_DOWN;
}
tim->Init.RepetitionCounter = ;
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0)
tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
#endif
if (HAL_TIM_Base_Init(tim) != HAL_OK)
{
LOG_E("%s init failed", tim_device->name);
return;
}
else
{
/* set the TIMx priority */
HAL_NVIC_SetPriority(tim_device->tim_irqn, , ); /* enable the TIMx global Interrupt */
HAL_NVIC_EnableIRQ(tim_device->tim_irqn); /* clear update flag */
__HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);
/* enable update request source */
__HAL_TIM_URS_ENABLE(tim); LOG_D("%s init success", tim_device->name);
}
}
}

我们发现之前设置的配置并没有使用,而是直接默认设置成频率10K,周期1s的定时器;

可根据情况后面用control修改,或注释掉 tim->Init. 的几条赋值语句,使用 user_data 传递过来的默认配置;

同时 stm32f4xx_hal_msp.c 中的TIM硬件初始化,也仅仅只是打开TIM外设时钟,所有锁CubeMX中只要使能对应TIM即可,无需配置;

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspInit 0 */ /* USER CODE END TIM3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM3_CLK_ENABLE();
/* USER CODE BEGIN TIM3_MspInit 1 */ /* USER CODE END TIM3_MspInit 1 */
}
else if(htim_base->Instance==TIM4)
{
/* USER CODE BEGIN TIM4_MspInit 0 */ /* USER CODE END TIM4_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM4_CLK_ENABLE();
/* USER CODE BEGIN TIM4_MspInit 1 */ /* USER CODE END TIM4_MspInit 1 */
} }

RT-Thread 设备驱动-硬件定时器浅析与使用的更多相关文章

  1. RT thread 设备驱动组件之USART设备

    本文以stm32f4xx平台介绍串口驱动,主要目的是:1.RTT中如何编写中断处理程序:2.如何编写RTT设备驱动接口代码:3.了解串行设备的常见处理机制.所涉及的主要源码文件有:驱动框架文件(usa ...

  2. Linux设备驱动——内核定时器

    内核定时器使用 内核定时器是内核用来控制在未来某个时间点(基于jiffies)调度执行某个函数的一种机制,其实现位于 <Linux/timer.h> 和 kernel/timer.c 文件 ...

  3. 蜕变成蝶~Linux设备驱动之按键设备驱动

    在上述的驱动系列博客中,我们已经了解了关于阻塞和非阻塞.异步通知.轮询.内存和I/O口访问.并发控制等知识,按键设备驱动相对来说是比较简单的,本章内容可以加深我们对字符设备驱动架构.阻塞与非阻塞.中断 ...

  4. Linux设备驱动中的阻塞和非阻塞I/O <转载>

    Green 博客园 首页 新随笔 联系 订阅 管理 Linux设备驱动中的阻塞和非阻塞I/O   [基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件 ...

  5. RTT设备与驱动之硬件定时器

    硬件定时器可以对外部时钟进行计数,利用内部时钟进行定时. 函数 描述 rt_device_t rt_device_find(const char* name); 查找定时器设备 rt_err_t rt ...

  6. RT Thread的SPI设备驱动框架的使用以及内部机制分析

    注释:这是19年初的博客,写得很一般,理解不到位也不全面.19年末得空时又重新看了RTThread的SPI和GPIO,这次理解得比较深刻.有时间时再整理上传. -------------------- ...

  7. 蜕变成蝶~Linux设备驱动之中断与定时器

    “我叮咛你的 你说 不会遗忘 你告诉我的 我也全部珍藏 对于我们来说 记忆是飘不落的日子 永远不会发黄 相聚的时候 总是很短 期待的时候 总是很长 岁月的溪水边 捡拾起多少闪亮的诗行 如果你要想念我  ...

  8. 【Linux开发】linux设备驱动归纳总结(七):2.内核定时器

    linux设备驱动归纳总结(七):2.内核定时器 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  9. linux设备驱动归纳总结(五):3.操作硬件——IO静态映射【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-83299.html linux设备驱动归纳总结(五):3.操作硬件——IO静态映射 xxxxxxxxx ...

随机推荐

  1. idea导入(import)项目和打开(open)项目的区别

    前言: 每次接手老项目,都得从git或svn下载下来,但是如果之前的项目不是用idea写的怎么办,可是你又习惯啦idea,那你必须把项目在idea上跑起来,那是用import还是用open呢,如何抉择 ...

  2. fread了解一下

    神奇读入挂^_^ 记得加头文件#include const int BufferSize=100*1000; char buffer[BufferSize],*head,*tail; bool not ...

  3. 创建Django项目(六)——模板

    2013-08-07 22:42:30|           1.设置模板路径         打开 settings.py 文件,修改 TEMPLATE_DIRS 内容,指向模板存放的绝对路径,而不 ...

  4. Ubuntu 16.04 GNOME无法使用拼音输入法问题

    说明:添加好之后重启!不然会出现输入错乱的问题. 参考: http://forum.ubuntu.org.cn/viewtopic.php?t=477765

  5. Maven公共仓库/镜像站收集及使用技巧

    查询: 1.http://search.maven.org/ 2.https://mvnrepository.com/ 3.https://maven-repository.com/ 4.(阿里云镜像 ...

  6. 详细图解mongodb 3.4.1 win7x64安装

    原文:http://www.cnblogs.com/yucongblog/p/6895983.html 详细图解,记录 win7 64 安装mongo数据库的过程.安装的版本是 MongoDB-win ...

  7. 解决Vue打包后背景图片路径错误问题

    1.原因解析 当用vue-cli自动构建项目后,有两种运行方法,分别是: npm run dev : 提供一个开发的环境,自动热更新,资源使用绝对路径,所以可以正常看到背景图片. npm run bu ...

  8. hdu oj 1285 确定比赛名次

    hdu oj 1285 确定比赛名次 题目: 确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  9. powershell 的版本号所引起的载入 FSharp 编译器问题

    powershell 的版本号所引起的载入 FSharp 编译器问题 在 64 位的系统下,大部分系统文件都有 64 位和 32 位的版本号:通常在C:\WINDOWS\system32 下的是 64 ...

  10. 【Swift】学习笔记(二)——基本运算符

    运算符是编程中用得最多的,其包含一元,二元和三元 三种运算符.swift也和其他编程语言一样基本就那些,以下总结一下,也有它特有的运算符.比方区间运算符 1.一元运算符 =   赋值运算符,用得最多的 ...