Ви не увійшли.
Так, дистанционно, сложно помочь. Осуществляйте сборку последовательно. Сначала убедитесь что ваши прогаммы исполняются в секции загрузчика, например простейший блинк, что-бы проверить настройки комоновшика. Постепенно, добавляя функциональность, проверяйте корректность исполнения. Не помешало бы воспользоваться нормальным отладчиком. Очень часто, не видят ошибок даже бывалые профессионалы, и приходится применять более развитые средства отладки.
IVSEL в MCUCR устанавливается в начале майна.
Boot Lock bit BLB02 и остальные блокировки не стоят.
avr-objcopy -j .text -j .data ... , компилировал что с опциями -j, что без них - виснет одинаково.
Светодиод прерывание не зажигает, то есть типа заходит в прерывание, но куда оно заходит х.з.
Виснет собственно намертво, так что даже вачдог не спасает, причем, ручной ресет кнопкой помогает.
Note: If Interrupt Vectors are placed in the Boot Loader section and Boot Lock bit BLB02 is
programmed, interrupts are disabled while executing from the Application section. If Interrupt Vectors are
placed in the Application section and Boot Lock bit BLB12 is programed, interrupts are disabled while
executing from the Boot Loader section.
00007000 <__vectors>:
7000: 0c 94 34 38 jmp 0x7068 ; 0x7068 <__ctors_end>
7004: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
...
Ну раз прерывания не с нуля начинаются, проверьте бит IVSEL в MCUCR.
Кстати можно засветить ножкой светодиод когда программа входит в прерывание, так будет понятно, входит ли она туда вообще.
Все примерно правильно. У меня "батники" еще проще.
И знаете, меня терзают смутные сомнения на счет опций -j "avr-objcopy -j .text -j .data"
-j sectionname
--only-section=sectionname
Copy only the named section from the input file to the output file.
This option may be given more than once. Note that using this
Вы в этом уверены? (У меня всегда без -j было)
А как на счет
[Секция .bss]
В секции .bss появляются неинициализированные глобальные или статические переменные.
Ну или другие, какие бы то не были секции, их точно можно исключить?
count не в bss?
Честно говоря этими секциями я никогда не интересовался. Загрузчик писал только раз, примерно таким же способом и он работал, к сожалению я сейчас не дома, не могу посмотреть даже есть ли там прерывания вообще.
Не забыл, таблица векторов прерываний перенесена в область бута, исходник:
...
uint8_t m = MCUCR;
MCUCR = m | (1 << IVCE); //Enable change of Interrupt Vectors
MCUCR = m | (1 << IVSEL); //Move interrupts to Boot Flash section
...
ISR(USART_RX_vect) {
RxBuff[RxCount++] = UDR0;
}
Дисасемблер:
ATmegaBOOT_168_atmega328_pro_8MHz.elf: file format elf32-avr
Disassembly of section .text:
00007000 <__vectors>:
7000: 0c 94 34 38 jmp 0x7068 ; 0x7068 <__ctors_end>
7004: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7008: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
700c: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7010: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7014: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7018: 0c 94 48 38 jmp 0x7090 ; 0x7090 <__vector_6>
701c: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7020: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7024: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7028: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
702c: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7030: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7034: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7038: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
703c: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7040: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7044: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7048: 0c 94 52 38 jmp 0x70a4 ; 0x70a4 <__vector_18>
704c: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7050: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7054: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7058: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
705c: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7060: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
7064: 0c 94 46 38 jmp 0x708c ; 0x708c <__bad_interrupt>
00007068 <__ctors_end>:
7068: 11 24 eor r1, r1
706a: 1f be out 0x3f, r1 ; 63
706c: cf ef ldi r28, 0xFF ; 255
706e: d8 e0 ldi r29, 0x08 ; 8
7070: de bf out 0x3e, r29 ; 62
7072: cd bf out 0x3d, r28 ; 61
00007074 <__do_clear_bss>:
7074: 23 e0 ldi r18, 0x03 ; 3
7076: a0 e0 ldi r26, 0x00 ; 0
7078: b1 e0 ldi r27, 0x01 ; 1
707a: 01 c0 rjmp .+2 ; 0x707e <.do_clear_bss_start>
0000707c <.do_clear_bss_loop>:
707c: 1d 92 st X+, r1
0000707e <.do_clear_bss_start>:
707e: a8 31 cpi r26, 0x18 ; 24
7080: b2 07 cpc r27, r18
7082: e1 f7 brne .-8 ; 0x707c <.do_clear_bss_loop>
7084: 0e 94 80 39 call 0x7300 ; 0x7300 <main>
7088: 0c 94 19 3c jmp 0x7832 ; 0x7832 <_exit>
0000708c <__bad_interrupt>:
708c: 0c 94 00 38 jmp 0x7000 ; 0x7000 <__vectors>
00007090 <__vector_6>:
//прерывание по срабатыванию вачдога----------------------------------
ISR(WDT_vect) {
7090: 1f 92 push r1
7092: 0f 92 push r0
7094: 0f b6 in r0, 0x3f ; 63
7096: 0f 92 push r0
7098: 11 24 eor r1, r1
//здесь делать пока ничего не надо
}
709a: 0f 90 pop r0
709c: 0f be out 0x3f, r0 ; 63
709e: 0f 90 pop r0
70a0: 1f 90 pop r1
70a2: 18 95 reti
000070a4 <__vector_18>:
//Прерывание по приему байта последовательным портом------------------
ISR(USART_RX_vect) {
70a4: 1f 92 push r1
70a6: 0f 92 push r0
70a8: 0f b6 in r0, 0x3f ; 63
70aa: 0f 92 push r0
70ac: 11 24 eor r1, r1
70ae: 2f 93 push r18
70b0: 3f 93 push r19
70b2: 8f 93 push r24
70b4: 9f 93 push r25
70b6: ef 93 push r30
70b8: ff 93 push r31
//RxBuff[RxCount++] = UDR0;
70ba: 80 91 64 01 lds r24, 0x0164 ; 0x800164 <RxCount>
70be: 90 91 65 01 lds r25, 0x0165 ; 0x800165 <RxCount+0x1>
70c2: 9c 01 movw r18, r24
70c4: 2f 5f subi r18, 0xFF ; 255
70c6: 3f 4f sbci r19, 0xFF ; 255
70c8: 30 93 65 01 sts 0x0165, r19 ; 0x800165 <RxCount+0x1>
70cc: 20 93 64 01 sts 0x0164, r18 ; 0x800164 <RxCount>
70d0: 20 91 c6 00 lds r18, 0x00C6 ; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
70d4: fc 01 movw r30, r24
70d6: ea 59 subi r30, 0x9A ; 154
70d8: fe 4f sbci r31, 0xFE ; 254
70da: 20 83 st Z, r18
}
70dc: ff 91 pop r31
70de: ef 91 pop r30
70e0: 9f 91 pop r25
70e2: 8f 91 pop r24
70e4: 3f 91 pop r19
70e6: 2f 91 pop r18
70e8: 0f 90 pop r0
70ea: 0f be out 0x3f, r0 ; 63
70ec: 0f 90 pop r0
70ee: 1f 90 pop r1
70f0: 18 95 reti
... Что я делаю не правильно? ...
Все. Про таблицу векторов прерываний забыли? Загляните в makefile и документацию и станет понятно.
Есть программа, она компилируется и все работает со всеми прерываниями. Далее, мне необходимо ее использовать как загрузчик.
В атмеге238 загрузчик использует последние 4, 2 или 0,5 кБ флеши, выставляется фьюзами. Я использую 4 кБ. Следовательно устанавливаю оба фьюза размера бута и так же фьюз бутресета. Этот же адрес я даю компилятору: -Wl,--section-start=.text=0x7000. Все остальные опции компилятора я не меняю.
Еще переношу таблицу прерываний в область загрузчика:
uint8_t m = MCUCR;
MCUCR = m | (1 << IVCE); //Enable change of Interrupt Vectors
MCUCR = m | (1 << IVSEL); //Move interrupts to Boot Flash section
Батник для компиляции:
avr-g++ -g -Wall -Os -mmcu=atmega328p -DF_CPU=8000000L -DMAX_TIME_COUNT=F_CPU>>4 -DNUM_LED_FLASHES=1 -DBAUD_RATE=57600 -DDOUBLE_SPEED -c -o ATmegaBOOT_168.o ATmegaBOOT_168.c
avr-g++ -g -Wall -Os -mmcu=atmega328p -DF_CPU=8000000L -DMAX_TIME_COUNT=F_CPU>>4 -DNUM_LED_FLASHES=1 -DBAUD_RATE=57600 -DDOUBLE_SPEED -Wl,--section-start=.text=0x7000 -o ATmegaBOOT_168_atmega328_pro_8MHz.elf ATmegaBOOT_168.o
avr-objcopy -j .text -j .data -O ihex ATmegaBOOT_168_atmega328_pro_8MHz.elf ATmegaBOOT_168_atmega328_pro_8MHz.hex
Компилируется, работает до возникновения прерывания (прихода байта по компорту), если отключаю линию RxD все работает.
Что я делаю не правильно?
Загрузчик использует специальную область памяти программ, а не стандартную. Это требует специфического плана компоновки.
Специальная область памяти - это последние n кБ флеши. Специфический план компоновки - это что?
Посмотрите в бинарнике по каким адресам расположен код самого загрузчика, может один из них находится в не области памяти из которой разрешена запись на flash, то это и будут проблемы линковки.
Все начинается c 7000h и занимает чуть больше 2 кБ.
Адрес так же может быть указан в исходнике.
Вячеслав Азаров пише:Скорее всего вы напутали в инстукциях линкера. Для программы и загрузчика планы размещения сегментов разные.
Можно чуть подробнее или ссылку?
Загрузчик использует специальную область памяти программ, а не стандартную. Это требует специфического плана компоновки. А также установки необходимых фузов при программированиии. Мэйк файл, расположенный в какаталоге родного загрузчика, содержит специальную инструкцию комновщика, изменяющую адрес размешения программы
Посмотрите в бинарнике по каким адресам расположен код самого загрузчика, может один из них находится в не области памяти из которой разрешена запись на flash, то это и будут проблемы линковки.
А прерывания действительно отличаются только адресом куда отправлять данные, так что проблема не в них (если адрес правильный).
Скорее всего вы напутали в инстукциях линкера. Для программы и загрузчика планы размещения сегментов разные.
Можно чуть подробнее или ссылку?
Ничего удивительного. Ваш массив размещен, разными компиляторами, в разных местах, потому и константы смещения различные. А что вычитание вместо сложения, так это оптимизация такая. Магистры все-таки делали!
Дисасемблировал 2 варианта компиляции: через ИДЕ (работает) и через avr-g++ (виснет на прерывании). Все одинаково за исключением строки:
ИДЕ:
2a4: e8 51 subi r30, 0x18 ; 24
avr-g++:
70d6: ea 59 subi r30, 0x9A ; 154
Код прерывания скомпилированный через ИДЕ:
00000272 <__vector_18>:
272: 1f 92 push r1
274: 0f 92 push r0
276: 0f b6 in r0, 0x3f ; 63
278: 0f 92 push r0
27a: 11 24 eor r1, r1
27c: 2f 93 push r18
27e: 3f 93 push r19
280: 8f 93 push r24
282: 9f 93 push r25
284: ef 93 push r30
286: ff 93 push r31
288: 80 91 14 03 lds r24, 0x0314 ; 0x800314 <RxCount>
28c: 90 91 15 03 lds r25, 0x0315 ; 0x800315 <RxCount+0x1>
290: 9c 01 movw r18, r24
292: 2f 5f subi r18, 0xFF ; 255
294: 3f 4f sbci r19, 0xFF ; 255
296: 30 93 15 03 sts 0x0315, r19 ; 0x800315 <RxCount+0x1>
29a: 20 93 14 03 sts 0x0314, r18 ; 0x800314 <RxCount>
29e: 20 91 c6 00 lds r18, 0x00C6 ; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
2a2: fc 01 movw r30, r24
2a4: e8 51 subi r30, 0x18 ; 24
2a6: fe 4f sbci r31, 0xFE ; 254
2a8: 20 83 st Z, r18
2aa: ff 91 pop r31
2ac: ef 91 pop r30
2ae: 9f 91 pop r25
2b0: 8f 91 pop r24
2b2: 3f 91 pop r19
2b4: 2f 91 pop r18
2b6: 0f 90 pop r0
2b8: 0f be out 0x3f, r0 ; 63
2ba: 0f 90 pop r0
2bc: 1f 90 pop r1
2be: 18 95 reti
А это через avr-g++:
000070a4 <__vector_18>:
70a4: 1f 92 push r1
70a6: 0f 92 push r0
70a8: 0f b6 in r0, 0x3f ; 63
70aa: 0f 92 push r0
70ac: 11 24 eor r1, r1
70ae: 2f 93 push r18
70b0: 3f 93 push r19
70b2: 8f 93 push r24
70b4: 9f 93 push r25
70b6: ef 93 push r30
70b8: ff 93 push r31
70ba: 80 91 64 01 lds r24, 0x0164 ; 0x800164 <RxCount>
70be: 90 91 65 01 lds r25, 0x0165 ; 0x800165 <RxCount+0x1>
70c2: 9c 01 movw r18, r24
70c4: 2f 5f subi r18, 0xFF ; 255
70c6: 3f 4f sbci r19, 0xFF ; 255
70c8: 30 93 65 01 sts 0x0165, r19 ; 0x800165 <RxCount+0x1>
70cc: 20 93 64 01 sts 0x0164, r18 ; 0x800164 <RxCount>
70d0: 20 91 c6 00 lds r18, 0x00C6 ; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
70d4: fc 01 movw r30, r24
70d6: ea 59 subi r30, 0x9A ; 154
70d8: fe 4f sbci r31, 0xFE ; 254
70da: 20 83 st Z, r18
70dc: ff 91 pop r31
70de: ef 91 pop r30
70e0: 9f 91 pop r25
70e2: 8f 91 pop r24
70e4: 3f 91 pop r19
70e6: 2f 91 pop r18
70e8: 0f 90 pop r0
70ea: 0f be out 0x3f, r0 ; 63
70ec: 0f 90 pop r0
70ee: 1f 90 pop r1
70f0: 18 95 reti
Разъясните мне бестолковому разницу.
Makefile родной. Правда в оригинальном загрузчике не используются прерывания, может там че дописать надо. Придется опять рыть инет.
Может и надо. Ваш обработчик прерывания, возможно, неправильный. Без окончания операций.