【问题标题】:PSTR() on __FUNCTION____FUNCTION__ 上的 PSTR()
【发布时间】:2013-07-31 16:55:36
【问题描述】:

使用avr-gcc 可以将数据存储在程序存储器中以节省 RAM。这是使用PROGMEM attribute 完成的。 AVR-libc 还提供了一个宏,PSTR(),可以用于文字字符串。

现在我正在尝试将PSTR()__func__, __FUNCTION__ or __PRETTY_FUNCTION__. 一起使用

以下代码按预期工作,

display.message(__func__, 2);
display.message(__FUNCTION__, 2);
display.message(__PRETTY_FUNCTION__, 2);

,当任何这些行的编译失败时,

display.messageP(PSTR(__func__), 2);
display.messageP(PSTR(__FUNCTION__), 2);
display.messageP(PSTR(__PRETTY_FUNCTION__), 2);

,出现以下错误:

initializer fails to determine size of '__c'

PSTR 的定义,来自 WinAVR/avr/include/avr,解释了错误消息中引用的变量:

# define PSTR(s) (__extension__({static char __c[] PROGMEM = (s); &__c[0];}))

这对于宏来说不是通用的,因为 __FILE__ 编译和工作正常:

display.messageP(PSTR(__FILE__), 2);

关于导致此错误的原因以及是否可以使用 PSTR() 将函数名插入程序内存的任何想法?

【问题讨论】:

  • 看起来那些字符串文字不能放在那个空间中,因为它们需要特殊功能?访问它们。事实上,这些名字应该非常小,所以我想知道将它们移到那里是否有真正的优势。我这么说是不知道你有多少内存。
  • @MichaelDorgan avr-libc 提供访问程序内存中变量的函数;问题的最后一行代码证实了这一点,它工作正常。我同意这些字符串很小,但它们在嵌入式系统中很重要(只有几 KB 的 RAM)。

标签: c++ c embedded avr-gcc


【解决方案1】:

__func____FUNCTION____PRETTY_FUNCTION__ 不是字符串字面量,如 __FILE__,而是像静态本地字符数组变量一样创建到您正在使用它们的函数中。因此,PSTR() 宏将失败,因为您不能使用数组变量来初始化另一个数组变量。

__func__ 在 C11, §6.4.2.2 ¶1 中有所描述:

标识符__func__ 应由翻译器隐式声明,就好像, 紧跟在每个函数定义的左大括号之后,声明

static const char __func__[] = "函数名";
出现,其中 function-name 是词法封闭函数的名称。

According to the GCC manual__FUNCTION____PRETTY_FUNCTION__ 只是 C 中 __func__ 的同义词(__PRETTY_FUNCTION__ 对于 C++ 更冗长)。

【讨论】:

  • 有没有办法让 func 进入程序内存?默认情况下,定义将其放置在 RAM 中。显然人们不想在静态调试数据上浪费 RAM。
  • 问题是关于avr-gcc,暗示AVR平台。它是一个哈佛架构,有两个内存空间。程序存储器是设备的闪存,通常是只读的。由于这些设备只有有限的 RAM(16k 大约是极限,通常为 2-4k),因此您不想用调试字符串填充它。
  • @MoJo:谢谢你的澄清。如果您有此要求,您似乎需要逐个声明自己的变量,或者您必须修改编译器以扩展它以允许您为 __func__ 变量指定内存目标。
  • 我对 GCC 提出了增强请求。
猜你喜欢
  • 2011-06-14
  • 2017-05-12
  • 2010-09-20
  • 1970-01-01
  • 2011-03-13
  • 2019-09-18
  • 2023-03-09
  • 2016-10-31
  • 1970-01-01
相关资源
最近更新 更多