Я пишу функцию обратного вызова на C. Она предназначена для инициализации датчика I2C и вызывается по завершении каждого (раздельного) шага конфигурации; после 9-го звонка аппарат практически готов к работе.
Основная идея функции такова:
void callback(void)
{
static uint8_t calls = 0;
if (++calls == 9) {
// Finalise device setup (literally a single line of code)
}
}
Моя проблема в том, что приведенный выше оператор if никогда не вводится, несмотря на то, что функция вызывается 9 раз.
Код (дез)ассемблера для моей функции кажется разумным (за исключением трюка subi . 0xFF
для приращения, несмотря на включение инструкции inc
):
00000a4c <callback>:
a4c: 80 91 9e 02 lds r24, 0x029E
a50: 8f 5f subi r24, 0xFF ; 255
a52: 80 93 9e 02 sts 0x029E, r24
a56: 89 30 cpi r24, 0x09 ; 9
a58: 09 f0 breq .+2 ; 0xa5c <callback+0x10>
a5a: 08 95 ret
a5c: 2e e1 ldi r18, 0x1E ; 30
a5e: 35 e0 ldi r19, 0x05 ; 5
a60: 41 e0 ldi r20, 0x01 ; 1
a62: 60 e0 ldi r22, 0x00 ; 0
a64: 84 e7 ldi r24, 0x74 ; 116
a66: 0c 94 c7 02 jmp 0x58e ; 0x58e <twi_set_register>
Я пишу код для микросхемы Atmel AVR и, таким образом, компилирую с помощью avr-gcc. У меня нет значимых возможностей отладки кода (у меня нет доступа к программатору JTAG, и в любом случае функция асинхронная/расщепленная; печать USART слишком медленная).
Однако у меня есть доступ к логическому анализатору, и я смог определить ряд вещей, поместив while (1) ;
операторов в код:
- вызывается функция - если я помещаю бесконечный цикл в начале функции, микроконтроллер зависает
- функция должна быть вызвана 9 раз - триггером для функции является связь I2C, и на предыдущем шаге она зависает сразу после первой связи; Я могу наблюдать 9 полных и действительных сообщений I2C
- вызовы увеличиваются внутри функции - если я добавляю
if (calls == 0) { while (1) ; }
после увеличения, он не зависает - вызовы никогда не бывают ненулевыми в начале функции — если я добавляю
if (calls) { while(1) ; }
перед приращением, он не зависает
У меня совсем нет идей.
Есть ли у кого-нибудь какие-либо предложения относительно того, что может вызвать это, или даже новые шаги по отладке, которые я мог бы предпринять?
0x029E
находится в.data
(он находится во внутренней SDRAM, поэтому должен быть доступен для чтения/записи) - person sapi   schedule 04.09.2013calls
ever не равно нулю (до оператора приращения), и включу бесконечный цикл, если это так, то этот цикл не сработает. - person sapi   schedule 04.09.2013calls
на 0. Может быть, вы найдете способ проверить это. - person Ingo Leonhardt   schedule 04.09.2013