Список

SlickEdit
IAR-AVR
MT-50x
avr_nullptr
empty4
empty5

AVR NULLPTR


Довольно часто при модульном программировании применяется вызов функции по указателю (для CallBack и т.п.)
Типичный синтаксис (кто не в курсе):
typedef void(*func_ptr)( void );

////////////////////////////////////////////////////////////////////////////////
void target_func( void )
{
    __no_operation();
}

////////////////////////////////////////////////////////////////////////////////
int main( void )
{
    static func_ptr fp = target_func;
    fp();
    fp = NULL; // искусственно допускаем ошибку
    fp(); // эх, забыли для отладки влепить ASSERT( fp ); Теперь предстоит найти источник ошибки
}
первый вызов будет корректен, но второй вызове переход на 0x000000 который почти эквивалентен сбросу.
Как найти, из какого файла и какого места был произведен переход ?
Для ARM-архитектуры это не проблема: там есть исключение DataAbort
Но AVR победнее будет, но как решить проблему нахождения источника ошибки сейчас покажу.
Для начала коннектимся через AvrStudio-JTAG/DebugWire к контроллеру и ставим BreakPoint на 0x000000.
Запускаем выполнение программы и ждем попадания на выставленный breakPoint


Далее, берется значение Stack Pointer, и ищутся байты, следующие за этим адресом ( Не включая байт по этому адресу !) .
Для мег с флеш > 128кБ берется три байта, для мег с флеш <= 128кБ берется два байта
и данное значение как есть вбивается в Program Counter (хоть AVR и Little Endian но стек растет с хвоста, и получается как Big Endian )
и попадаете на строку, куда должны были вернутся после выполнения функции


А там уже и номер строки, и имя файла как на ладони (если правда вы сделали экспорт из стороннего компилятора в UBROF-8 )

использованные материалы:
8-bit AVR Instruction Set
Последнее редактирование: 09.07.2015 23:31:27