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

Ну мне сыкотно так сразу код залить попробывать (всё же так и завалить камень можно).

 

DINT; // выкл. все прерывания
Uint16  val[SIZE]; // константа которая перезаписывается во flash
Uint16  i;
Uint16  Status;

typedef struct {
    Uint32  FirstFailAddr;
    Uint16  ExpectedData;
    Uint16  ActualData;
}FLASH_ST;
FLASH_ST FlashStatus;

Status = Flash_Erase(SECTORH,&FlashStatus);
if(Status != 0) 
{
       ESTOPO;
} 


Status = Flash_Program((Uint16 *) 0x3D8000,val,SIZE,&FlashStatus); // 0x3D8000 - адрес начала секции H
if(Status != 0) 
{
    ESTOPO;
}

  
Status = Flash_Verify((Uint16 *) 0x3D8000,val,SIZE,&FlashStatus);
if(Status != 0) 
{
    ESTOPO;
}  

EINT;

 

Весь код выше в секции ramfank (то есть копируется в ОЗУ) Выполняется по поднятию какого нибудь флага (моя переменная).

Все остальные настройки (такие как конфигурация тактирования) выполнены ранее так как в качестве скелета взял работающий исходник.

 

Что еще посоветуете?

 

Руки зачесались, попробывал, всё работает. Попробывал и не помещать в ОЗУ этот код, всётаки манипуляции с той часть flash где находиться код не произвожу, тоже работает.

 

Щас мысль: может и прерывания запрещать в данном случае нет смысла?

Изменено пользователем ELEKTROS

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


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

Главное с адресами ничего не напутать, чтоб в CSM ничего не записать, а так больше-то и нечего бояться.

На счёт прерываний, в памяти сидит, что их нужно выключать во время запися внутренней флэш-памяти.

 

Попробывал и не помещать в ОЗУ этот код, всётаки манипуляции с той часть flash где находиться код не произвожу, тоже работает.

В ОЗУ помещать необходимо, если только всё стереть хотите, если участки, где нет кода программы, то и нет необходимости.

 

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


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

Подскажите, сейчас мне не совсем загрузчик нужен, но работа тоже с flash (камень f28069).

Выделил я свою секцию в *.cmd, для сохранения констант:

mydata_servise       : > FLASHH,     PAGE = 0

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

#pragma DATA_SECTION(wer, "mydata_servise");
      volatile Uint16 wer=3;

 

Потом смотрю в отладке адрес этой переменной 0x3D8000 как бы правильно, но значение её 0xFFFF. Секцию H использую только для этого. Что еще объявить чтобы по этому адресу появилось присвоенное значение?

Еще интересно если убрать в конфигурации загрузчика галочку на секции H ничего не происходит, если же галочку убрать на других секциях где код находиться, то загрузчик ругается и не прошивает.

 

Для переменных нужно создавать не в

mydata_servise       : > FLASHH,     PAGE = 0

а, в RAM выделить также микро-секцию. я делал так, у себя в .cmd "отрезал" мелкие кусочки,

Просто к сведению, там ведь можно не только склеивать, но и обрезать.

volatile это совсем с другого предназначения, и он тут неуместен.

Для явного указания месторасположения в флеше достаточно указать const. (о, вам там кстати ответили тоже самое)

 

 

Когда например используется #pragma DATA_SECTION , то нужно указывать не переменную, а функцию, например:

#pragma DATA_SECTION(wer, "mydata_servise");
      Uint16 wer (Uint16 *datain)

 

Пишу на память(код на работе), могу гдето описку допустить, но думаю смысл вы поняли.

 

Щас мысль: может и прерывания запрещать в данном случае нет смысла?

Ух, не советовал бы, я наексперементировался... кстати при таймере в прерывании еще иногда работает, и даже иногда пишет верно, но зачастую с сбоями.

А вот если включить прерывание в АЦП, то вообще, только сбои при записи.

Короче я после детальных эксперементов решил всё таки прекратить баловаться с прерываниями.

Писать нужно только данные которые находятся в ОЗУ. В теории можно с секции которая не стирается, но у меня были какие то там сбои, уже точно не помню что именно.

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


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

Насчёт прерываний, не использую в моменты стирания, программирования. Насчёт секция для функций обозначается как CODE_SECTION. DATA_SECTION для данных. У меня структура данных с кучей переменных, одна такая переменная в RAM заведена, а одна типа const во FLASHH. При запуске всего кода структура из FLASHH копируется в RAM функцией memcopy. сохраняется во FLASHH впринципе всё кодом который я приводил выше.

 

Для явного указания месторасположения в флеше достаточно указать const это я понял уже давно, но чтобы конкретное место, знаю только способ через секцию так как я указал выше.

 

Щас уже в отпуск ушёл, но проблема непонятная осталась, а имено не всегда API функции выполняются удачно, процентов 60 случаев все три API функции "долго" весят, а потом выдают неудачный результат. Пробывал подождать 0.1 секунды после выполнения DINT, всё равно тоже самое. Функции API копирую в RAM предварительно, но разницы что копирую что нет, не заметил.

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


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

Занимаюсь аналогичной задачей, но никак не пойму механизм реализации прыжка.

Есть рабочая прошивка - все работает. По CANу приходит команда, что необходимо принять прошивку.Дальше должен быть скачок на бутлодер. Как это сделать? В случае неудачной записи как неубить сам бутлодер?

Смотрю код техаса. Извините за дилетанта - а что произойдент, когда мейн вернет адрес? Как это работает? Я привык к while(1)...

uint32_t main(void)
{
//
// flush SCIA TX port by waiting while it is busy, driverlib.
//
    sciaFlush();
//
// Step 1. Initialize System Control:
// Enable Peripheral Clocks
//
    Device_init();
//
// Step 2. Initialize GPIO:
//
    Device_initGPIO();

//
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
//
    DINT;

//
// init interrupt and vectorTable, driverlib.
//
    Interrupt_initModule();
    Interrupt_initVectorTable();


//
// Disable CPU interrupts and clear all CPU interrupt flags:
//
    IER = 0x0000;
    IFR = 0x0000;

   Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, 5);
    initFlashSectors();

    uint32_t EntryAddr;

//
// parameter SCI_BOOT for GPIO28,29
// refer to cpu1bootrom.h for alternate SCI Boot Pin configurations
//
    EntryAddr = sciGetFunction(SCI_BOOT);
    return(EntryAddr);
}

 

 

 

 

 

 

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


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

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

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

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

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

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

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

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

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

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