对STM32 HAL库的一些思考(二)__weak关键字和systick
来源:互联网 发布:中航工业津电 知乎 编辑:程序博客网 时间:2024/06/05 10:04
__weak
关键字
有时候我们阅读HAL源码的时候会发现,很多函数前会有一个__weak
的前缀,一开始我对这个前缀很好奇,想知道这到底是什么意思。在IAR for ARM中使用“go to defination”查看该关键字的时候会提示__weak defined on the command line
,即在命令行中定义,得,这又回到原点了……
不过一次偶然的机会,在查找C语言相关资料时,我看到它的真实含义,该关键字用于函数前,编译器在链接函数时会优先链接没有该关键字前缀的函数,即变相的,而且是不完全的实现了C++的函数重载特性,示例:
//HAL库微秒延时函数,有__weak关键字即代表可以重载该函数__weak HAL_Delay(__IO uint32_t delay);//用户函数HAL_Delay(__IO uint32_t delay);
以上两个函数,编译器会优先链接下面的函数,即为我们重定义延时函数提供了较大的便利性。
Systick定时器
了解ARM的人对Systick定时器一定不陌生,这是内核自带的定时器,不过我更喜欢称它为心跳定时器,一般在裸机开发时,由它提供整个内核的时基信号,当然也可以替换为外围的定时器,这一点可以在STM32CubeMX中得到验证,此处不赘述。
不过为什么要把systick和__weak
关键字扯在一起呢?这当然是有原因的。
如果有阅读过HAL库中关于cortex部分的源码,你会发现关于心跳定时器的每一个函数前都有__weak
关键字,以STM32F407为例,这部分源码在stm32f4xx_hal.h/.c和stm32f4xx_hal_cortex.h/.c中,之前网上有很多修改Tick的初始化以达到使HAL_Delay()
函数可以进行微秒级延时的例子,这里不多说这种方法,只是阐述一下HAL_Delay()
的延时原理。
Tick的默认初始化
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority){ /*Configure the SysTick to have interrupt in 1ms time basis*/ HAL_SYSTICK_Config(SystemCoreClock/1000U); /*Configure the SysTick IRQ priority */ HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); /* Return function status */ return HAL_OK;}
经过此函数,心跳定时器被初始化为1ms的时基单元,即每毫秒进入一次Systick中断
Systick中断及其回调函数
/** * stm32f4_it.c **/void SysTick_Handler(void){ /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); HAL_SYSTICK_IRQHandler(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */}/** * stm32f4xx_hal.c * uwTick是一个全局变量,在该文件中定义**/__weak void HAL_IncTick(void){ uwTick++;}
即每毫秒uwTick加一,用于计算Systick产生的节拍数
获取当前节拍
/** * stm32f4xx_hal.c * uwTick是一个全局变量,在该文件中定义**/__weak uint32_t HAL_GetTick(void){ return uwTick;}
返回当前节拍,如果内核正常运行,则uwTick的值即为已经经过的ms数(不考虑精确度)
延时函数
/** * stm32f4xx_hal.c * uwTick是一个全局变量,在该文件中定义**/__weak void HAL_Delay(__IO uint32_t Delay){ uint32_t tickstart = HAL_GetTick(); uint32_t wait = Delay; /* Add a period to guarantee minimum wait */ if (wait < HAL_MAX_DELAY) { wait++; } while((HAL_GetTick() - tickstart) < wait) { }}
我想这个函数不需要多解释,就是数节拍以确定延时。
既然了解了HAL的延时函数是如何延时的,则我们完全可以重写这些函数以实现花样延时,但是不建议直接修改库文件,有__weak
在,就可以在其他文件中书写自己的函数而不是破坏库函数原有结构了。另外,修改了库函数,在使用CubeMX重新生成的时候,所做的修改会消失,这一点要慎重。
- 对STM32 HAL库的一些思考(二)__weak关键字和systick
- 对STM32 HAL库的一些思考(一)SPI通信的数据格式问题
- __weak 和 __block 关键字的区别
- STM32中sysTick的设置(转)
- stm32的systick(系统滴答定时器)
- STM32的SysTick
- stm32的Systick定时器
- STM32的SYSTICK
- STM32的SYSTICK详解
- STM32的Systick定时器
- STM32的SYSTICK详解
- STM32的SYSTICK详解
- STM32的SYSTICK详解
- STM32的SYSTICK详解
- 对中国经济和房价的一些思考
- 对ui5的一些总结和思考
- (整理笔记)stm32 systick 的 研究和使用
- STM32的systick的设置
- MFC-给窗口添加滚动条
- 入门训练 序列求和
- redux 1.概念
- codevs1012题解
- java正则表达式匹配windows文件名带路径
- 对STM32 HAL库的一些思考(二)__weak关键字和systick
- 记录自己写的第一个有用的东西《网页收集信息直接录入Excel中》
- start with connect by prior 用法演示及for循环异常处理演示
- JAVA启动参数大全之三:非Stable参数
- 购物车布局
- 软件测试的5C标准
- 关于最小路径的算法(Dijkstra算法)
- Python编程从入门到实践:习题5-3~5-7
- 【吴恩达机器学习学习笔记01】监督学习和无监督学习介绍