首页 > 其他分享 >gcc 在嵌入式软件中一些常见的用法(待补充)

gcc 在嵌入式软件中一些常见的用法(待补充)

时间:2023-12-01 18:12:04浏览次数:41  
标签:__ gcc bigArray attribute GCC 用法 嵌入式软件 字节

大多数情况,嵌入式软件工程师并不需要知道gcc编译器是工作的,但是随着调试深入,了解gcc在软件中的一些常见的用法大有裨益。

这里列一下遇到的一些嵌入式软件中用到的一些gcc知识。

1 GCC关闭某函数的优化

软件库使用O2/O3优化,有时debug时,需要关闭其中某些函数的优化(即使用此函数使用O0优化),可以采用如下方式:

注意:只能放到函数外,不能放到函数内部。在特定代码前保存当前的编译选项,然后对特定的代码使用O0优化级别,最后再恢复之前保存的编译选项。

示例如下:

#pragma GCC push_options
#pragma GCC optimize("O0")
void conv_test()
{
  ...
}
#pragma GCC pop_options

2 怎么声明某个数组多少字节对齐?

为了效率,CPU从内存取数据并不是一字节一字节去读的,而是一次读取多个字节(如4字节),如果变量地址不对齐(不是4的倍数),则会降低CPU效率。

声明某个数组16Byte对齐:

 int32_t __attribute__((aligned(16))) a_array[1024];

这样,编译后a_array的地址能被16整除(地址低16bit全为0)

3 怎么将某数组定义到外部flash或ram上?

有时数组太大,直接放到片内ram放不下,需要放到外部SDRAM中,可以使用如下方法:

方法1:__ attribute __( at(绝对地址) )

例如:

const uint8_t bigArray[] __attribute__((at(0x30000000))) 

注意:有可能 GNU GCC 不再支持at方法,方法1不行时,请采用方法2。

方法2:__ attribute __((section(“块名”)))

这种方法稍显麻烦,需要修改链接脚本。

例如:

修改C代码

const uint8_t bigArray[] __attribute__((section(".bigArray"))) 

修改lds链接文件,假设外部SDRAM起始地址0x30000000,大小为30MB

/* Program Entry, set to mark it as "used" and avoid gc */
MEMORY
{
    ROM (rx) : ORIGIN =0x08000000,LENGTH =128k
    RAM (rw) : ORIGIN =0x20000000,LENGTH =512k
    EXTSDRAM (rw) : ORIGIN =0x30000000,LENGTH =32M  /* 新增 */
}

/* 在SECTIONS里新增段,段名要与C代码中的字段一致 */

    .bigArray (NOLOAD) : ALIGN(4)
    {
        . = ALIGN(4);
        *(.bigArray)
            *(.bigArray.*)
            . = ALIGN(4);
        __bigArray_free__ = .;
    } > EXTSDRAM

参考:

  1. 【管中窥豹集】听到“对齐”这两个字你能想到什么?

  2. 来了解一下GNU C __attribute__机制

  3. C语言再学习24——attribute (at())地址定位

  4. RTthread_Studio IDE怎么将数组定义到外部SDRAM中

标签:__,gcc,bigArray,attribute,GCC,用法,嵌入式软件,字节
From: https://www.cnblogs.com/sureZ-learning/p/17870654.html

相关文章

  • Docker|--镜像中既有gcc和.NET运行时, 但是容器启动的时候报错 exec: "dotnet": exec
    基本信息#镜像gcc_for_net7_image是如何产生的,分为3步1.基于gcc的镜像运行起来的一个包含了gcc环境的容器,2.在这个容器里安装了.NET7运行时,3.再将这个包含了gcc环境和.NET7的容器打包为一个镜像"gcc_for_net7_image"总之,这个镜像"gcc_for_net7_image"既包含了gcc......
  • python中range()的用法
    在Python中,range()是一个内置函数,用于生成一个包含等差数列的可迭代对象。range()函数有三种不同的用法:range(stop):生成一个从0开始到stop-1结束的整数序列。例如:range(5)生成的序列是0,1,2,3,4。foriinrange(5):print(i)#输出结果:#0#1#2#3......
  • 高版本gcc编译出的程序在低版本glibc机器上运行
    比如我们用gcc9.3.0编译程序,但需要发布的机器gcc版本是4.8.5,怎么办?你可能想到如下方法静态编译容器发布打包依赖的so,使用本地so运行程序1.静态编译将libc和libstdc++静态编译,编译时带上如下参数。g++-static-libgcc-static-libstdc++glibc并不推荐静态链接,你依赖......
  • switch用法
    switch(item.key){case"self_pickup":form.self_pickup=Number(item.value);break;case"same_city":form.same_city=Number(item.value);break;c......
  • GraphFrames介绍和基本用法
    阅读本篇博客前需先了解图数据、scala、spark相关知识 GraphFrames是一款图处理类库。该类库构建在DataFrame之上,既能利用DataFrame良好的扩展性和强大的性能,同时也为Scala、Java和Python提供了统一的图处理API。github:https://github.com/graphframes/graphframes官方文档:h......
  • Numpy-argsort()用法和Numpy-flipud()用法
    Numpy-argsort()用法语法:np.argsort(a,axis=-1,kind='quicksort',order=None)功能:对a进行由小到大排序,并输出其索引实例:importnumpyasnptest=np.array([8,2,-2,3,9,1])new_test=np.argsort(test)print('一维数组的排序结果:{}'.format(new_test))输出结......
  • systemctl和journalctl的用法
    systemctl使用方法 查看当前的服务启动systemctllist-units--type=service查看当前服务开机自启,同时过滤程序ConsumerLogsystemctllist-unit-files|grepConsumerLog服务启动、状态、停止、重启启动systemctlstart *****.service状态systemctlstatus *****.s......
  • C#中TimeSpan和DateTime的用法详解
    在C#编程中,TimeSpan和DateTime是常用的日期和时间处理类。它们提供了丰富的方法和属性,方便我们对日期和时间进行操作和格式化。本篇博客将详细介绍TimeSpan和DateTime的用法。TimeSpanTimeSpan类用于表示一段时间间隔,可以表示从几天到几个纳秒的时间。下面是TimeSpan类的常用属......
  • 初识Linux的文件基本权限和用法
    引言Linux操作系统以其稳定性和安全性而闻名,文件权限是Linux系统中重要的安全机制之一。本篇博客将介绍Linux文件的基本权限概念以及如何使用命令行进行文件权限的管理。文件权限概述在Linux中,每个文件都有一组权限,用于定义文件的访问规则。这组权限分为三个部分:用户(Owner)、群组(Gr......
  • Day20.匿名函数的两种调用方式_max用法_min用法_sorted用法_map用法_filter用法_reduc
    1.匿名函数的两种调用方式: 2.匿名函数求最大和求最小:3.sorted用法和map用法:4.filter的用法:5.reduce的用法:......