STM32 进阶教程 5 - 内联函数

2023-11-05

前言

在计算机科学中,内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支。但在选择使用内联函数时,必须在程序占用空间和程序执行效率之间进行权衡,因为过多的比较复杂的函数进行内联扩展将带来很大的存储资源开支。另外还需要特别注意的是对递归函数的内联扩展可能引起部分编译器的无穷编译。

内联扩展是一种特别的用于消除调用函数时所造成的固有的时间消耗方法。一般用于能够快速执行的函数,因为在这种情况下函数调用的时间消耗显得更为突出。这种方法对于很小的函数也有空间上的益处,并且它也使得一些其他的优化成为可能。

通常,在C语言中,内联展开的功能可由带参宏(Macros)在源码级实现。内联提供了几个更好的方法:

1,宏调用并不执行类型检查,甚至连正常参数也不检查,但是函数调用却要检查。

2,C语言的宏使用的是文本替换,可能导致无法预料的后果,因为需要重新计算参数和操作顺序。

3,在宏中的编译错误很难发现,因为它们引用的是扩展的代码,而不是程序员键入的。

许多结构体使用宏或者使用不同的语法来表达很难理解。内联函数使用与普通函数相同的语言,可以随意的内联和不内联。

4,内联代码的调试信息通常比扩展的宏代码更有用。

 

对于基于C的编译系统,内联函数的使用可能大大增加编译时间,因为每个调用该函数的地方都需要替换成函数体,代码量的增加也同时带来了潜在的编译时间的增加。

本节我们将基于“STM32 进阶教程 3 -  软件实现高精度延时 1”内能来介绍内联函数的命定义与使用,以及其带来的差别。

示例详解

基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 STM32F103c8t6, 使用stm32cubemx 工具自动产生的配置工程,使用KEIL5编译代码。

 

 

本示例所用的最小系统板原理图:

 

    1. 关于CUBEMX工具及KEIL工具的操作将不再细讲,如果还有不熟悉的可以查看之前的教程文档。下面直接介绍工程配置:

 

 

      1. 系统时钟树

      1. 定时器配置

      1. 引脚配置

      1. 中断配置(保持默认)

 

 

    1. 工程代码
      1. 将事先准备好的delay.c和delay.h文件加到工程中,

Delay.h文件放在INC文件夹下即可。

      1. 在main.c 中加入如下图所示代码:

 

 

    1. 编译工程,下载程序看效果:PC13引脚产生周期为100us 占空比为50%的方波信号,同时可以看到LED是常的,通过逻辑分析仪工具,可以看到PC13引脚上的波形:

 

编译后的代码大小:

对应的汇编代码:

 

接下来我们在delay_us函数实现前加上inline 关键字(也可以是 __inline 或 __INLINE)再次编译。

执行效果和代码大小均不变:

仿真查看其汇编代码:

发现并没有像宏一将展开,其实现还是一样,并没有实现内联展开,这里因为 inline只适合涵数体内代码简单的函数数使用,不能包含复杂的结构控制语句例如while、switch,并且内联函数本身不能是直接递归函数(自己内部还调用自己的函数)。

同时在keil的帮助文档中不有如下说明

接下来我们在main.c的USER CODE BEGIN 0区加入如下代码:

在USER CODE BEGIN 3中加入如下代码:

重新编译,仿真,查看对应汇编代码,发现其已经实现了内联,g函数中的f(x),与 f(y)对应的源码直接在g函数中:

 

通过上面的实例,我们已基本学会基于keil MDK平台的stm32 中内联函数的使用,了解决了其使用的基本方法(更多关于inline的说明可以查看对应的帮助文档):

 

OK,本期实验完成!下期见!同时如果大家有什么疑问或是有想了解的其它内容,也欢迎大家留言!!最后喜欢这个公众号的同学们记得加关注了,会有不定期技术干货推出!!

文中源码资料下载,在公众号里给十三发消息:

下载|STM32进阶教程5

 

关注十三公众号

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 进阶教程 5 - 内联函数 的相关文章

随机推荐

  • unity-Fatal Error GC-GetThreadContext Failed

    这几次在使用unity5 3打windows包后 运行x exe不久总是会弹出 fatal error GC GetThreadContext Failed 的错误 到网上查了 各种说法都有 我干脆换了unity5 6版本 但是问题依然存在
  • java.lang.NumberFormatException: Invalid int: “0 “

    关于 今天在接手前人模块开发的时候 测试一个数据列表点击跳转详细页面的时候奔溃了 控制台 主要出现的错误提示是这句 java lang NumberFormatException Invalid int 0 问题原因转换了特殊字符 空格 等
  • 常用的python 命令

    安装依赖的命令 venv虚拟环境 下载依赖包 创建虚拟环境 python m venv lt 虚拟环境名称 gt python m venv venv 创建名为venv的虚拟环境 激活虚拟环境 source venv bin activat
  • IPO向上,大模型向下:中国企服寻找新「出口」

    2023年 资本市场给企服行业带来的动荡 无疑是一次洗牌机会 只有当SaaS企业深耕产业侧 才能找到实现标准化的解法 才能在一波又一波的浪潮下抓住机遇 作者 思杭 编辑 皮爷 出品 产业家 2023上半年 企服行业在二级市场表现得尤为热闹
  • Mac latex vscode配置外部PDF阅读器并配置对应跳转

    1 下载并安装Skim 下载链接 https sourceforge net projects skim app 2 配置skim touch displayfile txt open displayfile txt 在文本中写入 bin
  • Unity Animation从UAS获取动画资产到编制状态机控制简单的人物动画

    Animation 动画 0 前言 这个笔记用于讨论在Unity中开发游戏时使用动画的相关知识 这个笔记最终期望能够达到 在Unity的Demo中展现一个人物 其能够进行类似挥拳 开门的具体动作 我将这个任务进一步的划分 第一阶段 获得动画
  • 环形内存circular_buffer

    boost中支持环形内存 该内存在一些地方还是蛮实用的 简单看下具体使用及部分源码 使用和源码相对来说都还是比较简单 易于理解的 与STL接口基本一致 void CCircularBufferTest TestCircularBuffer
  • 双向链表和循环双向链表的基本操作

    双向链表和循环双向链表的基本操作 include
  • Libevent库的介绍与应用

    Libevent库 Libevent概述 Libevent使用模型 Libevent库使用示例 Libevent事件类型和框架结构 使用Libevent完成tcp服务端 Libevent概述 Libevent是开源社区的一款高性能的I O框
  • VS远程连接调试Linux程序 ,vs找不到Linux头文件的解决办法

    使用VS编写Linux程序 可以将VS连接到Linux上 却出现了VS IDE中找不到 include
  • 小程序逆向工程:这个开源的小程序逆向工具真不错,2023年亲测成功

    前言 安全部门的大哥又双叒叕报了一个小程序的高危漏洞 他使用逆向工程破解了加密信心 用抓包修改了请求参数 又是头疼的一天 想成为一名微信小程序的开发者 前端思路的学习和安全意识是非常有必要的 故务必掌握小程序反编译技能 这里用到了2个工具
  • 虚拟化KVM

    什么是虚拟化 在计算机技术中 虚拟化是一种资源管理技术 是将计算机的各种实体资源 CPU 内存 磁盘空间 网络适配器等 予以抽象 转换后呈现出来并可供分割 组合为一个或多个计算机配置环境 并重新分割 重新组合 已达到最大化合理利用物理资源的
  • 程序的运行结构

    一 程序的运行结构有三种 1 顺序结构 2 分支结构 3 循环结构 二 分支结构 根据代码的成立与否 选择执行方向 包括 if 判断条件 代码块 if else语句 一定会执行一个语句或者是if里面的 或者是else里面的 switch 整
  • Leetcode每日一题:589. N 叉树的前序遍历

    前序遍历二叉树的要点就是根左右 在这里遍历的是n叉树 因此先访问根节点 然后再遍历根节点的每个孩子就可以了 递归解法 Definition for a Node class Node def init self val None child
  • Qt学习笔记:2018年8月记录

    1 Qt 设置背景图片注意事项 使用stylesheet设置背景图片还是有一些要注意的 如果是在mainwindow和dialog中 直接右键change style sheet在add resource中选择background imag
  • The method getContextPath() from the type HttpServletRequest refers to the missing type

    问题描述 每个JSP页面中的 request getContextPath 下方出现了红色的波浪线 提示的错误信息是 The method getContextPath from the type HttpServletRequest re
  • 微信小程序页面监听右上角退出,判断小程序进入后台时就实现页面跳转

    功能需求 在小程序中某一个页面没有进入后台的功能 如果点击右上角退出按钮 默认小程序进入后台 点击再次进入本页面 但是因为功能需要 在小程序进入后台时 再次进入需要跳转到首页 实现方法 在app js onHide 生命周期中监听进入后台的
  • 项目启动报错: This is very likely to create a memory leak. Stack trace of thread 解决方案

    问题发现 The web application ROOT appears to have started a thread named UIC STATISTIC THREAD but has failed to stop it This
  • 深度学习AI编译器-LLVM简介

    1 什么是LLVM LLVM的命名最早来源于底层语言虚拟机 Low Level Virtual Machine 的缩写 它是一个用于建立编译器的基础框架 以C 编写 创建此工程的目的是对于任意的编程语言 利用该基础框架 构建一个包括编译时
  • STM32 进阶教程 5 - 内联函数

    前言 在计算机科学中 内联函数 有时称作在线函数或编译时期展开函数 是一种编程语言结构 用来建议编译器对一些特殊函数进行内联扩展 有时称作在线扩展 也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方 上下文 从而节省了每次调用