Перейти к содержанию
    

Сергей Борщ

Модератор
  • Постов

    10 928
  • Зарегистрирован

  • Посещение

  • Победитель дней

    31

Весь контент Сергей Борщ


  1. Да, это работает, спасибо. Но хотелось бы, чтобы конец сегмента, или начало требуемого массива в тексте модуля *.с, а не в *.xcl , и адрес вычислялся на этапе компиляции Стоп. Вычислялся адрес или размещались данные? Для вычисления адреса вполне работает intrinsic-функция __segment_end("INTVEC"). А рулить размещением из .C можно только в одном случае: размещение констант по абсолютному адресу. Во всех остальных случаях это невозможно, ибо С с адресами не работает. Он знает только смещения в пределах перемещаемого сегмента (участка сегмента), а абсолютные адреса взамен этих смещений проставляет линкер после размещения сегмента. Возможно имеет место неправильный подход к проблеме. Если программа не использует прерываний то INTVEC состоит из одного вектора (RESET). Далее возможны два варианта в зависимости от содержания .xcl: следующий за этим сегментом адрес будет равен двум(байтам) либо будет "дырка" на неиспользуемые вектора. Но опять же предугадать какой вариант будет в конкретном случае не смотря в .xcl невозможно. Может вы изложите задачу более подробно, с каким-нибудь примитивным примером?
  2. а... Я-то думал вы сначала даташит про bootloader прочитали... Setting the Boot Loader Lock Bits by SPM To set the Boot Loader Lock Bits, write the desired data to R0, write “X0001001” to SPMCR and execute SPM within four clock cycles after writing SPMCR. Интересно, что же может делать функция с загадочным названием __DataToR0ByteToSPMCR_SPM? Не пользовался, но могу предположить что для процессоров с более 64К памяти, т.е. с адресом в 24 бита? Ну нет в функциях команды SPM очистки буфера The temporary buffer will auto-erase after a page write operation or by writing the RWWSRE bit in SPMCR. А макрос может выглядеть так: while(SPMCR & (1<<SPMEN)); Согласно правилам языка высокого уровня С если имя файла в директиве #include указано в двойных кавычках то компилятор ищет его в текущей директории, т.е. в папке проекта. Если же в угловых - то в папках указанных компилятору в опциях как include path. Поэтому flash.h искать в папках IAR не имело смысла - он должен быть в исходниках от "аплекухи 910".
  3. Если узнать и разместить надо на этапе компиляции - то в .xcl определить свой сегмент сразу после определения INTVEC и до остальных кодовых сегментов. В этот сегмент и поместить нужное. Если на этапе выполнения - __segment_end("INTVEC") в С и SFB(INTVEC) в асм.
  4. ой мама... "На колу мочало...". В intrinsics.h есть макросы >Очистить буфер, занести слово в буфер, _SPM_FILLTEMP(Addr,Data) > записать буфер, _SPM_PAGEWRITE(Addr) >биты защиты выстывить _SPM_LOCKBITS(Data) Там же полезные _SPM_ERASE(Addr) _SPM_GET_LOCKBITS() _SPM_GET_FUSEBITS() Они вызывают "в IAR функции для самопрограмирования": __DataToR0ByteToSPMCR_SPM() __AddrToZByteToSPMCR_SPM() __AddrToZWordToR1R0ByteToSPMCR_SPM() Или я опять вопроса не понял?
  5. Постараюсь по мере возможностей. Сначала сделаю отступление: эти функции я в своей работе пока не использую, поскольку в части проектов у меня загрузчик написан на асме а в части я использую AES Loader из аппликашки Атмела. С этими функциями я баловался еще в версии 2.28 (сейчас нашел тот исходник, там судя по исходнику их прототипы были описаны в pgmspace.h. Вот тот исходник: #include <iom8.h> #include <inavr.h> #include <pgmspace.h> void ErasePage (unsigned char page); const __root __flash unsigned char TestFill[64] @ (0x10 << 6) = {1,2,3,4,5}; void main (void) { DDRC = (1<<2)|(1<<3); PORTC = 0; ErasePage(0x10); for(;;) PORTC ^= (1<<2); } void ErasePage(unsigned char page) @ "BLS" { _SPM_ERASE((unsigned int)page << 6); while(SPMCR & (1<<SPMEN)) PORTC |= (1<<3); __DataToR0ByteToSPMCR_SPM(0, (1<<RWWSRE)|(1<<SPMEN)); }
  6. Все правильно, только препроцессор здесь ни при чем. Препроцессор тупо заменяет один текст другим, а все остальное делает компилятор. Да, правильно. А меня чего-то заклинило что это делает препроцессор. И очень меня это смущало. Спасибо, теперь "отпустило" :-) Действительно, при таком раскладе все становится гармоничным. Возможно я где-то более подробно читал какая из частей компилятора занимается вычислением констант и в голове ошибочно отложился препроцессор.
  7. Тем что в некоторых компиляторах long long состоит из вдвое большего количества бит чем long?
  8. Имеено так. Препроцессор по умолчанию считает все данные как int. Во избежание подобных недоразумений следует писать #define FCLK 14745600ULL, т.е объявлять константу типа unsigned long long или 14745600UL, т.е. unsigned long
  9. Имел в виду цифры версии. В 4.10 есть, а в моей 3.10 нет. Да, извиняюсь. Я поискал упоминание версии в постах а в тему и не посмотрел :-) В нем описываются прототипы функций. Сами тела __intrinsic- функций знает компилятор. Это позволяет ему встраивать тела функций в код очень эффективно. Боюсь такой вариант не пройдет. Особенно последняя смесь асма и С. Если нет возможности перейти на более свежую версию - то имеет смысл эти функции написать самому на асме (как в приложенных файлах от апликашки AES loader). Однако такой вариант будет менее эффективным ибо компилятор не сможет встроить такие функции. Это наиболее здравое решение. Снизу вверх проекты конвертятся легко.spm.ZIP
  10. Верни все взад. __IAR_SYSTEMS_ASM__ определяется автоматически если файл обрабатывается ассемблером. А если С-компилятором, то автоматически определяется __IAR_SYSTEMS_ICC__. Это позволяет один и тот же хидер подключать и с С и асм-файлам.
  11. Не знаю что считать старшей версией, у меня в 4.10B лежит в каталоге IAR\AVR\INC
  12. Это вызовет выравнивание по длине машинного слова. Для IBM PC, ARM это будет 4 байта, для MSP430 2 байта, для AVR - 1 байт. заводить для обмена временные переменные для которых тип структуры объявлен с #pragma pack
  13. Обрати внимание на строчку .xcl: -H1895 -h(CODE)00-25 общие исходные файлы? Не совсем понял о каком буфере идет речь, но если о команде SPM, то обрати внимание на функции и макросы из intrinsics.h: #define _SPM_FILLTEMP(Addr,Data) \ __AddrToZWordToR1R0ByteToSPMCR_SPM((void __flash*)(Addr), (Data), 0x01) #define _SPM_PAGEWRITE(Addr) \ __AddrToZByteToSPMCR_SPM((void __flash*)(Addr), (0x05)) Ну если описать толково, то beer_warrior не должен отказаться включить в FAQ :-)
  14. Скорее всего я чего-то не понимаю, но все же: как может вызваться в этом примере вложенное прерывание если VICVectAddr = 0; стоит в самом конце обработчика? Ведь пока не сделан VICVectAddr = 0 контроллер не выдаст адрес следующего обработчика?
  15. AVR и Epson lx-800

    А нет ли у него буфера на строку? Т.е. Не нужно ли послать CR чтобы началась печать?
  16. Да, именно это. Тогда оставьте c_startup как есть (точнее отключите от проекта чтобы брался библиотечный) и просто в .xcl измените: -Z(CODE)INTVEC=1800-1825 /* 19 Interrupt vectors * 2 bytes each */ /* Fill unused interrupt vector's with RETI */ -H1895 -h(CODE)1800-1825 -Z(CODE)TINY_F=1826-18FF -Z(CODE)NEAR_F,SWITCH,INITTAB,DIFUNCT=1826-1FFF -Z(CODE)CODE=1826-1FFF -Z(CODE)TINY_ID,NEAR_ID=1826-1FFF -Z(CODE)CHECKSUM#1FFF Причем лучше в форме $PROJ_DIR$\mynew.xcl Тогда при переносе проекта в другую папку не придется переписывать путь заново.
  17. __root char const __flash * copyright "Слава мне, победителю драконов!" :-)) Возможно переменнная объявляется в application а обращение к ней из bootloader section. Обе части компилятся как отдельные программы. В общем хоть и редко, но бывает надо.
  18. Ужас :-) 1) Все же присоединюсь к Игорю и порекомендую два отдельных проекта. 2) фуз BOOTRST дает только переход по сбросу на BOOTADDRESS. Остальные вектора не трогаются. Остальные вектора переназначаются на загрузчик битом IVSEL. Поэтому можно иметь две таблицы векторов (одну для режима загрузчика вторую для боевого). Только прописывать одну из них надо будет на асме. 3) #pragma vector используется точно так же как в обычной программе. вектор в данном случае означает смещение относительно начала сегмента INTVEC. Чтобы таблица векторов попала в BOOT-область надо в .xcl испавить -Z (CODE) INTVEC = 0-26 на -Z(CODE) INTVEC = 1800-1826 (пишу по памяти, насчет 26 мог ошибиться). Мимо. перед использованием @ вставить #pragma segment = "LOADER" Только учти, что до main вызывается c_startup, которая живет в библиотеке и попадет в сегмент CODE, а уже из c_startup вызывается main. Тебе придется подключить исходник c_startup к своему проекту и исправить в нем RSEG CODE на RSEG LOADER. Исходник лежит в папке IAR\avr\src\lib Сначала признайся - будешь делать один проект или два? Будешь использовать одну таблицу векторов или две?
  19. Проблема явно где-то в другом месте, потому что у меня следующий код работает во множестве процессоров без всяких выравниваний уже лет пять: void SetHex(void) { // пример функции BASE=16; } typedef struct { char Name[10]; void (*Action)(void); } tDictionary; tDictionary __flash Dictionary[] = { { "HEX", SetHex}, { "DECIMAL", DECIMAL }, { ".", DOT }, { "@", Reference }, { "!", Dereference }, { "SP.", stackdump }, {"LOOK", LOOK }, {"DUMP", DUMP }, {0, 0} // end of dictionary }; static tDictionary __flash *LP; for ( LP = Dictionary; LP->Action !=NULL; LP++ ) { // seach word if ( strcmp_P(token,LP->Name) == 0 ) break; } if ( LP->Action != NULL) // execute if token was found LP->Action(); else // else seach digit if (!pushDigit(token)) { // !!! can't interpret static __flash char str[] = " is undefined"; ErrMes(str,token); break; }
  20. LPC2138/IAR

    Да, выравнивание виновато. Есть два пути решения: 1) При описании типа структуры сделать так: #pragma pack(push,1) typedef struct { ... }tMy_struct; #pragma pack(pop) это заставить обращаться к элементам структуры побайтно, т.е. правильно но медленнее. 2) Если это возможно то выровнять структуры на 4 байта.
  21. Да выкинь его вообще из проекта. Он подлинкуется из библиотеки. P.S. у нас праздники, до понедельника на природу уезжаю, если до понедельника не разберешься - пиши мылом, постараюсь помочь.
  22. Попробуй держать открытым окно регистров и в момент получения сообщения посмотри что он кажет в SR. Одна из причин "сам уходит туда" - если стек портится и возврат происходит в непонятное место.
  23. А в пониженное потребление не уходишь? Когда ядро спит такое и получается, если память не изменяет.
  24. Нет,я не пытался ее собрать до конца. 1) Просто добавить его в список файлов 2)Изменить расширение на принятое у IAR .s79. 3)Переписать его заново ибо ассемблеры совсем не похожи. Возможно в примерах они и нужны, но я без крайней необходимости cstartup не трогаю. Поэтому по умолчанию подлинковывается уже готовый из библиотеки. Сейчас глянул этот .S: Я бы код начиная с метки Reset_Handler по комментарий // Setup Stack for each mode (инициализация периферии) перенес бы на С в начало main или в функцию __low_level_init(), а все остальное делает стандартный IARовский cstartup который подлинковывается из библиотеки. Да, надо. Так возьмите его из примера и подключите к проекту.
  25. Тогда надо писать два варианта "Для тех кто видит МК впервые" и "для мигрирующих с асма или с другого проца".
×
×
  • Создать...