|
Помогите моргнуть лампочкой |
|
|
|
Oct 20 2009, 08:53
|
Группа: Участник
Сообщений: 6
Регистрация: 18-09-09
Пользователь №: 52 449

|
Эта супер-программа должна моргать лампочкой со скважностью ~0,5 сек. Собираю всё в EWB 3.21, шью - PonyProg2000. Не получается заставить её работать в верхних 4 кб mega128. Во фьюзах ставлю галочки у BOOTRST и BOOTSZ1. Подправил адреса в xcl-файле (с 1F000 ). Подскажите где я промахнулся... Код #include <iom128.h> #include <ina90.h> //------------------------------------------------------- void main(void) { long t=0; __disable_interrupt(); MCUCR=(1<<IVCE);MCUCR=(1<<IVSEL);
PORTG = 0xff; DDRG |= 0x08;
__enable_interrupt(); while(1){ if(t++ > 100000){ PORTG ^= 0x08; t=0; } } } //-------------------------------------------------------- Проект также прилагается.
Прикрепленные файлы
Micro.rar ( 16.14 килобайт )
Кол-во скачиваний: 24
|
|
|
|
|
Oct 20 2009, 10:59
|

Частый гость
 
Группа: Свой
Сообщений: 156
Регистрация: 22-09-09
Из: Петергоф
Пользователь №: 52 521

|
Цитата(МП41 @ Oct 20 2009, 13:53)  А разве можно прямо в проверке условия делать инкремент переменной t? Да, действительно.. Код while(1){ if(t > 100000) t++; { PORTG ^= 0x08; так? (не помню.. надо точку с запятой?)
Сообщение отредактировал zltigo - Oct 20 2009, 11:01
Причина редактирования: Бездумное цитирование и многоэтажные подписи.
|
|
|
|
|
Oct 20 2009, 11:27
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Обращаю внимание присутствующих (и особливо суперпривередливого супермодератора), что этот топик не так прост, как можно заключить из его названия. Дело тут не в примитивном ногодрыганьи, а в том, что код, нормально работающий в нижних адресах памяти, не работает в верхних. На новичка Slev мало похож, новички xor-ом не моргают  . Данный пример программы, несомненно тестовый. И будь на месте человека, столкнувшегося с проблемой верхних адресов, профессионал, то он точно так же попытался бы запустить в этих адресах что-то моргающее светодиодиком. Я, к сожалению, не могу ответить на вопрос автора топика, т.к. сама не работала на mega с объемом flash выше 64К и EWB не использую. Однако подозреваю, что здесь что-то не ладно с фузами. Что-то типа того, что стоит защита, запрещающая обращаться к верхним адресам памяти. Такое бывает сплошь и рядом из-за требований обезопасить загрузчик (верхнюю часть памяти от попыток его протестировать через нижную загружаемую часть). Возможно и то, что таблица векторов прерываний оказалась по недосмотру поднята вверх, а старт остался снизу. Тогда тоже может случиться, что main() не получает управления. А вот заниматься поиском ляпов в программе не стоит, поскольку на нижних адресах памяти она работает. В любом случае, заданный вопрос достаточно серьезен, чтобы не вызывать раздражение модератора. Куда большие сомнения в отсутствии профессионализма следовало бы отнести к авторам реплик, не знающих механизма постинкрементации. Программа написана свершенно верно. Проблема же только в том, отчего она не работает в верхних 4К адресного пространства.
|
|
|
|
|
Oct 20 2009, 13:10
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(virtual9900 @ Oct 20 2009, 13:59)  Да, действительно.. (не помню.. надо точку с запятой?) Ну и зачем писать, если не помните? "Действительно" таки нет. Можно. Постинкремент - обычное выражение, результат которого четко документирован, и этот результат, как и результат любого другого выражения, может использоваться как один из операндов опертатора ">", результат которого уже используется в проверке условия.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 20 2009, 14:56
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Проверте настройки линкера - начало области загрузчика и размер секции векторов (там 35 векторов по 4 байта). Ещё проверте фус-биты настройки размера секции загрузчика, фус-бит старта из секции загрузчика. И выключите режим совместимости. Снизу фрагмент файла линкера на котором я осваивал бут-секцию атмеги 128. Выделе фрагмент где описано расположение сегментов во флеш - посмотрите может чемто поможет  CODE
-DBOOT_START_512=1FC00 //константа адрес начала секции загрузчика 512 байт -DBOOT_START_1024=1F800 //константа адрес начала секции загрузчика 1024 байт -DBOOT_START_2048=1F000 //константа адрес начала секции загрузчика 2048 байт -DBOOT_START_4096=1E000 //константа адрес начала секции загрузчика 4096 байт
-DBOOT_START=BOOT_START_4096 /*начало секции загрузчика*/
-DBOOT_SIZE_512=200 -DBOOT_SIZE_1024=400 -DBOOT_SIZE_2048=800 -DBOOT_SIZE_4096=1000 -DBOOT_SIZE=BOOT_SIZE_4096 //размер секции загрузчика
/* Code (flash) segments */ -D_..X_INTVEC_SIZE=8C /* 4 bytes * 35 vectors */ -D_..X_FLASH_TEND=FF /* End of tiny flash memory */ -D_..X_FLASH_NEND=FFFE /* End of near flash memory */ -D_..X_FLASH_END=(1FFFF-2) /* End of flash memory */ //тут указывается конечный адрес памяти минус 2 байта на crc -D_..X_CRC_FLASH_END=(1FFFF) /*указываем что crc16 будет размещаться в конце памяти отведённой для программы*/
/* Code memory */ -Z(CODE)INTVEC=BOOT_START-(BOOT_START+_..X_INTVEC_SIZE-1)
/* Fill unused interrupt vector's with RETI */ -H1895 -h(CODE)BOOT_START-(BOOT_START+_..X_INTVEC_SIZE)
-Z(CODE)TINY_F=(BOOT_START+_..X_INTVEC_SIZE)-(BOOT_START+_..X_FLASH_TEND) -Z(CODE)NEAR_F,SWITCH,DIFUNCT=(BOOT_START+_..X_INTVEC_SIZE)-(BOOT_START+_..X_FLASH_NEND) -Z(CODE)CODE=(BOOT_START+_..X_INTVEC_SIZE)-_..X_FLASH_END -Z(FARCODE)FAR_F=(BOOT_START+_..X_INTVEC_SIZE)-_..X_FLASH_END -Z(CODE)HUGE_F,INITTAB=(BOOT_START+_..X_INTVEC_SIZE)-_..X_FLASH_END -Z(CODE)TINY_ID,NEAR_ID=(BOOT_START+_..X_INTVEC_SIZE)-_..X_FLASH_END -Z(CODE)CHECKSUM=(_..X_CRC_FLASH_END-1)-_..X_CRC_FLASH_END //тут располагается сегмент crc16 - 2 последних байта памяти
//а это ключ линкера для вычисления crc16 по области (CODE)0-(_..X_CRC_FLASH_END-2) //-J2,crc16,1,=(CODE)0-(_..X_CRC_FLASH_END-2) -J2,crc16,1//=(CODE)1E004-1E00b // BOOT_START-(BOOT_START+2)
|
|
|
|
|
Oct 20 2009, 22:01
|
Группа: Участник
Сообщений: 6
Регистрация: 18-09-09
Пользователь №: 52 449

|
Спасибо всем, кто откликнулся (особенно Ксении - за понимание  . В нижних адресах всё работает. При сборке в верхние адреса, ставлю только две галки BOOTRST и BOOTSZ1. Остальные фузы не трогаю. Галочка с М103С снята. В прилагаемом проекте находится правленный xcl-файл (boot_m128.xcl) и в папке Release\List лежат листинги и map-файл (boot_m128.map). Посмотрите на них, плиз, свежим взглядом, может чего я пропустил... 2 memphis_: завтра попробую собрать с твоим фрагментом.
|
|
|
|
|
Oct 21 2009, 03:51
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Slev @ Oct 21 2009, 01:01)  Посмотрите на них, плиз, свежим взглядом, может чего я пропустил... В AppNote AVR231 (AES Bootloader) есть пример универсального xcl - файла для старших адресов. Типа -Z(CODE)INTVEC=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-BOOT_SIZE+IVT_SIZE-1) -Z(CODE)NEAR_F,HUGE_F,SWITCH,INITTAB,DIFUNCT,CODE=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-1) Несколько удобнее, не так ли? По теме - возможны две причины 1) Естественно, несовпадение размеров бут-области с xcl-файлом. Сам я не пользовался, но это про инверсию галок в пони всегда пишут? 2) не обеспечивается программирование старших адресов. Но смотрим файл HEX, вроде в порядке, команда установки сегмента есть.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Oct 21 2009, 08:01
|
Группа: Участник
Сообщений: 6
Регистрация: 18-09-09
Пользователь №: 52 449

|
Вложил картинку про фузы. BOOTSZ=01 - 2048 words - 4096 bytes - F800*2=1F000 2 memphis_: твой фрагмент ничего не изменил, адреса получились такие же. Раньше делал загрузчик для mega16, mega32. Сейчас хотел тупо собрать его для mega128 - не заработал. Всё повыкидовал оттуда, оставил только лампочку - всё равно не хочет работать... Наверное, есть какие-то нюансы для >64K...
Эскизы прикрепленных изображений
|
|
|
|
|
Oct 21 2009, 09:13
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(Slev @ Oct 21 2009, 11:01)  Вложил картинку про фузы. BOOTSZ=01 - 2048 words - 4096 bytes - F800*2=1F000
2 memphis_: твой фрагмент ничего не изменил, адреса получились такие же. В данный момент пишу загрузчик на основе настроек линкера что дал выше - светодиод моргает  Для моргания светодиода ньюансов нет. 1. BOOTSTART у вас выставлен правильно - по ресету прыгаем в секцию загрузчика. 2. Если фусы BOOTSZ10 = 01 то размер секции загрузчика 2048 слов и адрес с которого надо располагать программу 1F000 В моём файле линкера это выглядит так: Код -DBOOT_START_512=1FC00 //константа адрес начала секции загрузчика 512 байт -DBOOT_START_1024=1F800 //константа адрес начала секции загрузчика 1024 байт -DBOOT_START_2048=1F000 //константа адрес начала секции загрузчика 2048 байт -DBOOT_START_4096=1E000 //константа адрес начала секции загрузчика 4096 байт
-DBOOT_START=BOOT_START_2048 /*начало секции загрузчика*/
-DBOOT_SIZE_512=200 -DBOOT_SIZE_1024=400 -DBOOT_SIZE_2048=800 -DBOOT_SIZE_4096=1000 -DBOOT_SIZE=BOOT_SIZE_2048 //размер секции загрузчика Проверил - у меня всё работает. Не работает только в одном случае - если неправильно выставлены биты BOOTSZ10. В вашех hex-файле видно что программа располагается с правильно адреса. Ищите косяки в установке бит BOOTSZ10. Откомпилировал вашу программу у себя слегка изменив с параметрами Код -DBOOT_START_2048=1F000 //константа адрес начала секции загрузчика 2048 байт -DBOOT_START=BOOT_START_2048 /*начало секции загрузчика*/
-DBOOT_SIZE_2048=800 -DBOOT_SIZE=BOOT_SIZE_2048//размер секции загрузчика Попробуйте прошить. CODE #include <iom128.h> #include <ina90.h> //------------------------------------------------------- void main(void) { long t=1000000; __disable_interrupt(); MCUCR=(1<<IVCE);MCUCR=(1<<IVSEL);
PORTG = 0xff; DDRG |= 0x08;
__enable_interrupt(); while(1){ if(t > 0) t--; else { PORTG ^= 0x08; t=1000000; } }
} //--------------------------------------------------------
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|