|
Прерывания в Atmega128 |
|
|
|
Mar 11 2015, 09:51
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Цитата Я полагаю, что у bootloader'а своя таблица прерываний, начинающаяся с загрузочной области. Т.е. если МК стартует сверху, то и таблица прерываний тоже там. не совсем так - всего четыре варианта BOOTRST IVSEL Адрес сброса Начальный адрес векторов прерываний 1 0 $0000 $0002 1 1 $0000 Адрес сброса в загрузочном секторе + $0002 0 0 Адрес сброса в загрузочном секторе $0002 0 1 Адрес сброса в загрузочном секторе Адрес сброса в загрузочном секторе + $0002
Сообщение отредактировал alexeyv - Mar 11 2015, 09:54
|
|
|
|
|
Mar 12 2015, 08:54
|

Местный
  
Группа: Свой
Сообщений: 253
Регистрация: 28-12-07
Из: Украина г. Первомайск
Пользователь №: 33 716

|
AT90CAN Boot... CODE .cseg .org THIRDBOOTSTART ; boot size 2048words 4096 bytes 0xF800 (Dump 0x1F000)
jmp BOOTRESET ; Bootloader Reset Handler .org 0xF802 ; External Interrupt Request 0 reti .org 0xF804 ; External Interrupt Request 1 reti .org 0xF806 ; External Interrupt Request 2 reti .org 0xF808 ; External Interrupt Request 3 reti .org 0xF80A ; External Interrupt Request 4 reti .org 0xF80C ; External Interrupt Request 5 reti .org 0xF80E ; External Interrupt Request 6 reti .org 0xF810 ; External Interrupt Request 7 reti .org 0xF812 ; Timer/Counter2 Compare Match reti .org 0xF814 ; Timer/Counter2 Overflow reti .org 0xF816 ; Timer/Counter1 Capture Event reti .org 0xF818 ; Timer/Counter1 Compare Match A reti .org 0xF81A ; Timer/Counter Compare Match B reti .org 0xF81C ; Timer/Counter1 Compare Match C reti .org 0xF81E ; Timer/Counter1 Overflow reti .org 0xF820 ; Timer/Counter0 Compare Match reti .org 0xF822 ; Timer/Counter0 Overflow jmp boot_T0_ovf ; .org 0xF824 ; CAN Transfer Complete or Error reti .org 0xF826 ; CAN Timer Overrun reti .org 0xF828 ; SPI Serial Transfer Complete reti .org 0xF82A ; USART0, Rx Complete reti .org 0xF82C ; USART0 Data Register Empty reti .org 0xF82E ; USART0, Tx Complete reti .org 0xF830 ; Analog Comparator reti .org 0xF832 ; ADC Conversion Complete reti .org 0xF834 ; EEPROM Ready reti .org 0xF836 ; Timer/Counter3 Capture Event reti .org 0xF838 ; Timer/Counter3 Compare Match A reti .org 0xF83A ; Timer/Counter3 Compare Match B reti .org 0xF83C ; Timer/Counter3 Compare Match C reti .org 0xF83E ; Timer/Counter3 Overflow jmp boot_T3_ovf ; .org 0xF840 ; USART1, Rx Complete jmp _b_rxd1 ; Get byte via USART! .org 0xF842 ; USART1, Data Register Empty reti .org 0xF844 ; USART1, Tx Complete reti .org 0xF846 ; 2-wire Serial Interface reti .org 0xF848 ; Store Program Memory Read reti
BOOTRESET: ; Bootloader reset point! ;---- STACK INIT --------; ldi tmp, low(ramend) ; out SPL,tmp ; ldi tmp,high(ramend) ; out SPH,tmp ; cli ;---- Move_interrupts ---; in tmp,MCUCR ; Get MCUCR mov tmp1,tmp ; ori tmp,(1<<IVCE) ; Enable change of Interrupt Vectors out MCUCR,tmp ; ori tmp1,(1<<IVSEL) ; Move interrupts to Boot Flash section out MCUCR,tmp1 ; Переключили вектора прерываний на секцию BOOT!
bla-bla-bla
jmp RESET ; переходим на основную программу!
Main CODE jmp RESET ; Reset Handler .org INT0addr ; External Interrupt Request 0 reti .org INT1addr ; External Interrupt Request 1 reti .org INT2addr ; External Interrupt Request 2 reti .org INT3addr ; External Interrupt Request 3 reti .org INT4addr ; External Interrupt Request 4 reti .org INT5addr ; External Interrupt Request 5 reti .org INT6addr ; External Interrupt Request 6 reti .org INT7addr ; External Interrupt Request 7 reti .org OC2addr ; Timer/Counter2 Compare Match reti .org OVF2addr ; Timer/Counter2 Overflow reti .org ICP1addr ; Timer/Counter1 Capture Event reti .org OC1Aaddr ; Timer/Counter1 Compare Match A reti .org OC1Baddr ; Timer/Counter Compare Match B reti .org OC1Caddr ; Timer/Counter1 Compare Match C reti .org OVF1addr ; Timer/Counter1 Overflow reti .org OC0addr ; Timer/Counter0 Compare Match reti .org OVF0addr ; Timer/Counter0 Overflow jmp T0_ovf ; ;-----------------------; .org CANITaddr ; CAN Transfer Complete or Error ;jmp can_int reti ; .org OVRITaddr ; CAN Timer Overrun ;jmp can_ovf reti ;-----------------------; .org SPIaddr ; SPI Serial Transfer Complete reti .org URXC0addr ; USART0, Rx Complete reti .org UDRE0addr ; USART0 Data Register Empty reti .org UTXC0addr ; USART0, Tx Complete reti .org ACIaddr ; Analog Comparator reti .org ADCCaddr ; ADC Conversion Complete reti .org ERDYaddr ; EEPROM Ready reti .org ICP3addr ; Timer/Counter3 Capture Event reti .org OC3Aaddr ; Timer/Counter3 Compare Match A reti .org OC3Baddr ; Timer/Counter3 Compare Match B reti .org OC3Caddr ; Timer/Counter3 Compare Match C reti .org OVF3addr ; Timer/Counter3 Overflow jmp T3_ovf ; .org URXC1addr ; USART1, Rx Complete jmp _rxd1 ; Get byte vis USART! .org UDRE1addr ; USART1, Data Register Empty reti .org UTXC1addr ; USART1, Tx Complete reti .org TWIaddr ; 2-wire Serial Interface reti .org SPMRaddr ; Store Program Memory Read reti
RESET: ; ;---- STACK INIT ------; ldi tmp, low(ramend) ; out SPL,tmp ; ldi tmp,high(ramend) ; out SPH,tmp ; ;----------------------; clr zero ; clr loop2 ; ;--- Move_interrupts --; in tmp,MCUCR ; Get MCUCR ori tmp,(1<<IVCE) ; Enable change of Interrupt Vectors out MCUCR,tmp ; out MCUCR,zero ; Вернули прерывания на основную программу! ;----------------------; sts WDTCR,zero ; disable watchdog Timer sei ; enable interrupts
Открой апнот на свой проц, количество прерываний и их имя впиши таким же образом, проблемы отпадут. Дальше уже делать что душа пожелает... Какой протокол для загрузчика и соответственно сам алгоритм работы и общение с бутом. Я долго не игрался, взял за основу обмена команды как у загрузчика Renesas, добавил шифрование и проверку CRC каждой посылки.
|
|
|
|
|
Mar 12 2015, 09:55
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Цитата(alexeyv @ Mar 11 2015, 15:51)  не совсем так - всего четыре варианта
BOOTRST IVSEL Адрес сброса Начальный адрес векторов прерываний 1 0 $0000 $0002 1 1 $0000 Адрес сброса в загрузочном секторе + $0002 0 0 Адрес сброса в загрузочном секторе $0002 0 1 Адрес сброса в загрузочном секторе Адрес сброса в загрузочном секторе + $0002 Можно подробнее? Недавно столкнулся с необходимостью использовать прерывания в загрузчике.
|
|
|
|
|
Mar 12 2015, 10:14
|

Местный
  
Группа: Свой
Сообщений: 253
Регистрация: 28-12-07
Из: Украина г. Первомайск
Пользователь №: 33 716

|
Цитата(demiurg1978 @ Mar 12 2015, 11:55)  Можно подробнее? Недавно столкнулся с необходимостью использовать прерывания в загрузчике. Чем мой пример не нравится? В течении 3х тактов меняем значение, если этого не сделать, прерывания будут срабатывать в (main) программе! Переключили и бут становится как обычная программа в майне со всеми прерываниями. По большому счету нужны таймеры и один аппаратный протокол.
|
|
|
|
|
Mar 12 2015, 10:19
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Цитата(pavel-pervomaysk @ Mar 12 2015, 16:14)  Чем мой пример не нравится? В течении 3х тактов меняем значение, если этого не сделать, прерывания будут срабатывать в (main) программе!
Переключили и бут становится как обычная программа в майне со всеми прерываниями. По большому счету нужны таймеры и один аппаратный протокол. Вы не поняли. Подробнее рассказать, как работает каждый режим.
|
|
|
|
|
Mar 13 2015, 04:18
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
BOOTRST_____IVSEL__Адрес сброса_________________________Начальный адрес векторов прерываний 1______________0____$0000_______________________________$0002 1______________1____$0000_______________________________Адрес сброса в загрузочном секторе + $0002 0______________0____Адрес сброса в загрузочном секторе_____$0002 0______________1____Адрес сброса в загрузочном секторе_____Адрес сброса в загрузочном секторе + $0002
FUSE-бит BOOTRST определяет место, откуда будет стартовать программа, если есть бутлоадер, то устанавливаем этот бит (и не забываем про настройки компилятора!) Если бутлоадер работает с периферией по прерываниям и Вы не хотите мешать обработчики бутлоадера и основной проги, то для этого существует бит IVSEL, который перемещает указатель на таблицу прерываний в секцию бутлоадера. Алгоритм работы с бутлоадером: 1. запускается бутлоадер, прерывания запрещены 2. проверяется, например, запрос на обновление ПО или другие действия загрузчика 3. таблица перемещается в секцию бутлоадера, прерывания разрешаются 4. Работа в бутлоадере: ПО перешивается полностью, вместе со своей таблицей прерываний и т.д. и т.п. 5. прерывания запрещаются, таблица переводится в секцию приложения 6. переход на основную прогу.
Что еще хотите узнать?
Сообщение отредактировал alexeyv - Mar 13 2015, 04:20
|
|
|
|
|
Mar 13 2015, 05:25
|

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

|
Цитата(alexeyv @ Mar 13 2015, 07:18)  Что еще хотите узнать? У меня есть к вам вопрос: Откуда берется смещение $0002 между стартовым адресом и началом таблицы прерываний? Скажем, в хидере для ATmega8 (IAR EWAVR: iom8.h) точки входа в таблицу прерываний определены так: Код #define RESET_vect (0x00) #define INT0_vect (0x02) #define INT1_vect (0x04) Откуда следует, что таблица прерываний разделяет вектор RESET со стартовым адресом. Кроме того, у МК архитектуры AVR, имеющих более 8К флеша, каждый вектор прерывания в таблице занимает уже не 2, а 4 байта (соответственно 1 и 2 слова инструкций).
|
|
|
|
|
Mar 13 2015, 08:57
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
to Xenia! Это экзамен? 1. 0x00, 0x02, 0x04 и т.п. - это СЛОВАРНЫЕ адреса. AVR хоть и 8-ми разрядный МК, но память программ у него 16-ти битная 2. действительно на каждый вектор отводится 4 байта (у ТС это m1281/1280, разговор не идет про m8). Смотрим любой листинг: Код 0: 0c 94 6f 03 jmp 0x6de; 0x6de <__ctors_end> 4: 0c 94 8c 03 jmp 0x718; 0x718 <__bad_interrupt> 8: 0c 94 8c 03 jmp 0x718; 0x718 <__bad_interrupt> c: 0c 94 8c 03 jmp 0x718; 0x718 <__bad_interrupt> 10: 0c 94 8c 03 jmp 0x718; 0x718 <__bad_interrupt> 14: 0c 94 8c 03 jmp 0x718; 0x718 <__bad_interrupt> 18: 0c 94 75 15 jmp 0x2aea; 0x2aea <__vector_6> 1c: 0c 94 8a 15 jmp 0x2b14; 0x2b14 <__vector_7> 20: 0c 94 9f 15 jmp 0x2b3e; 0x2b3e <__vector_8> 24: 0c 94 8c 03 jmp 0x718; 0x718 <__bad_interrupt> 0c 94 - это команда jmp, вторые два байта - 16-ти разрядный адрес перехода 3. Про смещение. 0x00 - адрес перехода по ресету (так сказать немаскируемое прерывание у AVR МК), соответственно 0x02 - начало таблицы остальных прерываний 4. Условно всю таблицу прерываний можно разделить на две части: область перехода по ресету и область переходов по остальным прерываниям. FUSE-бит BOOTRST отвечает только за размещения области перехода по ресету, а бит IVSEL в MCUCR (относительно m1281/1280) - за размещение остальной таблицы переходов по прерываниям (причем смещение у нее равно 2 слова - для перехода по ресету в случае совпадения области размещения двух частей таблицы). Отсюда и возникают четыре варианта размещения всей таблицы. 5. По всем остальным возникающим вопросам можно почитать даташит (у ТС это m1281/1280): раздел 13 "Interrupts". Я не очень хороший учитель
Сообщение отредактировал alexeyv - Mar 13 2015, 09:09
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|