-=Space=- 0 6 июня, 2006 Опубликовано 6 июня, 2006 · Жалоба Что то я туплю, уже целый день туплю. где то глюк есть. Вообщем по UART запускаю процедуру IAP, зашиваю коэффициенты во флешь, результат выполнения этой процедуры запихиваю в буфер + устанавливаю счетчик байт на отправку следущим запросом хочу получить этот результат, но ! при этом запросе получаю 000 , т.е. буфер пуст и счетчик кем то сброшен. При пошаговой отладке место сброса буфера не обнаруживается, но стоит поставить breakpoint на прерывание от uarta, и я сразу вижу что буфер со счетчиком изменены Поставив точку останова на доступ к ячейке памяти нашел, что трет переменную и буфер процедура __segment_init() - стандартная процедура выполняется еще до main() но кто вызывает ее и зачем мне выяснить не удалось Если закоментировать процедуру IAP то проблемы нет RAM юзается до адреса 0x87F, т.е. 0x0400_0000 - 0x0400_087F В описании на IAP написано чт оюзаются последнии 16 байт RAM, вроде не пресекамся, даже близко Ткните пальцем что я не правильно делаю. ------------------- поставил точку останова не адрес 0 и она сработала значит это ресет вот тольок какой то задерженный, почему дает выйди из процедуры и не проявлется при пошаговой отладке? всеравно не понятно PLL выключен Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 6 июня, 2006 Опубликовано 6 июня, 2006 · Жалоба Поставив точку останова на доступ к ячейке памяти нашел, что трет переменную и буфер процедура __segment_init() - стандартная процедура выполняется еще до main() но кто вызывает ее и зачем мне выяснить не удалось Правильная процедура для инициализации неиспользуемой памяти нулями в инициализируемом сегменте даных . Располагайте свои буфера в неинициализированной памяти (смотрите __no_init но будут проблемы при старте не через Вашу IAP процедуру), либо, что правильно, инициализируйте их самостоятельно данными из Flash уже в main() а не в IAP процедуре. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
-=Space=- 0 6 июня, 2006 Опубликовано 6 июня, 2006 · Жалоба я так почти везде и делаю все глобальные пременные, которые я сам инициализирую, я объявляю как __no_init, но с данным буфером и счетчиком такой фокус не пойдет по значсению 0 я и определяю нужно мне что то отвечать на запрос или нет. а если при включении там останется мусор? Вопрос свелся не почему вызывается __segment_init() и зачем он нужен а почему после writeflash(), причем не сразу, а именно с задержкой следует reset? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 6 июня, 2006 Опубликовано 6 июня, 2006 · Жалоба Вопрос свелся не почему вызывается __segment_init() и зачем он нужен а почему после writeflash(), причем не сразу, а именно с задержкой следует reset? Вопрос звучал _совсем_ не так. По reset - вычитывайте исходники writeflash(). Прерывания, надеюсь, запрещены? Watchdog - как у Вас? Версия Bootloader какая? Без официальных багов с PLL? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 6 июня, 2006 Опубликовано 6 июня, 2006 · Жалоба Чую, прерывания разрешены и всё падает на ресет. Это если конечно writeflash() не кривая. А в конце RAM зарезервированно 32 байта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
-=Space=- 0 7 июня, 2006 Опубликовано 7 июня, 2006 · Жалоба По reset - вычитывайте исходники writeflash(). Не совсем понял, это про что? Прерывания, надеюсь, запрещены? прерывания отключаются при входе в flashwrite() и вновь разрешаются при выходе из нее Watchdog - как у Вас? никогда не использовался в моем коде нет команд работы с WD, а после ресета он вроде выключен. может его IAP включать? Версия Bootloader какая? Без официальных багов с PLL? Команда 55 выдала 0x01 0x40 кстати PLL выключен , проц работает на частоте кварца 11,059МГц (это из соображений минимизации потребления) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
-=Space=- 0 7 июня, 2006 Опубликовано 7 июня, 2006 · Жалоба Чую, прерывания разрешены и всё падает на ресет. Это если конечно writeflash() не кривая. А в конце RAM зарезервированно 32 байта. привожу свою процедуру flashWrite() немного соптимизировал ее 1. стирание сектора включено в процедуру записи 2. массив данных во flash всегда начинается с начала сектораи размером не больше сектора потом будет const RealByte ParamInEEPROM[2048] @ "EEPROM" = {.....} т.е. 8K - ровно 1 сектор int flashWrite(void) { RealByte buffer[512/sizeof (long)]; int i,result; __disable_interrupt(); flashParams[0] = 50; // prepare sector flashParams[1] = 16; // start sector flashParams[2] = 16; // end sector iap_entry(flashParams,flashResult); if (flashResult[0] != CMD_SUCCESS) { __enable_interrupt(); return flashResult[0]; } flashParams[0] = 52; // erase sector) flashParams[1] = 16; // start sector flashParams[2] = 16; // end sector flashParams[3] = GetProcessorClockFreq()/1000; // cpu clock freq in KHz iap_entry(flashParams,flashResult); if (flashResult[0] != CMD_SUCCESS) { __enable_interrupt(); return flashResult[0]; } // prepare all sectors for programing flashParams[0] = 50; // prepare sectors flashParams[1] = 16; // start sector flashParams[2] = 16; // last sector iap_entry(flashParams,flashResult); if (flashResult[0] != CMD_SUCCESS) { __enable_interrupt(); return flashResult[0]; } // загрузка буфера for(i=0;i<512/sizeof (long);i++) buffer[i].i = 0xffffffff; buffer[0].i = SensorMic.MicP1; /* .......... */ /* здесь продолжается заполнятся массив */ /* .......... */ flashParams[0] = 51; // copy RAM to Flash flashParams[1] = (unsigned long)ParamInEEPROM; // destination flashParams[2] = (unsigned long)buffer; // source flashParams[3] = 512; // byte count flashParams[4] = GetProcessorClockFreq()/1000; // CCLK in KHz iap_entry(flashParams,flashResult); if (flashResult[0] != CMD_SUCCESS) { __enable_interrupt(); return flashResult[0]; } __enable_interrupt(); return CMD_SUCCESS; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 7 июня, 2006 Опубликовано 7 июня, 2006 (изменено) · Жалоба RealByte buffer[512/sizeof (long)]; .... // загрузка буфера for(i=0;i<512/sizeof (long);i++) buffer[i].i = 0xffffffff; ....... buffer[0].i = SensorMic.MicP1; ....... Что-то более чем мутное с буфером и адресацией в нем. 1. А в стеке место есть под буфер? 2. дабы все было непонятно используем sizeof(long); 3. Ну жуткая необходимость была называть элемент union 'i'; Изменено 7 июня, 2006 пользователем zltigo Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
-=Space=- 0 7 июня, 2006 Опубликовано 7 июня, 2006 · Жалоба Что-то более чем мутное с буфером и адресацией в нем. RealByte это union из 4 байт которым может читаться как int как float или как 4 отдельных байта ну мне просто нужен не типизированный 4 байтовый буфер , и я так вышел из положения исходники RealByte были выше Кстати провел опыт: сразу после reseta посылаю стаус WD, там должен появиться бит если сброс произошел из-за таймаута WD. Получаю 00, т.е. Reset "внешний", не WDшный. Вот только происходит он не сразу, я успеваю отправить как минимум один байт - подтверждение что команда выполнена (просто байт 0x01) Бывает что успеваю и запросить ответ - результат выполнения функции flashWrite (всего по протоколу получается 9 байт) но вероятность этого мала, получилось всего 1- 2 раза. 0x01 принимается всегда. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 7 июня, 2006 Опубликовано 7 июня, 2006 · Жалоба Покажите-ка как объявляется "iap_entry" Ну и "RealByte" заодно. И ещё "flashParams" и "flashResult". В каком режиме скомпилена прога ARM or THUMB? И не понял что это такое: const RealByte ParamInEEPROM[2048] @ "EEPROM" = {.....} Можно "дословно" это написать? Дело ведь в ИАРе происходит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 7 июня, 2006 Опубликовано 7 июня, 2006 · Жалоба А в стеке место есть под буфер? 100 против 1, что нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 7 июня, 2006 Опубликовано 7 июня, 2006 · Жалоба А можно увидеть вырезку из дизассемблера для процедуры flashWrite ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
-=Space=- 0 7 июня, 2006 Опубликовано 7 июня, 2006 · Жалоба Вообщем выкладываю почти весь проект в основном модули которые интересны все остальные сенсорные модули имеют туже структуру что и sensor_radiation.cpp А в стеке место есть под буфер? 100 против 1, что нет. в стеке 1024 байта, помоему более чем достаточно а точно локальные переменные в стеке хранятся? надо проверить 1.ZIP Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
-=Space=- 0 7 июня, 2006 Опубликовано 7 июня, 2006 · Жалоба И всетаки ошибка со стеком была исправил. функция flashwrite() вызывается по uart, а это в прерывании т.е. стек юзается не CSTACK , а IRQ_STACK а он размером 0x100 он затирает адресса возвратов из функций в модуле main() увеличил стек IRQ_STACK до 0х400 после сделал RealByte buffer[512/sizeof (long)]; глобальным не помогло , всеравно reset походит может быть нельзя вызывать функции IAP из пррываний? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 7 июня, 2006 Опубликовано 7 июня, 2006 (изменено) · Жалоба RealByte const * pParamInEEPROM; А Вы уверены, что хотели именно так написать? Это будет указатель на variable (!!!) (а не FLASH), который нельзя будет изменять. Это если конечно в С++ всё не запутали окончательно. Я пишу на Си. Думаю, надо так: const RealByte *pParamInEEPROM; Вызывать из прерываний IAP конечно можно. Однако. Для начала сделайте прерывание от UART с возможностью вложенных прерываний. Что-то типа этого: __arm __irq __nested void UART1Interrupt() { _enaIRQ(); switch(U1IIR & 0x0f) { ..... } _disIRQ(); VICVectAddr = 0; // Clear interrupt in VIC. } Это сделает такой фокус, что внутри прерывания стек будет использоваться глобальный. Поэтому стек прерываний уменьшите до 128..256 байт обратно. typedef void (*IAP)(unsigned long *,unsigned long *); IAP iap_entry =(IAP) IAP_LOCATION; исправьте на typedef void (__interwork *IAP)(unsigned long *,unsigned long *); IAP iap_entry =(IAP) IAP_LOCATION; Хотя прерывание не исправляйте. Чё-то у Вас оно как-то неуклюже написано. И лучше не напрягаться, а то долго объяснять мне придётся что к чему. Почему-то нашёл только один вектор для таймера. Изменено 7 июня, 2006 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться