- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在寻找一种方法来在 PROGMEM 中为 AVR 项目清晰地定义字符串数组。我有一个需要命令字符串列表的命令行处理器。
在 AVR 架构上执行此操作的传统方法是分别定义每个字符串,然后是指向这些字符串的指针数组。这是非常冗长和丑陋的:
typedef struct
{
PGM_P str; // pointer to command string
uint8_t str_len; // length of command string
uint8_t id; // CLI_COM_* ID number
} CLI_COMMAND_t;
const char CLI_STR_TEMP[] PROGMEM = "TEMP";
const char CLI_STR_POWER[] PROGMEM = "POWER";
...
const CLI_COMMAND_t cli_cmd_table[] = { { CLI_STR_TEMP, sizeof(CLI_STR_TEMP), CLI_COM_TEMP },
{ CLI_STR_POWER, sizeof(CLI_STR_POWER), CLI_COM_POWER },
...
};
(CLI_COM_* 是枚举索引,但可以用函数指针或其他东西代替)
可以使用宏定义字符串和构建表格来减少这种困惑,例如:
#define FLASH_STRING(NAME...) const char CLI_STR_ ## NAME [] PORGMEM = #NAME;
#define FSTR(NAME...) { CLI_STR_ ## NAME, sizeof(CLI_STR_ ## NAME), CLI_COM_ ## NAME) }
FLASH_STRING(TEMP);
FLASH_STRING(POWER);
CLI_COMMAND_t cli_cmd_table[] = { FSTR(TEMP), FSTR(POWER) };
(未经测试,顺便说一句,但应该没问题)
但是,我只想定义所有字符串一次,并让宏生成单个字符串和指针/大小/枚举引用数组。
在 Arduino 平台上有一个 FLASH_STRING_ARRAY 宏,我不太明白,但似乎也无法编译。你可以在这里看到它:http://pastebin.com/pMiV5CMr也许它只是 C++ 之类的。而且它似乎只能在函数内部使用,不能全局使用。
AVR 上的字符串表长期以来一直是一种痛苦和不优雅。除了编写一个小程序来生成必要的代码之外,如果有一种方法可以用宏来定义它,那就太好了。
奖励点:使用相同的宏生成 CLI_COM_* 常量,作为枚举或使用#defines。
编辑:我想它的另一个名称是通过宏进行迭代声明。
解决方案:感谢 luser,我想出了这个解决方案:
typedef struct
{
PGM_P str; // pointer to command string
uint8_t str_len; // length of command string
uint8_t id; // CLI_COM_* ID number
} CLI_COMMAND_LUT_t;
#define COMMAND_TABLE \
ENTRY(testA) \
ENTRY(testB) \
ENTRY(testC)
enum {
#define ENTRY(a) CLI_COM_ ## a,
COMMAND_TABLE
#undef ENTRY
};
#define ENTRY(a) const char CLI_STR_ ## a PROGMEM = #a;
COMMAND_TABLE
#undef ENTRY
CLI_COMMAND_LUT_t command_lut[] PROGMEM = {
#define ENTRY(a) {CLI_STR_ ## a, sizeof(CLI_STR_ ## a), CLI_COM_ ## a},
COMMAND_TABLE
#undef ENTRY
};
预处理器产生以下输出:
typedef struct
{
PGM_P str;
uint8_t str_len;
uint8_t id;
} CLI_COMMAND_LUT_t;
enum {
CLI_COM_testA, CLI_COM_testB, CLI_COM_testC,
};
const char CLI_STR_testA PROGMEM = "testA"; const char CLI_STR_testB PROGMEM = "testB"; const char CLI_STR_testC PROGMEM = "testC";
CLI_COMMAND_LUT_t command_lut[] PROGMEM = {
{CLI_STR_testA, sizeof(CLI_STR_testA), CLI_COM_testA}, {CLI_STR_testB, sizeof(CLI_STR_testB), CLI_COM_testB}, {CLI_STR_testC, sizeof(CLI_STR_testC), CLI_COM_testC},
};
所以所有这些都可以包含在一个区域中,我最终得到的只是每个命令的一个简单且最重要的单一定义,该定义既用作其字符串名称又用作代码的引用。
非常感谢你们,非常感谢!
最佳答案
X-Macros 可能会有所帮助。
字符串.x:
X(TEMP, "Temp")
X(POWER, "Power")
用法:
// String concatenation macros
#define CONCAT(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
// Generate string variables
#define X(a, b) const char CONCAT(CLI_STR_, a) [] PROGMEM = b;
#include "strings.x"
#undef X
// Generate enum constants
#define X(a, b) CONCAT(CLI_COM_, a),
enum {
#include "strings.x"
};
#undef X
// Generate table
#define X(a, b) { CONCAT(CLI_STR_, a), sizeof(CONCAT(CLI_STR_, a)), CONCAT(CLI_COM_, a) },
const CLI_COMMAND_t cli_cmd_table[] = {
#include "strings.x"
};
#undef X
这是未经测试的。
关于AVR-GCC 中 PROGMEM 中干净整洁的字符串表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19047730/
我在 PROGMEM 中有几个二维数组。 我想将它们存储到另一个数组中,因此有一个二维 PROGMEM 数组的 PROGMEM 数组。 那我要把数据读出来 这是我的 void myFunc() {
我正在尝试从字符串数组中获取单个字符以写入 Arduino 上的 LCD 显示器。只是我没有真正得到任何有效数据。 LCD写代码: void LCD::drawString(uint16_t x, u
我一直无法让这段代码正常工作。我的目标是在 LCD 上显示放置在 PROGMEM 中的字符串。包含指向这些字符串的指针的数组也在 PROGMEM 中。该函数使用一个变量调用,该变量又被转换为索引号以读
你好,我正在 Arduino 上制作游戏,但我需要存储 2 个全局变量来跟踪分数 currScor 和 hiScor 类型都是 uint32_t 并且为了节省 ram 空间,我将它们标记为 uint3
我解决问题的第一种方法是尝试制作字典/哈希表,但有人告诉我这是一个坏主意。我被发送到 PROGMEM .现在我的问题是我正在使用触摸屏制作菜单系统。我需要每个按钮都可以使用不同的语言,所以有一个存储当
考虑这个使用 Arduino IDE 编译的代码片段: PROGMEM char charSet[] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xA , 0x6, 0xE, 0x
我正在尝试将数据存储在 PROGMEM 中并稍后检索。然后通过 USB 串行通信将它们发送到屏幕。 int8_t serial_comm_write(const uint8_t *buffer, ui
我在从程序内存读取字符串时遇到一些问题: const char str[] PROGMEM = "Test string here\r\n"; 这是我的打印例程: /** Send string ov
我正在尝试编写一个头文件来驱动 LED 矩阵,但我遇到了无法解决的语法错误 我已经在我认为有必要的地方添加了“;”并检查了https://www.nongnu.org/avr-libc/user-ma
我试图通过尝试减少 progmem 中的计数字符串来保护一些程序空间。所以我开始将所有多次需要的字符串放入一个带有命名空间的文件中: #include #ifndef __PSTRINGS__ #d
我正在开发一个小型 HTTP 服务器。我正在构建一个路由器,因为可能有很多路由,所以我想将它们放入闪存中,这样我就不必使用宝贵的 SRAM。然而,要么我没有正确理解某些事情,要么发生了一些奇怪的事情,
已找到解决方案,请参阅下面我的评论! 我正在尝试使用 PROGMEM 读取放置在结构中并存储在 Arduino Mega (ATmega 2560) 闪存中的数据。结构对象 manufacturer_
我有三个字符数组,我不希望 Arduino 将它们存储在 SRAM 中, 所以我想用 PROGMEM 来存储和读取 flash , 而不是。 char *firstArr[]={"option 1",
我制作了一个播放数组中保存的歌曲(使用蜂鸣器)的程序: (...) //function which plays a single note void playNote(int8 wavelength
我正在研究一个我认为基本上可以通过(乘法)链表很好解决的问题。然而,我的平台是一个 SRAM 非常有限的 Arduino,所以我想将它全部保存在 PROGMEM 中(使用 avr/pgmspace.h
我正在使用独立的 ATmega328P有两个piezo elements生成一些音乐。 我已经用音符的频率定义了一些常量。然后我定义了一个结构,其中包含第一个和第二个压电的音符以及音符的长度。然后我制
我正在使用 ATMEL Studio 6.2 及其工具链和 avr-gcc (avr8-gnu-toolchain)。我有一个需要放在 flash (PROGMEM) 中的变量,我将其声明为全局变量:
我有几个 const int 二维数组全局存储在 PROGMEM 中。例如: const int image1[][17]PROGMEM = { {1,1,1,1,1,1,1,1,1,0,0,0,
(由于大多数 Arduino 板上的可用内存有限,我有时会在使用有效的 C/C++ 代码时遇到问题,所以这个问题专门针对在 Arduino 上使用结构的任何问题。) 我看过 example code
我正在寻找一种方法来在 PROGMEM 中为 AVR 项目清晰地定义字符串数组。我有一个需要命令字符串列表的命令行处理器。 在 AVR 架构上执行此操作的传统方法是分别定义每个字符串,然后是指向这些字
我是一名优秀的程序员,十分优秀!