cubeIDE开发, stm32的C库应用分析

news2025/1/16 14:45:57

一、stm32的C库

        cubeIDE针对STM32芯片开发,提供个了两大库,HLA库和C库(集成GNU Tools for STM32工具链时提供,该工具链同样是意法半导体提供,可在http:// www.st.com单独下载),前者帮助开发这简化与硬件交互,后者帮助开发者简化底层软逻辑实现。CubeIDE已经通过插件形式将GNU Tools for STM32工具链内嵌在该开发平台的插件集中,它主要包含两大内容,一部分涉及编译相关的make、gcc及平台特性等,另一部分就是开发应用软件密切相关的newlib库(即c库)。

        因为在符合POSIX.1标准(也称为IEEE 1003.1)的系统上使用C库,C库依赖于操作系统服务的少量必要函数调用,这些必要函数中的大多数都是随操作系统提供的。若开发者基于cubeIDE开发STM32应用时,如果不加入第三方嵌入式系统时,相当于在为“裸板”系统开发软件,没有操作系统,就必须自行提供一些必须的依赖函数(子例程)。因此,当基于cubeIDE创建STM32工程时,开发平台就直接帮开发者把newlib库的调用加入输出代码中,其中syscalls.c就是已经最小化地提供不做任何操作的必要函数定义或具有最小功能的子例程。

        同时在程序启动文件startup_stm32*.s汇编文件中,调用了c库。

          CubeIDE通过集成arm-none-eabi交叉编译工具包将 C库加入STM32工程,该c库包含:

  • as(assembler ,汇编器)子库,用于汇编编译;
  •  BFD(Binary File Descriptor Library)子库,用于处理目标文件,像as、ld、binutils等都依赖它间接出来文件;
  • libc(standard ANSI C library,基于Red Hat newlib C Library)子库;
  • gdb子库,用于调试。
  • stabs(symbol table strings)子库;
  • ld(GNU linker)子库,用于链接功能。
  • libm(C Math Library)子库,用于计算,主要是通用计算。
  • refcard 子库,涉及GDB相关的启停、断点监测、信号捕获、标识列表、调试脚本、调试输出、调试控制等。
  •  ibiberty(library of free software)子库,主要是实现了一些函数的接口或者宏,用于补充、替换、优化、扩展c实现。
  • gprof子库,用于性能检测分析工具;
  • binutils( gnu Binary Utilities)子库,用于各种命令工具集;
  • gcc子库,用于gcc编译、部署、运行相关。

        其中,在STM32应用开发编程中涉及对c库调整的主要是libc库,该库主要包含 stdlib、stdio、ctype、string、wchar、 signal、time、locale、arglist、Protection以及前面例程组件的重写部分及其他特定例程。

二、stm32的c库重载函数调整

        CubeIDE在创建工程是输出syscalls.c源码,已经将c库在stm32MCU上运行的依赖的必要函数例程做了定义,但是都是没有具体内柔的伪实现。

        正如本专栏前面提到的将printf函数输出映射到lpuart1串口上,就是改写了syscalls.c中_write函数来实现的。在libc的printf源码中,printf接受一系列参数,从*format向每个参数应用一个格式说明符,并将格式化数据写入stdout。在不修改libc库基础上,调整_write写入到“stdout”替换成lpuart1,就可以实现printf输出内容到串口上。

        syscalls.c中的_write如下,该函数还是弱定义(_weak):

         例如可以调整为

__attribute__((weak)) int _write(int file, char *ptr, int len)
{
	int DataIdx;

	for (DataIdx = 0; DataIdx < len; DataIdx++)
	{
		//__io_putchar(*ptr++);
        HAL_UART_Transmit(&lpuart1,  ptr++, 1, HAL_MAX_DELAY);
	}
	return len;
}

        更近一步,如前面博文提到的,可以程序开始前先指定printf需要映射的实例句柄,将整个写入内容直接转发到串口实例上。

UART_HandleTypeDef *gHuart;
void ResetPrintInit(UART_HandleTypeDef *huart)  {
  gHuart = huart;
  /* Disable I/O buffering for STDOUT  stream, so that
   * chars are sent out as soon as they are  printed. */
  setvbuf(stdout, NULL, _IONBF, 0);
}

int _write(int fd, char* ptr, int len) {
  HAL_StatusTypeDef hstatus;
  if (fd == STDOUT_FILENO || fd ==  STDERR_FILENO) {
    hstatus = HAL_UART_Transmit(gHuart,  (uint8_t *) ptr, len, HAL_MAX_DELAY);
    if (hstatus == HAL_OK)
      return len;
    else
      return EIO;
  }
  errno = EBADF;
  return -1;
}

        依据libc的移植说明,printf需要这些函数:close、fstat、isatty、lseek、read、sbrk、write支持,因此在STM32上实现printf函数,需要提供这些函数的定义(可以是伪定义、空定义或实际内容)。在实际应用中,先将映射指向串口,在调用printf函数就可以实现打印输出到指向串口,而非libc原来的stdout。

ResetPrintInit(&hlpuart1);
...
printf("123\r\n");

        类似printf,以下功能函数也可以根据实际项目需要调整其输出指向来实现:

  • fprintf与printf类似,只是输出指向流fd而不是stdout。
  • sprintf与printf类似,只是输出指向缓冲区str,并输出终止NUL,注意生成的输出不要超过缓冲区所能容纳的输出。
  • snprintf与sprintf类似,不同的是输出最多限制为字节大小,包括终止的NUL。
  • asprintf与sprintf类似,只是输出存储在动态分配的缓冲区pstr中,稍后应使用free释放该缓冲区。
  • asnprintf类似于sprintf,不同的是返回类型是原始str(如果它足够大),或者是动态分配的字符串(注意输出超过*size情况)。

        又如syscalls.c中和时间相关的_times函数,该函数是clock计时函数所需要,通过改写该函数,将其与STM32的systick关联,实现到STM32的迁移使用。

         在STM32工程中,调用clock函数时,就会进入子例程调用_times函数,通过改写_times函数,就间接地调整了clock函数,例如:

int _times(struct tms *buf)
{
    uint32_t ct = HAL_GetTick();
	return (int)ct/1000;
}

        更多关于libc库里各个功能函数依赖那些子例程函数,可以通过查找自己CubeIDE开发平台的GNU Tools for STM32工具包目录,

         进入该目录,找到pdf/libc.pdf说明文档查看,该文档会具体指出各个功能函数依赖那些子例程函数以及使用注意事项和迁移注意事项。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/145159.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

P1055 [NOIP2008 普及组] ISBN 号码————C++

文章目录题目[\[NOIP2008 普及组\] ISBN 号码](https://www.luogu.com.cn/problem/P1055)题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1样例 #2样例输入 #2样例输出 #2提示解题思路1Code运行结果解题思路2Code运行结果题目 [NOIP2008 普及组] ISBN 号码 题目描述 …

windows 安装jenkins运行发布vue项目到linux服务器

文章目录背景安装jenkins安装插件安装nodej插件Publish over SSH系统配置Publish over SSH全局工具配置设置node构建项目创建一个freestyle的项目Discard old buildsgit命令报错Host key verification failedBuild背景 由于服务器上运行jenkins很卡&#xff0c;所以对于小公司…

windows安装jenkins运行发布java springboot项目到linux服务器

文章目录背景安装jenkins安装插件安装maven插件Publish over SSH系统配置Global propertiesPublish over SSH全局工具配置设置jdk设置maven设置git构建java maven项目freestyle 或者maven都可以Discard old buildsgit命令报错Host key verification failed每次构建前清理构建环…

可观测性之Log4j2优雅日志打印

可观测性之Log4j2优雅日志打印# 简介 对于Log4j2大家应该都不是很陌生&#xff0c;听说最多的应该是2021年年底出现的安全漏洞了&#xff0c;不过最让大家头痛的应该不仅仅是这个安全漏洞的处理&#xff0c;安全漏洞通过升级最新的依赖版本即可快速解决&#xff0c;平时在使用…

基于Java+SpringMvc+vue+element实现上海汽车博物馆平台

基于JavaSpringMvcvueelement实现上海汽车博物馆平台 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源…

C语言.表白神器.爱你之心之闪耀

前言 爱你之心之闪耀&#xff0c;这个名字比较沙雕哈哈哈。。。 爱你之心之闪耀前言爱心函数的选取爱心函数1爱心函数2简单爱心粒子发射原理爱心结构一些宏初始化init创建若干爱心并初始化setHeart展示爱心showHeart爱心变大modifyHeart设置音乐主函数Love.hLove.cpp祝有情人&a…

【有营养的算法笔记】一文轻松学会高精度算法(加减乘除)

&#x1f451;作者主页&#xff1a;进击的安度因 &#x1f3e0;学习社区&#xff1a;进击的安度因&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;有营养的算法笔记 文章目录一、前言二、高精度加法1、思想及模板2、代码实现三、高精度减法1、思路及模板2…

电脑一键重装系统卡在正在准备就绪怎么办

最近有些用户想要给电脑换新的系统使用&#xff0c;选择一键重装工具重装&#xff0c;但结果卡住了&#xff0c;小白一键重装系统卡在正在准备就绪怎么办?下面小编就教下大家小白一键重装系统卡在正在准备就绪怎么办的解决办法。 工具/原料&#xff1a; 系统版本&#xff1a;…

七 近代史案例欣赏

首先打开我们的编译器&#xff0c;EgretWing,新建一个Egret项目。 新建好后如下图&#xff1a; 主要文件夹介绍 libs:包类文件夹 resource&#xff1a;资源文件夹 src&#xff1a;编写代码文件夹 template&#xff1a;前端文件夹 代码编写 1 打开src中Main.ts文件找到crea…

Scala中的协变点、逆变点、不变点如何确定?

阅读《scala编程》时&#xff0c;我们知道了类的类型参数是可以型变&#xff08;variance&#xff09;的。型变包含以下三种&#xff1a; 协变&#xff08;convariant&#xff09;&#xff1a;如果S是T的子类型&#xff0c;则C1[S]也是C1[T]的子类型&#xff0c;则称C1在类型参…

leetcode 208. 实现 Trie (前缀树)【字典树(前缀树)的介绍与思路整理】

题目 Trie&#xff08;发音类似 “try”&#xff09;或者说 前缀树 是一种树形数据结构&#xff0c;用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景&#xff0c;例如自动补完和拼写检查。 请你实现 Trie 类&#xff1a; Trie() 初始化前缀树对象。…

HCL Notes/Domino 12.0.2版本正式发布

大家好&#xff0c;才是真的好。 之前代号为多瑙河版本的Notes/Domino产品&#xff0c;昨天晚上正式露出了神秘的面纱&#xff0c;版本号也正式定为12.0.2。从版本上来看&#xff0c;是12.0版本的小版本&#xff0c;但从功能和特性上来说&#xff0c;这完全就是一个大版本。 …

Duboo优雅关闭(附源码分析)

Dubbo优雅关闭 1. 关闭有什么问题 当服务提供方要上线的时候&#xff0c;一般是通过部署系统完成实例重启。在这个过程中&#xff0c;服务提供方的团队并不会事先告诉调用方他们需要操作哪些机器&#xff0c;从而让调用方去事先切走流量。而对调用方来说&#xff0c;它也无法…

LeetCode刷题复盘笔记—一文搞懂动态规划之72. 编辑距离问题(动态规划系列第四十一篇)

今日主要总结一下动态规划的一道题目&#xff0c;72. 编辑距离 题目&#xff1a;72. 编辑距离 Leetcode题目地址 题目描述&#xff1a; 给你两个单词 word1 和 word2&#xff0c; 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作&…

FME对调查云平台完成变更调查照片的批量迁移

目录 前言 二、实际步骤 1.准备基础数据 2.模拟登录 3.获取图斑标识码 4.获取图形信息 5.通过空间位置关系过滤不合格照片 5.通过深度学习模型过滤照片特征错误图斑 6.照片迁移 总结 前言 又到了一年一度国土变更调查的苦日子&#xff0c;因为项目规则原因&#xff0c;…

【架构设计】你的应用该如何分层呢?

前言 最近review公司的代码&#xff0c;发现现在整个代码层级十分混乱&#xff0c;一个service类的长度甚至达到了5000多行。而且各种分层模型DTO、VO乱用&#xff0c; 最终出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动一处就牵一发而动全身等问题。 我们在吸取了阿里…

spring之aop底层实现

1.aop之ajc增强 什么是ajc增强&#xff1f; ajc是aop的另外一种实现&#xff0c; 通过aspectj编码器来改动class源文件实现aop 2.aop之agent增强 什么是agent增强&#xff1f; agent是aop的另外一种实现&#xff0c;是通过类加载时改动class类 3.aop之proxy增强-jdk代理 …

Mac系统入门之电脑卡死怎么办

当你兴冲冲的从菜鸡驿站提回来一台新的电脑,你欣喜若狂,迫不及待的拆开快递箱,里面是一台苹果电脑,这时,你不禁抓耳挠腮:Mac系统怎么用啊? 下面,这篇专栏教你如何入门Mac系统 https://blog.csdn.net/cyyyyds857/category_12163999.html –––––前言 你正兴致勃勃的写着…

mysql中字符串拼接、填充和切片

一、本文主要结构 在编程过程往往会遇到&#xff0c;多个字符串需要进行拼接或者填充固定值或者截取部分数据&#xff0c;本文主要实战下面四个函数 concat(str1, str2,…)&#xff1a;字符串进行拼接 lpap&#xff08;&#xff09;&#xff1a;左边填充 rpad&#xff08;&…

【C语言】指针经典题分析

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;《初识C语言》 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录前言一、指针与数组经典题解析二、经…