Перейти к содержанию
    

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

где то глюк есть.

 

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

следущим запросом хочу получить этот результат, но !

при этом запросе получаю 000 , т.е. буфер пуст и счетчик кем то сброшен.

При пошаговой отладке место сброса буфера не обнаруживается, но стоит поставить breakpoint на прерывание от uarta, и я сразу вижу что буфер со счетчиком изменены

 

Поставив точку останова на доступ к ячейке памяти нашел, что трет переменную и буфер процедура

__segment_init() - стандартная процедура выполняется еще до main()

но кто вызывает ее и зачем мне выяснить не удалось

Если закоментировать процедуру IAP то проблемы нет

 

RAM юзается до адреса 0x87F, т.е. 0x0400_0000 - 0x0400_087F

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

 

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

 

-------------------

поставил точку останова не адрес 0 и она сработала

значит это ресет

вот тольок какой то задерженный, почему дает выйди из процедуры и не проявлется при пошаговой отладке?

всеравно не понятно

PLL выключен

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поставив точку останова на доступ к ячейке памяти нашел, что трет переменную и буфер процедура

__segment_init() - стандартная процедура выполняется еще до main()

но кто вызывает ее и зачем мне выяснить не удалось

Правильная процедура для инициализации неиспользуемой памяти нулями в инициализируемом сегменте даных . Располагайте свои буфера в неинициализированной памяти (смотрите __no_init

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я так почти везде и делаю

все глобальные пременные, которые я сам инициализирую, я объявляю как __no_init,

но с данным буфером и счетчиком такой фокус не пойдет

по значсению 0 я и определяю нужно мне что то отвечать на запрос или нет.

а если при включении там останется мусор?

 

Вопрос свелся не почему вызывается __segment_init() и зачем он нужен

а почему после writeflash(), причем не сразу, а именно с задержкой следует reset?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос свелся не почему вызывается __segment_init() и зачем он нужен

а почему после writeflash(), причем не сразу, а именно с задержкой следует reset?

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

 

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

Прерывания, надеюсь, запрещены?

Watchdog - как у Вас?

Версия Bootloader какая? Без официальных багов с PLL?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

А в конце RAM зарезервированно 32 байта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Не совсем понял, это про что?

Прерывания, надеюсь, запрещены?

прерывания отключаются при входе в flashwrite()

и вновь разрешаются при выходе из нее

Watchdog - как у Вас?

никогда не использовался

в моем коде нет команд работы с WD, а после ресета он вроде выключен.

может его IAP включать?

Версия Bootloader какая? Без официальных багов с PLL?

Команда 55 выдала 0x01 0x40

кстати PLL выключен , проц работает на частоте кварца 11,059МГц

(это из соображений минимизации потребления)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чую, прерывания разрешены и всё падает на ресет. Это если конечно 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;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то более чем мутное с буфером и адресацией в нем.

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

ну мне просто нужен не типизированный 4 байтовый буфер , и я так вышел из положения

исходники RealByte были выше

 

Кстати провел опыт:

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

 

Вот только происходит он не сразу, я успеваю отправить как минимум один байт - подтверждение что команда выполнена (просто байт 0x01)

Бывает что успеваю и запросить ответ - результат выполнения функции flashWrite

(всего по протоколу получается 9 байт)

но вероятность этого мала, получилось всего 1- 2 раза.

0x01 принимается всегда.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Покажите-ка как объявляется "iap_entry"

Ну и "RealByte" заодно.

И ещё "flashParams" и "flashResult".

В каком режиме скомпилена прога ARM or THUMB?

И не понял что это такое:

const RealByte ParamInEEPROM[2048] @ "EEPROM" = {.....}

Можно "дословно" это написать? Дело ведь в ИАРе происходит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообщем выкладываю почти весь проект

в основном модули которые интересны

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

 

 

А в стеке место есть под буфер?

100 против 1, что нет.

в стеке 1024 байта, помоему более чем достаточно

а точно локальные переменные в стеке хранятся?

надо проверить

1.ZIP

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И всетаки ошибка со стеком была

исправил.

функция flashwrite() вызывается по uart, а это в прерывании

т.е. стек юзается не CSTACK , а IRQ_STACK

а он размером 0x100

он затирает адресса возвратов из функций в модуле main()

увеличил стек IRQ_STACK до 0х400

 

после сделал

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

 

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

 

может быть нельзя вызывать функции IAP из пррываний?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...