Программирование AVR: решение проблем, FAQ AVR Studio + avr-gcc: программа ведет себя непредсказуемо Sun, April 23 2017  

Поделиться

нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


AVR Studio + avr-gcc: программа ведет себя непредсказуемо Печать
Добавил(а) microsin   

Возможная причина - переполнение памяти, неверная инициализация стека.

Стек инициализируется в самом начале программы, для этого компилятор avr-gcc компилирует обычно такой код (можно посмотреть во время отладки, если выбрать в меню View -> Disassembler и перейти в самое начало листинга). Например, для микроконтроллера ATmega16:

+00000000:   940C002A    JMP     0x0000002A       прыжок на начало программы
    ..
+0000002A:   2411        CLR     R1               R1 == 0
+0000002B:   BE1F        OUT     0x3F,R1          очистка SREG
+0000002C:   E5CF        LDI     R28,0x5F         загрузка адреса 0x045F
+0000002D:   E0D4        LDI     R29,0x04         загрузка адреса 0x045F
+0000002E:   BFDE        OUT     0x3E,R29        
загрузка стека адресом 0x045F
+0000002F:   BFCD        OUT     0x3D,R28         загрузка стека адресом 0x045F
    ..

В этом примере в стек загружается значение 0x045F (адрес, равный макросу RAMEND из хедера, определяющего ресурсы процессора).

Напомню, что стек у AVR должен начинаться от максимального адреса RAM, и по мере заполнения стека его граница смещается к младшим адресам (стек растет вверх, адрес в указателе стека уменьшается). Предельное минимальное значение указателя стека для микроконтроллера ATmega16 - 0x60, поскольку дальше начинается область SFR (Special Function Registers, регистры специального назначения).

В системе WinAVR адрес начала стека присваивается символу __stack. Если в Вашей системе символ __stack не задан, то возможна неправильная установка стека. Символ __stack можно задать вручную и передать линкеру через командную строку компилятора, например так (в этом примере устанавливается стек для ATmega16, у которого размер RAM равен 1024 байт):
## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS += -Wl,-Map=$(PROJECT).map -Wl,--cref -Wl,--defsym=__stack=0x045F

Адрес начала стека можно посмотреть с помощью программы avr-nm.exe (входит в пакет WinAVR вместе с компилятором avr-gcc). Например, для выходного файла формата ELF это можно сделать так (кроме адреса, будет также выведен тип и размер символов, в списке нужно искать символ __stack):

avr-nm -S rs422.elf
    ..
0000268c 000001aa T __pack_f
00002f7e T __prologue_saves__
0000045f W __stack
00002fee t __stop_program
00001f02 00000062 T __subsf3
00800075 00000008 D __thenan_sf
00000000 a __tmp_reg__   
    ..

Можно также использовать утилиту avr-objdump.exe (также входит в пакет WinAVR):
c:\asm\rs422\default>avr-objdump -x rs422.elf | grep __stack
0000045f  w      *ABS*  00000000 __stack

Общую статистику по использованию памяти может показать утилита avr-size.exe (также входит в пакет WinAVR), например:
c:\asm\rs422\default>avr-size rs422.elf
   text    data     bss     dec     hex filename
  12272     286     591   13149    335d rs422.elf   

Или из Makefile:
@avr-size -C --mcu=${MCU} ${TARGET}
avr-objdump -h -S rs422.elf > rs422.lss
AVR Memory Usage
----------------
Device: atmega16

Program:   12558 bytes (76.6% Full)
(.text + .data + .bootloader)

Data:        877 bytes (85.6% Full)
(.data + .bss + .noinit)

Build succeeded with 1 Warnings...

 

Добавить комментарий


Защитный код
Обновить

Top of Page