реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Вопрос по АРМ LPC
-=Space=-
сообщение Jun 6 2006, 14:09
Сообщение #16


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 14-01-05
Из: Москва Зеленоград
Пользователь №: 1 962



Что то я туплю, уже целый день туплю.
где то глюк есть.

Вообщем по UART запускаю процедуру IAP, зашиваю коэффициенты во флешь, результат выполнения этой процедуры запихиваю в буфер + устанавливаю счетчик байт на отправку
следущим запросом хочу получить этот результат, но !
при этом запросе получаю 000 , т.е. буфер пуст и счетчик кем то сброшен.
При пошаговой отладке место сброса буфера не обнаруживается, но стоит поставить breakpoint на прерывание от uarta, и я сразу вижу что буфер со счетчиком изменены

Поставив точку останова на доступ к ячейке памяти нашел, что трет переменную и буфер процедура
__segment_init() - стандартная процедура выполняется еще до main()
но кто вызывает ее и зачем мне выяснить не удалось
Если закоментировать процедуру IAP то проблемы нет

RAM юзается до адреса 0x87F, т.е. 0x0400_0000 - 0x0400_087F
В описании на IAP написано чт оюзаются последнии 16 байт RAM, вроде не пресекамся, даже близко

Ткните пальцем что я не правильно делаю.

-------------------
поставил точку останова не адрес 0 и она сработала
значит это ресет
вот тольок какой то задерженный, почему дает выйди из процедуры и не проявлется при пошаговой отладке?
всеравно не понятно
PLL выключен
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 6 2006, 14:25
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(-=Space=- @ Jun 6 2006, 17:09) *
Поставив точку останова на доступ к ячейке памяти нашел, что трет переменную и буфер процедура
__segment_init() - стандартная процедура выполняется еще до main()
но кто вызывает ее и зачем мне выяснить не удалось

Правильная процедура для инициализации неиспользуемой памяти нулями в инициализируемом сегменте даных . Располагайте свои буфера в неинициализированной памяти (смотрите __no_init
но будут проблемы при старте не через Вашу IAP процедуру), либо, что правильно, инициализируйте их самостоятельно данными из Flash уже в main() а не в IAP процедуре.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
-=Space=-
сообщение Jun 6 2006, 16:05
Сообщение #18


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 14-01-05
Из: Москва Зеленоград
Пользователь №: 1 962



я так почти везде и делаю
все глобальные пременные, которые я сам инициализирую, я объявляю как __no_init,
но с данным буфером и счетчиком такой фокус не пойдет
по значсению 0 я и определяю нужно мне что то отвечать на запрос или нет.
а если при включении там останется мусор?

Вопрос свелся не почему вызывается __segment_init() и зачем он нужен
а почему после writeflash(), причем не сразу, а именно с задержкой следует reset?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 6 2006, 16:46
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(-=Space=- @ Jun 6 2006, 19:05) *
Вопрос свелся не почему вызывается __segment_init() и зачем он нужен
а почему после writeflash(), причем не сразу, а именно с задержкой следует reset?

Вопрос звучал _совсем_ не так.

По reset - вычитывайте исходники writeflash().
Прерывания, надеюсь, запрещены?
Watchdog - как у Вас?
Версия Bootloader какая? Без официальных багов с PLL?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 6 2006, 23:29
Сообщение #20


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Чую, прерывания разрешены и всё падает на ресет. Это если конечно writeflash() не кривая.
А в конце RAM зарезервированно 32 байта.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
-=Space=-
сообщение Jun 7 2006, 05:50
Сообщение #21


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 14-01-05
Из: Москва Зеленоград
Пользователь №: 1 962



Цитата
По reset - вычитывайте исходники writeflash().

Не совсем понял, это про что?
Цитата
Прерывания, надеюсь, запрещены?

прерывания отключаются при входе в flashwrite()
и вновь разрешаются при выходе из нее
Цитата
Watchdog - как у Вас?

никогда не использовался
в моем коде нет команд работы с WD, а после ресета он вроде выключен.
может его IAP включать?
Цитата
Версия Bootloader какая? Без официальных багов с PLL?

Команда 55 выдала 0x01 0x40
кстати PLL выключен , проц работает на частоте кварца 11,059МГц
(это из соображений минимизации потребления)
Go to the top of the page
 
+Quote Post
-=Space=-
сообщение Jun 7 2006, 06:09
Сообщение #22


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 14-01-05
Из: Москва Зеленоград
Пользователь №: 1 962



Цитата(GetSmart @ Jun 7 2006, 03:29) *
Чую, прерывания разрешены и всё падает на ресет. Это если конечно 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;
}
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 7 2006, 06:57
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Код
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';

Сообщение отредактировал zltigo - Jun 7 2006, 08:06


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
-=Space=-
сообщение Jun 7 2006, 07:25
Сообщение #24


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 14-01-05
Из: Москва Зеленоград
Пользователь №: 1 962



Цитата(zltigo @ Jun 7 2006, 10:57) *
Что-то более чем мутное с буфером и адресацией в нем.

RealByte это union из 4 байт которым может читаться как int как float или как 4 отдельных байта
ну мне просто нужен не типизированный 4 байтовый буфер , и я так вышел из положения
исходники RealByte были выше

Кстати провел опыт:
сразу после reseta посылаю стаус WD, там должен появиться бит если сброс произошел из-за таймаута WD. Получаю 00, т.е. Reset "внешний", не WDшный.

Вот только происходит он не сразу, я успеваю отправить как минимум один байт - подтверждение что команда выполнена (просто байт 0x01)
Бывает что успеваю и запросить ответ - результат выполнения функции flashWrite
(всего по протоколу получается 9 байт)
но вероятность этого мала, получилось всего 1- 2 раза.
0x01 принимается всегда.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 7 2006, 07:35
Сообщение #25


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Покажите-ка как объявляется "iap_entry"
Ну и "RealByte" заодно.
И ещё "flashParams" и "flashResult".
В каком режиме скомпилена прога ARM or THUMB?
И не понял что это такое:
const RealByte ParamInEEPROM[2048] @ "EEPROM" = {.....}
Можно "дословно" это написать? Дело ведь в ИАРе происходит?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 7 2006, 08:08
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



А в стеке место есть под буфер?
100 против 1, что нет.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 7 2006, 08:30
Сообщение #27


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



А можно увидеть вырезку из дизассемблера для процедуры flashWrite ?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
-=Space=-
сообщение Jun 7 2006, 09:40
Сообщение #28


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 14-01-05
Из: Москва Зеленоград
Пользователь №: 1 962



Вообщем выкладываю почти весь проект
в основном модули которые интересны
все остальные сенсорные модули имеют туже структуру что и sensor_radiation.cpp


Цитата
А в стеке место есть под буфер?
100 против 1, что нет.

в стеке 1024 байта, помоему более чем достаточно
а точно локальные переменные в стеке хранятся?
надо проверить
Прикрепленные файлы
Прикрепленный файл  1.ZIP ( 32.6 килобайт ) Кол-во скачиваний: 54
 
Go to the top of the page
 
+Quote Post
-=Space=-
сообщение Jun 7 2006, 10:49
Сообщение #29


Частый гость
**

Группа: Свой
Сообщений: 105
Регистрация: 14-01-05
Из: Москва Зеленоград
Пользователь №: 1 962



И всетаки ошибка со стеком была
исправил.
функция flashwrite() вызывается по uart, а это в прерывании
т.е. стек юзается не CSTACK , а IRQ_STACK
а он размером 0x100
он затирает адресса возвратов из функций в модуле main()
увеличил стек IRQ_STACK до 0х400

после сделал
RealByte buffer[512/sizeof (long)]; глобальным

не помогло , всеравно reset походит

может быть нельзя вызывать функции IAP из пррываний?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 7 2006, 11:30
Сообщение #30


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата
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;

Хотя прерывание не исправляйте. Чё-то у Вас оно как-то неуклюже написано. И лучше не напрягаться, а то долго объяснять мне придётся что к чему.

Почему-то нашёл только один вектор для таймера.

Сообщение отредактировал GetSmart - Jun 7 2006, 11:33


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 08:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01486 секунд с 7
ELECTRONIX ©2004-2016