|
Bootloader. Не работают прерывания. |
|
|
|
Sep 9 2010, 14:09
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 12-11-08
Пользователь №: 41 579

|
Здравствуйте, уважаемые форумчание! Пишу загрузчик в IAR 5.5. Загрузчик, как положено, отдельным проектом. Вектора и код переместил в загрузочную область: Файл lnkusb647s.xclКод . . . /* Code (flash) segments */ -D_..X_INTVEC_SIZE=F098 /* 4 bytes * 38 vectors */ . . . /* Code memory */ -Z(CODE)INTVEC=F000-(_..X_INTVEC_SIZE-1)
/* Fill unused interrupt vector's with RETI */ -H1895 -h(CODE)F000-_..X_INTVEC_SIZE . . . Код и вектора переместились, это видно из чтения памяти программ. Начало векторов расположено с адреса 0хF000, следом идет код. Код программы: Код . . . int main(void) { __enable_interrupt(); // разрешение прерываний (sei) DDRD |= (1 << PD7); // управление светодиодом EIMSK |= (1 << INT0); // разрешение прерывания MCUCR |= (1 << IVCE); // для записи IVSEL MCUCR = (1 << IVSEL); // вектора в загрузочной области
for(;;) {
} return 0; } #pragma vector = INT0_vect __interrupt void INT0_interrupt() { for(;;) { PORTD |= (1 << PD7); __delay_cycles(4000000);
PORTD &= ~(1 << PD7); __delay_cycles(4000000); } } Когда код идет с нулевого адреса, все нормально прерывание проходит, светодиод мигает. При переносе кода в загрузчик, выполнение программы "сваливается" куда-то непонятно куда. Что я делаю не так? Спасибо
|
|
|
|
|
Sep 9 2010, 15:07
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(Jhohn @ Sep 9 2010, 18:09)  Вектора и код переместил в загрузочную область...Когда код идет с нулевого адреса, все нормально...При переносе кода в загрузчик, выполнение программы "сваливается"... тупой вопрос: при программировании кристалла фьюзы выставляете правильно? адресс RESET вектора совпадает с вашим значением в .org ? (круглый)
|
|
|
|
|
Sep 10 2010, 09:48
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 12-11-08
Пользователь №: 41 579

|
Цитата(kolobok0 @ Sep 9 2010, 19:07)  тупой вопрос: при программировании кристалла фьюзы выставляете правильно? адресс RESET вектора совпадает с вашим значением в .org ? Микроконтроллер at90usb. Вне зависимости от значения fuses bit BOOTRST программа стартует в main(), я это проверял с помощью следующего кода: Код int main(void) { __enable_interrupt(); // разрешение прерываний (sei) DDRD |= (1 << PD7); // управление светодиодом EIMSK |= (1 << INT0); // разрешение прерывания MCUCR |= (1 << IVCE); // для записи IVSEL MCUCR = (1 << IVSEL); // вектора в загрузочной области
for(;;) { PORTD |= (1 << PD7); __delay_cycles(400000);
PORTD &= ~(1 << PD7); __delay_cycles(400000); } return 0; } Не важно выставлен или сброшен бит BOOTRST программа стартует с адекватно с загрузочной области - светодиод мигает, когда запрещены все прерывания, при разрешении прерываний (sei) программа "сваливается".
|
|
|
|
|
Sep 10 2010, 13:19
|

Местный
  
Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035

|
Стартовый адрес линкерного скрипта для бутлоадера совпадает с физическим адресом, который получается с установлением фьюзами размера бутлоадера? Код MCUCR |= (1 << IVCE); // для записи IVSEL MCUCR = (1 << IVSEL); // вектора в загрузочной области И ещё есть большое подозрение, что проблема здесь. Вы смотрели дизасмом после установки IVCE вы успеваете за 4 такта установить IVSEL?
|
|
|
|
|
Sep 10 2010, 14:12
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(xelax @ Sep 10 2010, 17:19)  И ещё есть большое подозрение, что проблема здесь. Вы смотрели дизасмом после установки IVCE вы успеваете за 4 такта установить IVSEL? Скорее всего, проблема не в этом... Наверное, программа прошита не в области бута, а с нулевого адреса. Поэтому она (программа) и стартует при любом BOOTRST: в одном случае - и должна, в другом - пытаются выполниться команды FFFF до тех пор, пока указатель не сбросится в ноль. При выполнении программы перемещаются вектора (изменяется IVSEL) в бут, но поскольку бут пуст, то по прерыванию опять выполняются команды FFFF до сброса указателя в ноль - на начало программы; программа начинает выполняться - и всё заново по кругу...
|
|
|
|
|
Sep 14 2010, 06:59
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 12-11-08
Пользователь №: 41 579

|
Цитата(xelax @ Sep 10 2010, 17:19)  Стартовый адрес линкерного скрипта для бутлоадера совпадает с физическим адресом, который получается с установлением фьюзами размера бутлоадера? Да, совпадают: fuses выставлены words start address=$7800, физически (реально) располагается код, как писал выше, с адреса $F000. Цитата(xelax @ Sep 10 2010, 17:19)  Код MCUCR |= (1 << IVCE); // для записи IVSEL MCUCR = (1 << IVSEL); // вектора в загрузочной области И ещё есть большое подозрение, что проблема здесь. Вы смотрели дизасмом после установки IVCE вы успеваете за 4 такта установить IVSEL? Посмотрел на интерпретацию этих двух команд в ассемлере, приминала не нашел. Дополнительно проделал следующий тест: Код #define CHECK_BIT(ADDRESS,BIT) (ADDRESS & (1<<BIT)) int main(void) { //__enable_interrupt(); DDRD |= (1 << PD7);
EIMSK |= (1 << INT0); MCUCR |= (1 << IVCE); MCUCR = (1 << IVSEL); for(;;) { if(CHECK_BIT(MCUCR, IVSEL)) { PORTD |= (1 << PD7); __delay_cycles(2000000);
PORTD &= ~(1 << PD7); __delay_cycles(2000000); } } //wdtdrv_disable(); //Clear_prescaler(); //scheduler(); return 0; } Светодиод мигает, следовательно выставляется бит IVSEL, но прерывания не проходят. Таки куда-то сваливается.
Сообщение отредактировал Jhohn - Sep 14 2010, 12:08
|
|
|
|
|
Sep 14 2010, 12:07
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 12-11-08
Пользователь №: 41 579

|
Чтение памяти Flash - см. ПРИКРЕПЛЕННЫЙ ФАЙЛ
|
|
|
|
|
Sep 14 2010, 13:21
|

Местный
  
Группа: Свой
Сообщений: 232
Регистрация: 26-02-07
Из: г. Зеленоград
Пользователь №: 25 669

|
Цитата(Jhohn @ Sep 14 2010, 16:07)  Чтение памяти Flash - см. ПРИКРЕПЛЕННЫЙ ФАЙЛ >:10F000000C9462790C946E7818951895189518954B это 1-я строка кода Вашей программы она заносится начиная с адреса 0xF000 (байтовый адрес) что соответствует адресу в словах = 0x7800 т.е. куда то в середину Flash. Скорее всего Вы в Linker - задали формат выходного файла Intel а надо Intel-Extended
--------------------
Вяжешь - вой, а поедешь - песни пой. Между "хочу" и "можно" всегда есть дистанция
|
|
|
|
|
Sep 14 2010, 13:28
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 12-11-08
Пользователь №: 41 579

|
Цитата(IJAR @ Sep 14 2010, 17:21)  >:10F000000C9462790C946E7818951895189518954B это 1-я строка кода Вашей программы она заносится начиная с адреса 0xF000 (байтовый адрес) что соответствует адресу в словах = 0x7800 т.е. куда то в середину Flash. Скорее всего Вы в Linker - задали формат выходного файла Intel а надо Intel-Extended Хм, как же в середину? В прикрепленном файле вся Flash (последняя строка оканчивается командой с адресом 0xFFFF = 65к), по расположению загрузчика в файле видно, что он никак не в середине. В опциях стоит Intel-Extended.
|
|
|
|
|
Sep 14 2010, 13:39
|

Местный
  
Группа: Свой
Сообщений: 232
Регистрация: 26-02-07
Из: г. Зеленоград
Пользователь №: 25 669

|
Цитата(Jhohn @ Sep 14 2010, 17:28)  Хм, как же в середину? В прикрепленном файле вся Flash (последняя строка оканчивается командой с адресом 0xFFFF = 65к), по расположению загрузчика в файле видно, что он никак не в середине.
В опциях стоит Intel-Extended. А Вы можете показать hex файл созданный компилятором?
--------------------
Вяжешь - вой, а поедешь - песни пой. Между "хочу" и "можно" всегда есть дистанция
|
|
|
|
|
Sep 14 2010, 13:44
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 12-11-08
Пользователь №: 41 579

|
Цитата(IJAR @ Sep 14 2010, 17:39)  А Вы можете показать hex файл созданный компилятором? Сделано. ИЗВИНЯЮСЬ ТУТ АДЕРСА С 0XFC00
Сообщение отредактировал Jhohn - Sep 14 2010, 13:50
|
|
|
|
|
Sep 14 2010, 13:50
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 12-11-08
Пользователь №: 41 579

|
Попробовал исправить на 1Е000 комилятор ругается. CODE Fatal Error[e140]: The range declaration used in D:\...lnkusb647s.xcl 91 -Z(CODE)NEAR_F,SWITCH,DIFUNCT=_..X_INTVEC_SIZE-_..X_FLASH_NEND is illegal since 0x1e098 > 0xffff.
Максимум в этом контроллере 0xFFFF. Файл линковки ниже
Сообщение отредактировал Jhohn - Sep 14 2010, 13:59
|
|
|
|
|
Sep 14 2010, 14:09
|

Местный
  
Группа: Свой
Сообщений: 232
Регистрация: 26-02-07
Из: г. Зеленоград
Пользователь №: 25 669

|
Цитата(Jhohn @ Sep 14 2010, 17:50)  Попробовал исправить на 1Е000 комилятор ругается. CODE Fatal Error[e140]: The range declaration used in D:\...lnkusb647s.xcl 91 -Z(CODE)NEAR_F,SWITCH,DIFUNCT=_..X_INTVEC_SIZE-_..X_FLASH_NEND is illegal since 0x1e098 > 0xffff.
Максимум в этом контроллере 0xFFFF. Файл линковки ниже Извиняюсь - на счет 0x1e000 - это я загнул в кристалле 64К должно быть 0xFC00 поскольку Ваш программа грузится с этого байтового адреса Цитата(Jhohn @ Sep 14 2010, 17:50)  Попробовал исправить на 1Е000 комилятор ругается. CODE Fatal Error[e140]: The range declaration used in D:\...lnkusb647s.xcl 91 -Z(CODE)NEAR_F,SWITCH,DIFUNCT=_..X_INTVEC_SIZE-_..X_FLASH_NEND is illegal since 0x1e098 > 0xffff.
Максимум в этом контроллере 0xFFFF. Файл линковки ниже Так, я кажется понял - Вы либо Fuse биты исправте на начало секции загрузчика с 0xF000 или в xcl файле укажите правильный адрес начала FLASH (0xFC00) и все что это тянет за собой
--------------------
Вяжешь - вой, а поедешь - песни пой. Между "хочу" и "можно" всегда есть дистанция
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|