Могу ли я создать функцию, которая принимает как указатели RAM, так и ROM в Microchip C18? - PullRequest
9 голосов
/ 17 мая 2011

Когда я объявляю функцию, которая принимает const char*, и я передаю строковый литерал, я получаю

Предупреждение: [2066] несоответствие квалификатора типа в назначении

потому что строковые литералы rom const char*. То же самое и наоборот.

Несмотря на то, что PIC - это гарвардская архитектура, память отображается в одно смежное адресное пространство, поэтому теоретически должна быть возможна одинаковая поддержка указателей ram и rom. Вероятно, я должен использовать указатели rom, потому что они 24-битные, в то время как ram-указатели 16-битные.

Однако просто приведение const char* к const rom char* не работает.

Ответы [ 2 ]

4 голосов
/ 17 мая 2011

К сожалению, это неотъемлемое ограничение компилятора Microchip C18. Указатель в C18 может указывать либо на ПЗУ, либо на ОЗУ, но не на оба.

Именно поэтому вы найдете дублированные функции для операций с ПЗУ и ОЗУ, например, в Библиотеках приложений Microchip:

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

Компилятор Hi-Tech PICC-18 имеет соответствующее адресное пространство, определенное во время выполнения, что позволяет более гибко использовать указатель.Это одна из причин, по которой я отказался от C18 в пользу PICC-18.

См. Ответы на этот вопрос и Джон 1013 * Сравнение Hi-Tech PICC-18 иMPLAB C18 для большего понимания.

1 голос
/ 03 апреля 2015

Добавление к ответу 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));
}

^ Это не фактический код, скорее псевдо-код. Кроме того, я не уверен, что это эффективно.

...