ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
21 ноября
1032963 Топик полностью
Связанные сообщения
Pic24
Я совсем даже не прав. XC16++ Unofficial C++ compiler for PIC24 and dsPIC chips, based on the official XC16 compiler from Microc...2020-02-23
fk0, легенда (02.09.2020 12:37, просмотров: 584) ответил MBedder на Там не банка, а регистр типа DS у x86, DSPAG называется
В нижнюю половину (0..32кБайт) мапятся регистры (опять LOL) и всегда доступная память, а в верхней половине (32..64кБайт) сделано окно, через которую мапится или программная память в режиме доступа к константным данным, или одна из банок ОЗУ, которых нет если ОЗУ < 32кБайт и обычно в верхнюю половину мапятся константы из программной памяти (секция rodata), ибо по другому их читать можно только спец. инструкциями что малосовместимо с программами на C. 

Соответственно при нормальном программировании лимиты: 32кБайт констант и 32кБайт ОЗУ.


* Исполняемый код из code space читается совершенно отдельно и эта картинка к нему не имеет отношения, считать константы из code space можно либо спец. инструкциями (компилятор напрямую не поддерживает), либо кусок code space замапить в окно и читать как данные, как уже показано на картинке.




Если нужно больше констант, то проще написать функции для копирования из памяти констант в обычное ОЗУ кусочками, мапить другую страницу трудно (см. дальше).


Если нужно больше ОЗУ, то потенциально можно ручками воткнуть в окно другую банку вместо констант (ОЗУ или программную память тоже), но нормальная C-программа тут же перестаёт работать (потому, что ей самой для работы нужны константы -- их в обычной программе полно, в т.ч. неявных, нужных самому компилятору). Можно константы на этапе линковки перенести в нижние 32кБайт ОЗУ, тогда заработает, но это слишком расточительно. Либо писать какие-то функции на ассемблере которые умудряются переключать банки и что-то читать из банки замапленной вместо констант. Уже как-то нетривиально. Либо, поскольку на чтение и запись можно замапить разные банки, на чтение оставить константы, а на запись замапить видеопамять -- так ещё терпимо. Почему кстати много памяти как раз у чипов с видеоконтроллером.


Но толком из C работать с памятью в банках -- невозможно. В компиляторе нет, как я помню, понятия far pointer (как на x86) для переменных (для кода есть, см. ниже) и его толком невозможно сделать. Верней там есть "eedata", но обращение к нему -- руками из ассемблера (он чём я выше написал), компилятор код не сгенерирует. Почему невозможно сделать: для нормальной работы C нужно несколько окон или сегментных регистров, один для работы с текущим указателем, один для констант и т.п. Почему сегментных регистров в x86 -- много (cs, ds, es, fs, gs...) С одним нужно постоянно жонглировать этой банкой, как в PIC18. Практически окажется слишком неэффективно, элементарная функция типа memcpy превращается в игольное ушко наподобии DPTR у x51 (для нормальной работы нужно хотя бы два окна/сегмента, для каждого указателя свой).


** В микрочиповской документации far и near означают совсем другое -- память ниже первых 8-и килобайт может адресоваться инструкциями напрямую (полный адрес умещается в код операции), выше 8-и килобайт как на RISC процессоре (вначале в регистр грузим адрес, потом косвенно обращаемся). Соответственно near -- первые 8 кБайт ОЗУ, far -- всё остальное (все 64 килобайта, остальное через банки, поэтому не надо путать "eedata" и "far").


Код тоже выходит за пределы 64 килослов или килобайт (не помню): регистр PC занимает где-то три байта. Но адреса функций 16-битные. Это достигается тем, что если функция не помещается в нижние 64к программной памяти, то линкер прозрачно пoдсовывает в нижнюю часть памяти thunk который делает jump на полноценный адрес функции. С данными, понятно, так не поступишь.


http://ww1.microchip.com/downloads/en/devicedoc/39733a.pdf

[ZX]