当我声明一个接受const char*
的函数并传递字符串文字时,我得到一个
警告:[2066] 类型限定符在赋值中不匹配
因为字符串文字是rom const char*
.反之亦然。
虽然PIC是哈佛架构,但内存被映射到一个连续的地址空间,所以理论上应该可以以相同的方式支持ram和rom指针。可能我必须使用 rom 指针,因为它们是 24 位的,而 ram 指针是 16 位的。
但是,仅将const char*
转换为const rom char*
是行不通的。
不幸的是,这是Microchip C18编译器的固有限制。C18 中的指针可以指向 ROM 或 RAM,但不能同时指向两者。
这就是为什么您会在例如Microchip应用程序库中找到ROM和RAM操作的重复功能的原因:
BYTE* TCPPutString(TCP_SOCKET hTCP, BYTE* Data);
ROM BYTE* TCPPutROMString(TCP_SOCKET hTCP, ROM BYTE* Data);
Hi-Tech PICC-18 编译器具有在运行时确定的适当地址空间,允许更灵活地使用指针。这就是我放弃C18而选择PICC-18的原因之一。
请参阅这个问题的答案和John Temples的高科技PICC-18和MPLAB C18的比较,以获取更多见解。
添加到 mizo 的答案中(我无法发表评论,因为我主要回答 Arduino.SE 和 EE.SE)
XC8编译器还具有在运行时确定适当地址空间的功能。
所以是的,Hi-Tech PICC-18 这样做,但不是唯一这样做的编译器。
虽然我可以理解目前是否不可能切换编译器。
因此,您可能希望在string.h
中使用以下函数
/** @name memcpypgm2ram
* The {bf memcpypgm2ram} function performs a {bf memcpy} where
* {bf s1} points to data memory and {bf s2} points to program
* memory.
* @param s1 pointer to destination in data memory
* @param s2 pointer to source in program memory
* @param n number of characters to copy
*/
void *memcpypgm2ram (auto void *s1, auto const MEM_MODEL rom void *s2, auto sizeram_t n);
/** @name memcpyram2pgm
* The {bf memcpyram2pgm} function performs a {bf memcpy} where {bf s1}
* points to program memory and {bf s2} point to data memory.
* @param s1 pointer to destination in program memory
* @param s2 pointer to source in data memory
* @param n number of characters to copy
*/
MEM_MODEL rom void *memcpyram2pgm (auto MEM_MODEL rom void *s1, auto const void *s2, auto sizeram_t n);
你可以让你的函数像:
void YourStringFunction(ramstring);
void YourStringFunctionAccpetingRom(romstring){
YourStringFunction(memcpypgm2ram(romstring));
}
^这不是实际代码,更多的是伪代码。另外,我不确定它是否有效。