ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
25 апреля
386096
fk0, легенда (08.02.2013 18:12 - 20:23, просмотров: 4002)
PIC18 и callbacks (вообще любые функции вызываемые по указателю) для MCU с объёмом FLASH > 64КБайт вызывают проблемы (hitech-C 9.51pl2 с опцией --cp=16) известного плана: адрес функции шире собственно указателя и старшие биты обрезаются. С опцией --cp=24 эта проблема уходит, но приходят массово множество других, лучше сразу забыть. Остаётся такие функции вручную класть в сегмент lowtext. Проблема в том, что в итоге практически вся программа окажется в lowtext (на ту же область претендует и const, что совсем печально). Ибо #pragma psect text=lowtext действует на весь модуль в целом. В других компиляторах, более приличных, в таких случях используют промежуточную функции (вида jmp real_function), размещаемые в нижнем участке памяти. Можно поступить также: #ifndef CONCAT #define CONCAT(x, y) _CONCAT(x, y) #define _CONCAT(x, y) x##y #endif #ifndef STRINGIFY #define __STRINGIFY(str) #str #define STRINGIFY(str) __STRINGIFY(str) #endif /* non static on PIC18 */ #define NSTATIC /* на других платформах NSTATIC=static */ /* для callback функций */ // ,global,reloc=2,class=LOWCODE // asm(STRINGIFY(CONCAT(CONCAT(__end_of_,name),:))); #define CB_GLOBAL global #define CB_LOCAL local #define CB_FUNC(cb_type, type, name, args) \ static type CONCAT(_,name) args; /* real function */ \ /* NO STATIC! */ type name args; /* proxy function */ \ asm("psect lowtext"); \ asm(STRINGIFY(cb_type) " " STRINGIFY(CONCAT(_,name))); \ asm("local " STRINGIFY(CONCAT(__,name))); /* make real function local */ \ asm("global " STRINGIFY(CONCAT(?__,name))); \ asm("dw " STRINGIFY(CONCAT(?__,name))); \ asm(STRINGIFY(CONCAT(CONCAT(_,name),:))); \ asm("goto " STRINGIFY(CONCAT(__,name))); \ asm("fncall " STRINGIFY(CONCAT(_,name)) "," STRINGIFY(CONCAT(__,name))); \ /* eliminate "unused function" error */ \ static const char CONCAT(__void_,__LINE__) = (unsigned long)CONCAT(_,name)&0; \ static type CONCAT(_,name) args /* real function */ Декларация (в месте определения функции) такая (пример): CB_FUNC(CB_LOCAL, NSTATIC int, flash_writer, (char *buf, unsigned size)) { ... return 0; } Для глобальных функций используется CB_GLOBAL и без NSTATIC. Принцип работы упомянут в тексте выше.
[ZX]