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

 
 
 
Reply to this topicStart new topic
> STM32 Bootloader
Jenya7
сообщение Apr 28 2016, 06:03
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Я написал отдельную программу - бутлоадер. Чтоб разместить ее во флеш нужно изменить стартап файл и линкер файл. и тут у меня трудности. может кто нибудь рассказать как это делать?
под бутлоадер я хочу отвести первые две страницы. линкер и стартап в принципе изменять не надо.
насчет главной программы. в линкере заменил
Код
MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
  CCMRAM (rw)     : ORIGIN = 0x10000000, LENGTH = 64K
}

На
Код
MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08001000, LENGTH = 1024K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
  CCMRAM (rw)     : ORIGIN = 0x10000000, LENGTH = 64K
}

и в system_stm32f30x.c заменил
Код
#define VECT_TAB_OFFSET  0x0

На
Код
#define VECT_TAB_OFFSET  0x1000

а что еще надо поменять?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 28 2016, 06:17
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Jenya7 @ Apr 28 2016, 09:03) *
CODE
  FLASH (rx)      : ORIGIN = 0x08001000, LENGTH = 1024K

Вы уехали за границу доступной памяти. Осетра-то урежте wink.gif , в смысле LENGTH укоротите на размер загрузчика. И в загрузчике аналогично, чтобы получить ошибку если он вдруг налезет на приложение.
QUOTE (Jenya7 @ Apr 28 2016, 09:03) *
а что еще надо поменять?
Зависит от того, что и как вы наворотили в загрузчике. У меня линкер сразу после векторов добавляет размер прошивки в словах (чтобы загрузчик знал, до куда считать CRC), а также резервируется место под CRC.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Apr 28 2016, 06:42
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Сергей Борщ @ Apr 28 2016, 12:17) *
Вы уехали за границу доступной памяти. Осетра-то урежте wink.gif , в смысле LENGTH укоротите на размер загрузчика. И в загрузчике аналогично, чтобы получить ошибку если он вдруг налезет на приложение.
Зависит от того, что и как вы наворотили в загрузчике. У меня линкер сразу после векторов добавляет размер прошивки в словах (чтобы загрузчик знал, до куда считать CRC), а также резервируется место под CRC.

спасибо. укоротил. вроде бежит главная программа но как то странно. запускаю через дебагер – пишет no source file named main.c. и через 30 секунд - это у меня таймаут в бутлоудере - бежит главная программа.

добавил в Startup Script
Код
# Reconfigure vector table offset register to match the application location
set *0xe000ed08 = 0x1000

# Get the application stack pointer (First entry in the application vector table)
set $sp = *(unsigned int*)0x1000

# Get the application entry point (Second entry in the application vector table)
set $pc = *(unsigned int*)0x1004

ничего не изменилось.

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

вроде решил проблему. вот полный код скрипта.
Код
# Set flash parallelism mode to 32, 16, or 8 bit when using STM32 F2/F4 microcontrollers
# Uncomment next line, 2=32 bit, 1=16 bit and 0=8 bit parallelism mode
#monitor flash set_parallelism_mode 2

# Set character encoding
set host-charset CP1252
set target-charset CP1252

# Reset to known state
monitor reset

# Load the program executable
load        

# Reconfigure vector table offset register to match the application location
set *0xe000ed08 = 0x1000

# Get the application stack pointer (First entry in the application vector table)
set $sp = *(unsigned int*)0x1000

# Get the application entry point (Second entry in the application vector table)
set $pc = *(unsigned int*)0x1004

# Reset the chip to get to a known state. Remove "monitor reset" command
#  if the code is not located at default address and does not run by reset.
#monitor reset

# Enable Debug connection in low power modes (DBGMCU->CR)
set *0xE0042004 = (*0xE0042004) | 0x7

# Set a breakpoint at main().
tbreak main

# Run to the breakpoint.
continue


Сообщение отредактировал Jenya7 - Apr 28 2016, 08:11
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 28 2016, 10:50
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Jenya7 @ Apr 28 2016, 09:42) *
кстати а как линкер знает размер прошивки?
Он же сам ее собрал, кто же лучше него может знать?
CODE
    .text :
    {
        _image_start = .;
        KEEP(*(.isr_vector))

        LONG((_image_end - _image_start) / 4);    /* application size, in 4-byte words */
.............
/* после всех text, romem и data: */
    .text.crc :
    {
        . = . + 4;  /* reserve space for CRC */
        _image_end = .;
    } > TEXT


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Apr 28 2016, 15:50
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Сергей Борщ @ Apr 28 2016, 15:50) *
Он же сам ее собрал, кто же лучше него может знать?
Код
    .text :
    {
        _image_start = .;
        KEEP(*(.isr_vector))

        LONG((_image_end - _image_start) / 4);    /* application size, in 4-byte words */
.............
/* после всех text, romem и data: */
    .text.crc :
    {
        . = . + 4;  /* reserve space for CRC */
        _image_end = .;
    } > TEXT

А у меня в линкере этого нет LONG((_image_end - _image_start) / 4); Вы сами добавили?
Go to the top of the page
 
+Quote Post
AleksBak
сообщение Apr 28 2016, 17:30
Сообщение #6


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

Группа: Участник
Сообщений: 132
Регистрация: 6-02-16
Из: г. Баку
Пользователь №: 90 364



Цитата(Jenya7 @ Apr 28 2016, 19:50) *
А у меня в линкере этого нет LONG((_image_end - _image_start) / 4); Вы сами добавили?

Пример просто он привел. С новой директивой линкера. Интересной. А Вы под Ac6 проект используете? Или под gcc.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 28 2016, 17:51
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Jenya7 @ Apr 28 2016, 18:50) *
А у меня в линкере этого нет LONG((_image_end - _image_start) / 4); Вы сами добавили?
У вас там и резервирования места под CRC нет. Да, сам добавил. Скрипт линкера - не какая-нибудь священная корова, а такая же часть проекта, как и все остальные файлы исходников.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Apr 29 2016, 09:42
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(AleksBak @ Apr 28 2016, 23:30) *
Пример просто он привел. С новой директивой линкера. Интересной. А Вы под Ac6 проект используете? Или под gcc.

У меня Atollic TrueStudio. там GCC.

Цитата(Сергей Борщ @ Apr 28 2016, 23:51) *
У вас там и резервирования места под CRC нет. Да, сам добавил. Скрипт линкера - не какая-нибудь священная корова, а такая же часть проекта, как и все остальные файлы исходников.

а как вы тогда определяете _image_end и _image_start? я не понимаю кто придумал такой ужасный смнтаксис в линкере. похоже на шпионскую шифровку. есть столько красивых скриптовых языков.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 29 2016, 10:04
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Jenya7 @ Apr 29 2016, 12:42) *
а как вы тогда определяете _image_end и _image_start?
Там все показано:
CODE
     _image_start = .;
.....
     _image_end = .;
Документацию на линкер пересказывать не буду, извините. "Чтение информации из интернета вслух - 100 евро в час".

QUOTE (Jenya7 @ Apr 29 2016, 12:42) *
я не понимаю кто придумал такой ужасный смнтаксис в линкере. похоже на шпионскую шифровку. есть столько красивых скриптовых языков.
"Жалуйтесь в лигу сексуальных реформ" wink.gif или напишите свой линкер с красивым скриптовым языком.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Apr 29 2016, 10:33
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Сергей Борщ @ Apr 29 2016, 15:04) *
Там все показано:
Код
     _image_start = .;
.....
     _image_end = .;
Документацию на линкер пересказывать не буду, извините. "Чтение информации из интернета вслух - 100 евро в час".

"Жалуйтесь в лигу сексуальных реформ" wink.gif или напишите свой линкер с красивым скриптовым языком.

спасибо. почитал по ссылке. довольно доходчивое объяснение.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение May 2 2016, 06:48
Сообщение #11


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



еще такой вопрос хотел задать.
мне надо принять по CAN прошивку и положить во флеш. может есть пример как это делается?
разбить hex файл на строки и посылать построчно? а как по CAN принимать? насколько я понимаю приемный FIFO содержит 8 байт. прошивать по 8 байт или накапливать пакет,скажем размером в страницу и затем прошивать?
Go to the top of the page
 
+Quote Post
AleksBak
сообщение May 2 2016, 07:15
Сообщение #12


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

Группа: Участник
Сообщений: 132
Регистрация: 6-02-16
Из: г. Баку
Пользователь №: 90 364



Цитата(Jenya7 @ May 2 2016, 10:48) *
еще такой вопрос хотел задать.
мне надо принять по CAN прошивку и положить во флеш. может есть пример как это делается?
разбить hex файл на строки и посылать построчно? а как по CAN принимать? насколько я понимаю приемный FIFO содержит 8 байт. прошивать по 8 байт или накапливать пакет,скажем размером в страницу и затем прошивать?

А зачем hex файл посылать? Он же текстовый. Сразу в бинарном виде же лучше - тем более тут CAN. И контрольную сумму не забыть потом. У Вас по CAN какой-то хост имеется что ли?
Go to the top of the page
 
+Quote Post
Jenya7
сообщение May 2 2016, 08:08
Сообщение #13


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(AleksBak @ May 2 2016, 13:15) *
А зачем hex файл посылать? Он же текстовый. Сразу в бинарном виде же лучше - тем более тут CAN. И контрольную сумму не забыть потом. У Вас по CAN какой-то хост имеется что ли?

нет. обычный CAN. принимаю данные по прерыванию.
Код
void USB_LP_CAN1_RX0_IRQHandler(void)
{
    if((CAN1->RF0R & CAN_RF0R_FMP0)!=0) /* check if a message is filtered and received by FIFO 0 */
    {
        CAN_ReceiveData = CAN1->sFIFOMailBox[0].RDLR;   /* read data */
        CAN_CmdType = CAN1->sFIFOMailBox[0].RDHR;
        CAN_Identifier = CAN1->sFIFOMailBox[0].RIR;
        CAN1->RF0R |= CAN_RF0R_RFOM0;                  /* release FIFO */
        data_ready = 1;
    }
    else {
          //error_flag |= CAN_ERR;
          CAN1->TSR |= CAN_TSR_ABRQ0;
          CAN1->IER &= ~CAN_IER_ERRIE;
    }
}

непонятно как организовать протокол приема бин файла.

сам бут выглядит пока так
Код
int boot_main(void)
{

    __disable_irq();

    GPIO_Config();
    CAN_Config();
    Start_TIM2();

    __enable_irq();

    //load parameters from flash
    memcpy(&flashParams, (uint32_t*)FLASH_PAGE127, sizeof(flashParams));
    
    // notify other party that we are alive
    CAN_Send(UNIT_ID , READY, 0);
  
  /* Infinite loop */
  while (1)
  {
      //get data from CAN
      if (data_ready)
      {
          data_ready = 0;
          WriteAppToFlash();
      }

      //timeout to exit to main application
      if (sec_count > TIMEOUT)
      {
          sec_count = 0;
          if (flashParams.state == LAST_BOOT_OK)
          {
              JumpToApp();
          }
          else  //try to program flash from the buffer
          {
                   
          }      
      }

  }
}


WriteAppToFlash() в сыром виде выглядит так
Код
void WriteAppToFlash(void)
{
    /* Porgram APP to FLASH -------------------------------------------------------------*/

    // Unlock the Flash
    FLASH_Unlock();

    /* Clear All pending flags */
    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR | FLASH_FLAG_BSY);

    uint32_t done = 0;
    uint32_t page;
    uint32_t page_addr;
    uint32_t page_addr_end;

    /* Erase the FLASH pages */
    for(page = 0; page < 20; page++)  //main program takes 20 pages
    {
        page_addr = (page * FLASH_PAGE_SIZE) + APPLICATION_ADDRESS;
        FLASHStatus = FLASH_ErasePage(page_addr);
        if (FLASHStatus != FLASH_COMPLETE)
            break;
    }

    /* Program Flash */
    page = 0;
    while (page < 20 || !done)
    {
        Address = (page * FLASH_PAGE_SIZE) + APPLICATION_ADDRESS;
        page_addr_end = Address + FLASH_PAGE_SIZE;
        while((Address < page_addr_end))
        {
            // Get packet from CAN
            //?????????

            //Program packet to flash
            FLASHStatus = FLASH_ProgramWord(Address, Data);
            Address = Address + 4;
            addr_data = addr_data +4;
            if (FLASHStatus != FLASH_COMPLETE)
            {
                //done = 1;
                break;
            }
        }
        page++;
    }

    FLASH_Lock();

    /* Jump to User define Application Address */
    JumpToApp();
}



Сообщение отредактировал Jenya7 - May 2 2016, 07:24
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 01:43
Рейтинг@Mail.ru


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