|
WinAVR 200701.., Не могу понять где глюк |
|
|
|
Apr 18 2007, 14:40
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Чип M168, компилирую с опцией -Os, с O0 использовать не могу т.к. hex получается больше 16k.. Девайс периодически перезагружается, MCUSR показывает Reset Source - 0 (прыжек на адрес 0), через ~1-8 часов работы..
В main при инициализации заполнил область стека тестовым паттерном 0xA5 после этого: 1. девайс начал иногда вместо ребута подвисать (через те же 1-8 часов работы), прерывания продолжают работать.. (WatchDog пока не включаю чтоб не мешал) 2. Заметил, что некая long переменная K, которую обновляю в основном цикле программы: K = X; (где X long переменная равная xxxx, и X = (volatile long)Y; ) иногда принимает значение: 0xA5A5xxxx, когда ожидается 0x0000xxxx. (переменные X и Y - имеют правильные значения)
Промониторил стек после очередного ребута - за границу 256 байт - не выходит и не пересекается с другими структурами данных. float, sprintf, printf в программе не применяю.
Собсно вопрос, может есть известные баги WinAVR 200701xx, которые бы могли это объяснить?
|
|
|
|
|
Apr 18 2007, 15:02
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(defunct @ Apr 18 2007, 15:40)  2. Заметил, что некая long переменная K, которую обновляю в основном цикле программы: K = X; (где X long переменная равная xxxx, и X = (volatile long)Y; ) иногда принимает значение: 0xA5A5xxxx, когда ожидается 0x0000xxxx. (переменные X и Y - имеют правильные значения) Приведите весь код где используються переменные K, X и Y Анатолий.
|
|
|
|
|
Apr 18 2007, 15:47
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Код volatile U32 rtc_time;
struct { U32 sys_time; // in seconds (from system reset) TRTC_REC rtc; // 6 переменных U8 (yy.mm.dd.hh.mm.ss) ... } rtcContext;
struct { .... U32 WhenToUpdateCounters; .... } DeviceDesc;
static inline U8 ILock(void) { U8 retval = SREG; cli(); return retval; }
static inline void IUnlock( U8 iStatus) { SREG = iStatus; }
void RTC_UpdateSysTime(void) { U8 iStatus = ILock(); rtcContext.sys_time = rtc_time; IUnlock( iStatus ); }
void RTC_ReloadContext(void) { RTC_UpdateSysTime(); if (GetRTC( &rtcContext.rtc ) != ACK ) { // update rtc read-error counter if (DeviceDesc.stats.rtcErrors < 0xFFFF) DeviceDesc.stats.rtcErrors += 1; } else if ( (rtcContext.sys_time > DeviceDesc.WhenToUpdateCounters) && ( (rtcContext.rtc.minutes == 0) || (rtcContext.rtc.minutes == 30) ) ) { // ТУТ НИЧЕГО БОЛЕЕ НЕ ДЕЛАЕТСЯ.. привожу как есть - только имитация работы DeviceDesc.WhenToUpdateCounters = rtcContext.sys_time + (60 * 30);; <-- DeviceDesc.WhenToUpdateCounter и есть переменная "K" } }
/*********************************************** * (1 Hz clock) * ***********************************************/ SIGNAL (INT0_vect) { rtc_time += 1; Set_Callback( &RTC_ReloadContext, 0, TASK_SINGLECALL ); } rtc_time - переменная Y rtcContext.sys_time - переменная X DeviceDesc.WhenToUpdateCounters - переменная K RTC_ReloadContext будет вызвана в основном цикле программы, и после выполнения - удалена из очереди.
|
|
|
|
|
Apr 18 2007, 17:15
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(defunct @ Apr 18 2007, 16:47)  RTC_ReloadContext будет вызвана в основном цикле программы, и после выполнения - удалена из очереди. А очередь обладает свойством атомарности? Что будет если из очереди начинает удаляться функция, в этот момент происходит прерывание, в очередь добавляется новая функция, по окончании прерывания, заканчивает удаляться предыдущая функция? Какой RTOS вы пользуетесь? Анатолий.
|
|
|
|
|
Apr 18 2007, 18:02
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(aesok @ Apr 18 2007, 16:15)  А очередь обладает свойством атомарности? Что будет если из очереди начинает удаляться функция, в этот момент происходит прерывание, в очередь добавляется новая функция, по окончании прерывания, заканчивает удаляться предыдущая функция? Должна обладать. Запуск и удаление происходит так: if (slot[i] != NULL) { U8 iStatus = ILock() __func *temp = __slot[i]; __slot[i] = NULL; IUnlock( iStatus ); temp(); } Цитата Какой RTOS вы пользуетесь? В этом проекте я RTOS не использую. Спасибо за ваш комент, помониторю на предмет ошибок очереди. PS: А что насчет 0xA5A5xxxx, как это могло случиться в приведенном выше коде?
|
|
|
|
|
Apr 18 2007, 18:16
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(defunct @ Apr 18 2007, 19:02)  что насчет 0xA5A5xxxx, как это могло случиться в приведенном выше коде? Пока нет мыслей. Анатолий.
|
|
|
|
|
Apr 18 2007, 19:26
|

учащийся
    
Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249

|
Цитата(defunct @ Apr 18 2007, 14:40)  2. Заметил, что некая long переменная K, которую обновляю в основном цикле программы: K = X; (где X long переменная равная xxxx, и X = (volatile long)Y; ) иногда принимает значение: 0xA5A5xxxx, когда ожидается 0x0000xxxx. (переменные X и Y - имеют правильные значения) Это может показывать что значение stack pointer каким то образом портится. Почему? Наверно переменная которая портится, располагается в стеке. Если значение SP каким то образом сместилось , при обрашении к стеку , переменные (изза того что они адресуются относительно SP) могут быть прочитаны из другой ячейки .
--------------------
Зачем лаять на караван , когда на него можно плюнуть?
|
|
|
|
|
Apr 18 2007, 19:30
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(_artem_ @ Apr 18 2007, 20:26)  Это может показывать что значение stack pointer каким то образом портится. Почему? Наверно переменная которая портится, располагается в стеке. Если значение SP каким то образом сместилось , при обрашении к стеку , переменные (изза того что они адресуются относительно SP) могут быть прочитаны из другой ячейки . Нет, в GCC нет адесации относительно указателя стека. Анатолий.
|
|
|
|
|
Apr 18 2007, 19:42
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(_artem_ @ Apr 18 2007, 20:39)  Тогда как же в gcc адресуются временные переменные живущие на время выполнения функции и обитаюшие в стеке? Это называется Frame Pointer, и он живет в регистре Y. Анатолий.
|
|
|
|
|
Apr 18 2007, 19:59
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(_artem_ @ Apr 18 2007, 20:45)  Эт в смысле хард и софт тек в иар ? В avr-gcc один общий стек. Но для доступа к локальным переменным используеться регистр Y (FP). Анатолий.
|
|
|
|
|
Apr 18 2007, 20:52
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Apr 18 2007, 21:19)  Уточню еще один момент. 0xA5A5xxxx проявляется не при первом обновлении переменной "K"... При первом - все в порядке.. Обращений к "K" в других местах программы - нет.
Конкретную проблему с этой переменной я устранил другим путем - поменял условие события, т.о. надобность в U32 переменной отпала. Ребуты продолжаются.. А по-моему зря Вы убрали U32 переменную. Как Вы теперь узнаете что прога близка к перезагрузке ? Я бы в месте где идет работа с этой переменной поставил что-то типа if (K==0xA5A5xxxx) { ............ // здесь вывод SP, Y ну и всякой другой отладочной инфы // куда-нибудь (если есть куда), ну или хотя бы в порт while (1); }
|
|
|
|
|
Apr 18 2007, 20:53
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(defunct @ Apr 18 2007, 21:19)  Конкретную проблему с этой переменной я устранил другим путем - поменял условие события, т.о. надобность в U32 переменной отпала. Ребуты продолжаются.. На 99% ошибка в вашей программе. Только не подумайте что я заявляю что GCC совершенно безглючный. Чем отлаживаете? Поробуйте поставить брейк на переменной К, вернув ей тип long. Проверте работу с указателями, самая частая ошибка. Возможно гдето пропустили ILock()/ IUnlock(). Поодключайте в программе разные блоки. Ищите! Анатолий.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|