【问题标题】:Can I make a function that accepts both ram and rom pointers in Microchip C18?我可以在 Microchip C18 中创建一个同时接受 ram 和 rom 指针的函数吗?
【发布时间】:2011-05-17 01:49:03
【问题描述】:

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

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

因为字符串文字是rom const char*。反之亦然。

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

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

【问题讨论】:

    标签: c pointers microcontroller pic


    【解决方案1】:

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

    这就是为什么您会发现 ROM 和 RAM 操作的重复功能,例如Microchip Application Libraries:

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

    Hi-Tech PICC-18 编译器在运行时确定了适当的地址空间,这允许更灵活的指针使用。这是我放弃 C18 转而使用 PICC-18 的原因之一。

    查看this question 和 John Temples 的Comparison of Hi-Tech PICC-18 and MPLAB C18 的答案以获得更多信息。

    【讨论】:

      【解决方案2】:

      补充 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));
      }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-17
        • 2012-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多