我可以在 Microchip C18 中创建一个同时接受 ram 和 rom 指针的函数吗?

发布于 2024-11-08 11:09:39 字数 349 浏览 0 评论 0 原文

当我声明一个接受 const char* 的函数并传递一个字符串文字时,我得到一个

警告:[2066] 赋值中的类型限定符不匹配

,因为字符串文字是 rom const char*。反过来也是一样的。

虽然PIC是哈佛架构,但内存被映射到一个连续的地址空间,因此理论上应该可以以相同的方式支持ram和rom指针。可能我必须使用 rom 指针,因为它们是 24 位,而 ram 指针是 16 位。

但是,仅将 const char* 转换为 const rom char* 是行不通的。

When I declare a function that accepts const char* and I pass a string literal, I get a

Warning: [2066] type qualifier mismatch in assignment

because string literals are rom const char*. It's the same the other way around.

Though the PIC is Harvard architecture, the memory is mapped into one contiguous address space, so theoretically it should be possible to support both ram and rom pointers the same way. Probably I have to use rom pointers because they are 24 bit while ram pointers are 16 bit.

However, just casting a const char* to a const rom char* does not work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

铃予 2024-11-15 11:09:39

不幸的是,这是 Microchip C18 编译器的固有限制。 C18 中的指针可以指向 ROM 或 RAM,但不能同时指向两者。

这就是为什么您会在 Microchip 应用程序库

BYTE* TCPPutString(TCP_SOCKET hTCP, BYTE* Data);
ROM BYTE* TCPPutROMString(TCP_SOCKET hTCP, ROM BYTE* Data);

高科技 PICC-18 编译器具有在运行时确定的适当地址空间,从而可以更灵活地使用指针。这是我放弃 C18 而选择 PICC-18 的原因之一。

请参阅此问题和 John Temples 的高科技 PICC-18 和 MPLAB C18 的比较以获得更多见解。

Unfortunately, this is an inherent limitation of the Microchip C18 compiler. A pointer in C18 can point to either ROM or RAM, but not both.

This is why you will find duplicated functions for ROM and RAM operations in e.g. the Microchip Application Libraries:

BYTE* TCPPutString(TCP_SOCKET hTCP, BYTE* Data);
ROM BYTE* TCPPutROMString(TCP_SOCKET hTCP, ROM BYTE* Data);

The Hi-Tech PICC-18 compiler has the appropriate address space determined at runtime, which allows for more flexible pointer usage. This is one of the reasons I ditched C18 in favour of PICC-18.

See the answers to this question and John Temples' Comparison of Hi-Tech PICC-18 and MPLAB C18 for more insight.

携余温的黄昏 2024-11-15 11:09:39

添加到 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));
}

^这不是实际代码,而是更多伪代码。另外,我不确定它是否有效。

Adding to the answer of mizo (I'm unable to comment, as I primarily answer on Arduino.SE and EE.SE)

The XC8 compiler also has the feature to determine the appropriate address space at runtime.

So yes, Hi-Tech PICC-18 does this, but is not the only compiler to do so.

Though I could understand if switching compiler might be impossible at the moment.


For that reason, you might want to use the following functions in 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);

And you could make your function like:

void YourStringFunction(ramstring);

void YourStringFunctionAccpetingRom(romstring){
YourStringFunction(memcpypgm2ram(romstring));
}

^This isn't actual code, more psuedo code. Also, I'm not sure if it's efficient.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文