硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2946|回复: 7
收起左侧

[STM32H7] 实用技能分享,充分利用内联函数,内联汇编,内部函数和嵌入式汇编提升代码执行效率和便捷性(2021-12-17)

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
发表于 2021-12-17 11:52:12 | 显示全部楼层 |阅读模式
本帖为继续为大家分享实战技能。
一、内联函数Inline function:
内联函数就是带inline关键字修饰的函数,作用是将函数直接嵌入到调用此函数的代码中,从而降低调用此函数所占用的时间。

典型的像CMSIS软件包,ST的LL库都开始采用内联的定义方式,这类函数特点是简短,适合需要频繁调用的场景。因为这样才能发挥内联的优势:

QQ截图20211217005535.png

LL库这里用的关键字是__STATIC_INLINE,这个是ARM的CMSIS软件包专门做的定义方式,对MDK,IAR和GCC都做了适配,通用。

QQ截图20211217005928.png

二、内联汇编Inline assembler:

内联汇编可以将汇编程序指令直接插入到 C 或 C++ 函数中。通常,如果需要访问在 C 中不可访问的硬件资源或者编写时间关键的代码序列,使用内联汇编非常方便。

内联汇编程序类似 C 函数,也可以有形参和返回值。

这个的典型代表是CMSIS软件包,由于要访问一些内核寄存器,所以C里面嵌入汇编再合适不过了。
cmsis_armcc.h :对应MDK AC5头文件
cmsis_gcc.h     : 对应各种基于GCC的编译器头文件
cmsis_clang.h  : 对应MDK AC6头文件
cmsis_iccarm.h : 对应IAR头文件

比如我们常用的函数__set_MSP设置主堆栈指针,实现如下:

123.png

又比如32bit变量赋值的原子操作,由于要用到互斥指令ldrex和strex,通过内联汇编,就可以方便的在各种编译器里实现:

123.png


三、内部函数Instruction Intrinsics

使用内联汇编程序的一个限制是编译器的各种优化对其可能不起作用,这里时候就可以考虑改用内部指令。
内部函数看起来像一个普通的函数调用,但它实际上是编译器识别的内置函数。内部函数编译为内联代码,作为单个指令或作为一小段指令序列,一般用双下划线 (__) 标记

针对内部函数,ARM的CMSIS软件包也是做了一大批,主要分两类:

1、一类是CPU使用的内部函数,部分截图:

QQ截图20211217100638.png

像NOP空周期指令,用到的地方很多。

需要硬件开平方指令,可以使用__sqrtf,开方操作仅需要12-14个时钟周期。

需要调节字节顺序,可以使用__REV, __REV16, __REVSH,  __RBIT,这比我们用C来实现,方便太多了,而且速度快肯定,因为是直接调用的M内核专用指令

QQ截图20211217101332.png

又比如各种RTOS里面最高优先级任务查找,调用指令CLZ(Count Leading Zeros)可以很快查找当前就绪的最高优先级任务(32个优先级)。





2、另一类是SIMD指令,这个在CMSIS-DSP库里面被大量应用,主要使用操作加速,下面是部分截图:

QQ截图20211217102358.png

四、嵌入式汇编:

现在xxxx.S启动文件和各种RTOS的Port移植,都是采用的汇编文件(或者内联汇编)实现。像RTOS里面,做上下文切换得用汇编来做入栈和出栈处理。

不可否认,汇编用的比较溜,相比C有不错的速度优势。但是需要较深的汇编编程能力,这个时候可以多积累些好用的汇编代码。特别是一些算法类的加速和中断服务程序的快速执行。

比如uCOS做的CRC汇编,在需要软件CRC场景下,实际测试比市面上的各种C实现CRC加速都要有优势。
uC-CRC-master.zip

而且做成了C接口形式,大大方便大家使用,部分截图:

QQ截图20211217105144.png

五、总结:

刚开始阶段可以先用ARM,各IC厂家和软件厂商提供的各种玩法,用熟练了,慢慢积累形式自己的风格。

针对这几种用法,ARM也做过一个简单对比图:

QQ截图20211217105522.png





回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2021-12-17 11:52:13 | 显示全部楼层
一上午倒腾了一个帖子,分享下。
回复

使用道具 举报

1

主题

131

回帖

134

积分

初级会员

积分
134
发表于 2021-12-17 12:20:44 | 显示全部楼层
eric2013 发表于 2021-12-17 11:52
一上午倒腾了一个帖子,分享下。

点赞+10086,  辛苦啦,  谢谢分享实用干货
回复

使用道具 举报

0

主题

28

回帖

28

积分

新手上路

积分
28
发表于 2022-1-23 23:07:54 | 显示全部楼层
点赞!感谢分享!
回复

使用道具 举报

4

主题

74

回帖

86

积分

初级会员

积分
86
发表于 2022-1-25 09:11:28 | 显示全部楼层
感恩,感谢
回复

使用道具 举报

3

主题

1222

回帖

1231

积分

至尊会员

积分
1231
发表于 2022-1-25 10:20:38 | 显示全部楼层
回复

使用道具 举报

13

主题

89

回帖

128

积分

初级会员

积分
128
发表于 2023-10-30 10:10:53 | 显示全部楼层
硬汉哥,32bit变量赋值的原子操作的API在H7怎么搜索不到,在哪个文件里?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106692
QQ
 楼主| 发表于 2023-10-30 12:30:26 | 显示全部楼层
qq1646544 发表于 2023-10-30 10:10
硬汉哥,32bit变量赋值的原子操作的API在H7怎么搜索不到,在哪个文件里?

CMSIS给RTX5提供了
https://www.armbbs.cn/forum.php? ... D%D7%D3%B2%D9%D7%F7
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-30 05:24 , Processed in 0.456933 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表