Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32 flash
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
dimka76
В документации написано что шина данных FLASH памяти у STM32 128-ми битная.
Но при этом в коде startup, где идет инициализация переменных в ОЗУ, копирование идет по 4 байта (32 бита) инструкции
Код
       ...
   ldr  r3, [r3, r1]
   str  r3, [r0, r1]
   adds  r1, r1, #4
       ...


У ST есть AppNote EEPROM emulation in STM32F10x microcontrollers, где при чтении из FLASH (виртуальной EEPROM) копируются 16-ти битные данные
Код
/**
  * @brief  Returns the last stored variable data, if found, which correspond to
  *   the passed virtual address
  * @param  VirtAddress: Variable virtual address
  * @param  Data: Global variable contains the read variable value
  * @retval Success or error status:
  *           - 0: if variable was found
  *           - 1: if the variable was not found
  *           - NO_VALID_PAGE: if no valid page was found.
  */
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)


Как же все-таки читается FLASH?
А если мне надо только один байт прочитать из FLASH ?
aaarrr
Цитата(dimka76 @ May 30 2014, 15:44) *
Как же все-таки читается FLASH?

Как угодно: разрядность шины flash для ядра прозрачна.
scifi
Цитата(dimka76 @ May 30 2014, 15:44) *
В документации написано что шина данных FLASH памяти у STM32 128-ми битная.
...
Как же все-таки читается FLASH?
А если мне надо только один байт прочитать из FLASH ?

Процессор может свободно читать и один байт, и 32-разрядное слово. Грубо говоря, контроллер флэш подсовывает процессору из этих 128 бит только те, которые ему нужны. Всё это волшебство происходит автоматически и незаметно.

Цитата(dimka76 @ May 30 2014, 15:44) *
У ST есть AppNote EEPROM emulation in STM32F10x microcontrollers, где при чтении из FLASH (виртуальной EEPROM) копируются 16-ти битные данные

Запись - это совсем другая история. Обычно у флэш есть минимальная ячейка памяти, меньше которой записать нельзя. Для STM32F1 это 16 бит. Кстати, в семействах STM32F2 и STM32F4 флэш устроена иначе, и записывать можно даже 1 байт за раз, что открывает новые возможности для эмуляции EEPROM.
dimka76
Спасибо всем ответившим.

Цитата(scifi @ May 30 2014, 17:47) *
Запись - это совсем другая история. Обычно у флэш есть минимальная ячейка памяти, меньше которой записать нельзя. Для STM32F1 это 16 бит. Кстати, в семействах STM32F2 и STM32F4 флэш устроена иначе, и записывать можно даже 1 байт за раз, что открывает новые возможности для эмуляции EEPROM.


Про запись я не спрашивал ;-)
А по поводу флэш в STM32F2xx очень полезное замечание, т.к. с ним и работаю. А указанный выше AppNote просто первым подвернулось, и я думал, что у всех STM32F память устроена одинакого.

Еще один вопрос.
Скомпилировал для STM32F2xx следующую строчку, где raw_data константы во флэш. Компилятор GCC.
Код
uint8_t    raw_data[118660] __attribute__ ((section (".ordata")));
uint8_t    appdata[10000];
for(i=0; i<10000UL; ++i) appdata[i] = raw_data[i];


И вот, что наблюдаю в листинге

Код
8001a6e:    f242 7410     movw    r4, #10000    
8001a72:    5cb8          ldrb    r0, [r7, r2]
8001a74:    6819          ldr    r1, [r3, #0]
8001a76:    f8df a20c     ldr.w    sl, [pc, #524]
8001a7a:    5488          strb    r0, [r1, r2]
8001a7c:    3201          adds    r2, #1
8001a7e:    42a2          cmp    r2, r4
8001a80:    d1f7          bne.n    8001a72


Мне непонятна строчка
Код
ldr.w    sl, [pc, #524]

Что она делает ? Ведь в цикле регистр sl вообще не используется, зачем в него что-то загружается ? И при чем всегда одно и тоже.
Golikov A.
регистр SL - это стэк лимит, а вот зачем в него что-то в цикле пихать постоянно... хрен знает...

может тут SL просто 10 регистр и все? как временный используется...
kan35
Между памятью и ядром есть прослойка в виде например ART акселератора. Если память работает на частоте 32МГц, то как инструкции могут поступать с частотой 180МГц?.. - вот потому и за 1 обращение вычитывается от 4 до 8 инструкций.
AHTOXA
Цитата(dimka76 @ May 31 2014, 00:33) *
Код
8001a6e:    f242 7410     movw    r4, #10000    
8001a72:    5cb8          ldrb    r0, [r7, r2]
8001a74:    6819          ldr    r1, [r3, #0]
8001a76:    f8df a20c     ldr.w    sl, [pc, #524]
8001a7a:    5488          strb    r0, [r1, r2]
8001a7c:    3201          adds    r2, #1
8001a7e:    42a2          cmp    r2, r4
8001a80:    d1f7          bne.n    8001a72

Строчка
Код
    ldr.w    sl, [pc, #524]

явно лишняя, как и строчка
Код
          ldr    r1, [r3, #0]

в цикле. У вас указатель appdata не volatile случайно?

dimka76
Цитата(AHTOXA @ May 31 2014, 09:17) *
У вас указатель appdata не volatile случайно?


Нет, не волатиле.
Haamu
Чтобы не плодить новых тем, продолжу эту.
Во flash-памяти контроллера STM32F407 есть такая область под названием "OTP (one-time programmable) area", состоящая из 15 блоков по 32 байта памяти и 16 байт блока защиты. У кого есть опыт работы с этой областью памяти, подскажите пожалуйста, в какой последовательности действовать, чтобы записать туда что-либо?
Сергей Борщ
Цитата(Haamu @ Jun 20 2014, 08:45) *
подскажите пожалуйста, в какой последовательности действовать, чтобы записать туда что-либо?
www.st.com->Products->Microcontrollers->STM32 ARM Cortex MCU->STM32F4 series->Programming manuals->PM0081 STM32F40xxx and STM32F41xxx Flash programming manual->1.7 One-time programmable bytes
Haamu
Читал. Правда не в Programming manual, а в Reference manual, одно и то же слово в слово. Все-равно не работает.
Написано "Each OTP data block can be programmed until the value 0x00 is programmed in the corresponding OTP lock byte."
Так и делаю, пишу один байт (либо слово (32 бит), либо 4 слова сразу) нулей по адресу 0x1FFF7A00. После чего пробую записать 32-байтное слово по адресу 0x1FFF7820. Смотрю состояние памяти - остается без изменений (все единицы). Что я делаю не так? Может перед этим еще где-то надо какую-то блокировку снять?
Вот кусок кода:
Код
uint32_t* pLockBlock = (uint8_t)0x1FFF7A00;
*pLockBlock = 0;
uint32_t* pData = (uint32_t)0x1FFF7800;
*pData = 0xAA55AA55;

Может я с указателями что-то напутал?
_Артём_
Цитата(Haamu @ Jun 20 2014, 15:17) *
Так и делаю, пишу один байт (либо слово (32 бит), либо 4 слова сразу) нулей по адресу 0x1FFF7A00.

Код
uint32_t* pLockBlock = (uint8_t)0x1FFF7A00;
*pLockBlock = 0;

Что-то странно вы пишите - запись 0 по адресу 0.
Может так:
Код
uint32_t* pLockBlock = (uint32_t *)0x1FFF7A00;
*pLockBlock = 0;


Цитата(Haamu @ Jun 20 2014, 15:17) *
После чего пробую записать 32-байтное слово по адресу 0x1FFF7820. Смотрю состояние памяти - остается без изменений (все единицы).

Код
uint32_t* pData = (uint32_t)0x1FFF7800;
*pData = 0xAA55AA55;

Код
uint32_t* pData = (uint32_t *)0x1FFF7800;
*pData = 0xAA55AA55;
Сергей Борщ
Цитата(Haamu @ Jun 20 2014, 14:17) *
пишу один байт (либо слово (32 бит), либо 4 слова сразу) нулей по адресу 0x1FFF7A00. После чего пробую записать 32-байтное слово по адресу 0x1FFF7820.
То есть делаете с точность до наоборот от того, что написано в документации. Там написано: после того, как записали 0 в 0x1FFF7A00 - сушите весла, больше ничего программироваться не будет.
Цитата
Each OTP data block can be programmed until the value 0x00 is programmed in the corresponding OTP lock byte.


Ну и с учетом этого - даже хорошо, что вы писали неправильно (см. сообщение Артема). Это раз. И второе - я так понял, что писать эти байты надо так же, как и остальную флеш, то есть через регистры FLASH_KEY, FLASH_CR, FLASH_SR.
ViKo
Цитата(scifi @ May 30 2014, 12:37) *
Кстати, в семействах STM32F2 и STM32F4 флэш устроена иначе, и записывать можно даже 1 байт за раз, что открывает новые возможности для эмуляции EEPROM.

Вот задумался сделать обновление программы по-простому. Приму по USART во внешнюю RAM весь file.bin, а потом попробую записать. Смогу ли? Если можно записывать (и стирать, значит?) по байтам? Когда подберется к месту, где находится сама запись во флэш, команды-то в буфере будут.
scifi
Цитата(ViKo @ Jul 1 2014, 14:00) *
Если можно записывать (и стирать, значит?) по байтам?

Нет, конечно. Стирается целый сектор. Иначе это была бы не флеш, а EEPROM.
Там и другая проблема: если прервать прошивку, то устройство превращается в кирпич. Поэтому нужен загрузчик.
ViKo
Как бы тогда перекинуть функцию записи в ОЗУ, и выполнить?
scifi
Цитата(ViKo @ Jul 1 2014, 14:18) *
Как бы тогда перекинуть функцию записи в ОЗУ, и выполнить?

Вот так, к примеру:
Код
static const uint16_t jump2fw[] =
{
        0xF850, 0xDB04, /* LDR.W SP, [R0], #4   */
        0x6800,         /* LDR.W R0, [R0]       */
        0x4700,         /* BX R0                */
};
...
((void (*)(int*))(1 + (int)jump2fw))(&fw_start);

Самый переносимый способ. Функцию можно сделать очень компактной, так что особого напряга быть не должно.
A. Fig Lee
Цитата(ViKo @ Jul 1 2014, 06:18) *
Как бы тогда перекинуть функцию записи в ОЗУ, и выполнить?

Или пользоватся встроенным бутлоадером, или сделать свой.
Основную программу разместить по другому аддрессу.
Тогда и внешняя РАМ не надо
Сергей Борщ
Цитата(scifi @ Jul 1 2014, 13:22) *
Самый переносимый способ. Функцию можно сделать очень компактной, так что особого напряга быть не должно.

Но не самый "прямой".
Код
__attribute__(("section"(".ramfunc")))
void somefunc()
{
     ......

}

*.ld:
......
    .data :
    {
        . = ALIGN(4);
        _sdata = .;                /* start of .data label */
        *(.ramfunc)
        *(.ramfunc.*)
        *(.data)
        *(.data.*)
        . = ALIGN(4);
        _edata = .;                /* end of .data label */
    } > RAM AT > TEXT
    _sidata = LOADADDR(.data);    /* start of initialized data label */

И все. Тело функции будет скопировано перед запуском main() заодно с инициализированными данными (как и ваше, кстати), но обращаться к ней можно напрямую - линкер при обращении к этой функции будет подставлять правильный адрес в ОЗУ, и не нужно писать эту функцию в машинных кодах. Для других компиляторов можно сделать аналогично.
Но сколько работаю с разными Cortex, пока что ни разу функция в ОЗУ не потребовалась.
ViKo
Да, можно разместить "прошивальщик" в конце flash, например. И не трогать этот сектор никогда.
A. Fig Lee
Цитата(ViKo @ Jul 1 2014, 07:13) *
Да, можно разместить "прошивальщик" в конце flash, например. И не трогать этот сектор никогда.

Нет, прошивальщик должен всегда стартовать по нулевому аддрессу, с рестарта. Иначе смысл теряется.
А вот программа может быть где угодно
ViKo
Цитата(A. Fig Lee @ Jul 1 2014, 14:15) *
Нет, прошивальщик должен всегда стартовать по нулевому аддрессу, с рестарта. Иначе смысл теряется.
А вот программа может быть где угодно

Так стартовать можно, куда задашь. По нулевому адресу расположена таблица startup.
Хорошо, стартанул я в загрузчик. Настроил все нужные режимы, чтобы принять новую прошивку. Жду... а ее нет. Подождал, свалил в основную программу. Так?
Сергей Борщ
Цитата(ViKo @ Jul 1 2014, 14:18) *
По нулевому адресу расположена таблица startup.
Таблица векторов прошивальщика. Приложение со своей собственной таблицей может располагаться где угодно. При старте запускается прошивальщик, он проверяет целостность приложения, переключает VTOR на вектора приложения (для Cortex-M0 копирует вектора приложения в ОЗУ и делает ремап), грузит указатель стека из векторов приложения и передает управление на вектор Reset приложения. Приложение может отсутствовать вообще (или быть испорченным, недозаписанным), в этом случае прошивальщик весело мигая светодиодом ожидает новую прошивку для приложения, записывает ее и делает рестарт. После рестарта прошивальщик проверяет целостность... (далее читать с начала).
ViKo
Цитата(Сергей Борщ @ Jul 1 2014, 14:25) *
При старте запускается прошивальщик, он проверяет целостность приложения, переключает VTOR на вектора приложения (для Cortex-M0 копирует вектора приложения в ОЗУ и делает ремап), грузит указатель стека из векторов приложения и передает управление на вектор Reset приложения.

А если приложение целое, но хочу зашить новую прошивку? Чем подтолкнуть?
А целостность как определить - CRC посчитать? А размеры кода откуда узнать, хранить во flash, рядом с CRC?

В конце flash сектора большие, по 128 KB (речь идет про STM32F20x). Значит, загрузчик надо расположить в начальных секторах, или в OTP (страшно!).
Сергей Борщ
Цитата(ViKo @ Jul 1 2014, 14:34) *
А если приложение целое, но хочу зашить новую прошивку? Чем подтолкнуть?
Я делаю программный сброс из приложения. А загрузчик после обновления делает сброс по собаке. При старте загрузчика проверяю источник сброса и если он программный - ухожу на обновление, если нет - проверяю целостность и запускаю приложение.
Цитата(ViKo @ Jul 1 2014, 14:34) *
А целостность как определить - CRC посчитать?
Да, тем более что у STM32 есть и аппаратный расчет CRC и DMA.
Цитата(ViKo @ Jul 1 2014, 14:34) *
А размеры кода откуда узнать, хранить во flash, рядом с CRC?
Я размер храню сразу после области векторов приложения. У меня его туда линкет прописывает:
Код
    .text :
    {
        _image_start = .;
        KEEP(*(.isr_vector))

        LONG((_image_end - _image_start) / 4);    /* application size, in 4-byte words */
      
    ....................
    } > TEXT

    .data :
    {
        . = ALIGN(4);
        _sdata = .;                /* start of .data label */
        *(.ramfunc)
        *(.ramfunc.*)
        *(.data)
        *(.data.*)
        . = ALIGN(4);
        _edata = .;                /* end of .data label */
    } > RAM AT > TEXT
    _sidata = LOADADDR(.data);    /* start of initialized data label */

    .crc :
    {
        . = . + 4;        /* reserve space for CRC */
        _image_end = .;
    } > TEXT



Цитата(ViKo @ Jul 1 2014, 14:34) *
Значит, загрузчик надо расположить в начальных секторах, или в OTP (страшно!).
Разумеется в начальных секторах. Чтобы всегда, после заливки чего угодно он всегда стартовал первым и имел возможность залить другое приложения. Я предусматриваю одну из свободных ног для принудительного запуска загрузчика - если залито приложение, которое хотя и целое, но тем не менее нерабочее, то сняв питание, закоротив эту ногу и подав питание снова, я из кирпича получаю готовое к обновлению устройство.
ViKo
В секторе 0 расположить загрузчик, основную программу начать с сектора 1.
А таблицей векторов нельзя ли одной обойтись? Запретить все прерывания при загрузке, и шабаш?
Сергей Борщ
Цитата(ViKo @ Jul 1 2014, 15:15) *
В секторе 0 расположить загрузчик, основную программу начать с сектора 1.
Именно.
Цитата(ViKo @ Jul 1 2014, 15:15) *
А таблицей векторов нельзя ли одной обойтись? Запретить все прерывания при загрузке, и шабаш?
Не вижу смысла. Вектора приложения все равно каким-то образом должны попасть на свое место - или через VTOR или через ремап. При этом содержимое векторов загрузчика никакой роли уже не имеет. Никаких плюсов от неиспользования прерываний в загрузчике нет.
doom13
Цитата(Сергей Борщ @ Jul 1 2014, 14:48) *
Я предусматриваю одну из свободных ног для принудительного запуска загрузчика - если залито приложение, которое хотя и целое, но тем не менее нерабочее, то сняв питание, закоротив эту ногу и подав питание снова, я из кирпича получаю готовое к обновлению устройство.

И вчём смысл такого решения, если всё равно необходимо будет разобрать всё устройство (что порой бывает не просто), чтобы добраться до платы с процессором. Там уже что ножку коротить, что программатор подключить, особой разницы нету.
demiurg_spb
Цитата(doom13 @ Jul 1 2014, 17:16) *
И вчём смысл такого решения, если всё равно необходимо будет разобрать всё устройство (что порой бывает не просто), чтобы добраться до платы с процессором. Там уже что ножку коротить, что программатор подключить, особой разницы нету.
Это нормальное решение. Сам так всегда делаю.
Часто у устройств есть клавиатура или кнопочки, поэтому и без разбора прибора всё прекрасно получается.
doom13
Цитата(demiurg_spb @ Jul 1 2014, 16:32) *
Это нормальное решение. Сам так всегда делаю.
Часто у устройств есть клавиатура или кнопочки, поэтому и без разбора прибора всё прекрасно получается.

Т.е. данная кнопка выносится на корпус и доступна любому пользователю? На мой взгляд, не есть хорошее решение. Если бы какой-то Master мог сделать это по внешней технологической команде, тогда ещё приемлемо.
ViKo
Я последовательно соединял две независимых кнопки (у каждой две группы контактов). В обычном режиме каждая работает сама по себе, а когда нажимаю обе - особый случай.
Теперь аналогичное делаю программным способом, с некоторыми дополнительными условиями.
scifi
Цитата(doom13 @ Jul 1 2014, 17:41) *
Т.е. данная кнопка выносится на корпус и доступна любому пользователю? На мой взгляд, не есть хорошее решение. Если бы какой-то Master мог сделать это по внешней технологической команде, тогда ещё приемлемо.

У меня обычно есть несколько кнопок, и я делаю вход в загрузчик, если при включении питания нажата определённая комбинация. Обычный обыватель не догадается, и в случае неисправности комбинацию можно сообщить пользователю. Опять же залить что попало он туда не сможет, потому что есть проверка целостности прошивки.
Golikov A.
А у меня есть видеорегистратор, который виснет если при включении держать кнопку, и только ресетом через дырочку отвисает. Подозреваю как раз в загрузчик переходит. А вот что выйти кнопкой включения нельзя - руки бы поломал бы.... Да еще кнопки так стоят, что включая легко задеть ту самую заветную%)...

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

Но аварийная кнопка нужна. Если случайно зальют левак какой-то с верным ЦРЦ и верным кодом безопасности или в котором команда перехода в бутлоадер сломана или езернет отвалится, или случайно у битого кода совпадет ЦРЦ, мало ли что.....

Так же надо не забывать что иногда ваши устройства собирают партнеры которые могут и обновлять прошивки во время сборки, что им ЖТАГ поставлять?
Сергей Борщ
Цитата(Golikov A. @ Jul 1 2014, 18:11) *
Но аварийная кнопка нужна. Если случайно зальют левак какой-то с верным ЦРЦ и верным кодом безопасности или в котором команда перехода в бутлоадер сломана или езернет отвалится, или случайно у битого кода совпадет ЦРЦ, мало ли что.....
Именно. Или какой-то непредусмотренной комбинацией штатных настроек устройство приводится в нерабочее состояние (ну бывает, любая программа содержит минимум одну ошибку), или клиенту случайно отправили промежуточную, совсем нерабочую версию - вот в таком крайнем случае можно попросить клиента вскрыть устройство, замкнуть заветную точку и залить исправление. Это быстрее и дешевле, чем пересылать устройство на ремонт через половину земного шарика. В штатном режиме устройство обновляется командой по интерфейсу без вмешательства человека.
demiurg_spb
Цитата(doom13 @ Jul 1 2014, 17:41) *
Т.е. данная кнопка выносится на корпус и доступна любому пользователю?
Она не выносится, она уже есть и является частью клавиатуры прибора. И используется обычно по своему назначению, а вызов загрузчика это её вторая скрытая функция, активируемая лишь в момент подачи питания на несколько миллисекунд.
Убеждать вас в её необходимости я не буду. Сами всё поймёте рано или поздно.
doom13
Цитата(demiurg_spb @ Jul 2 2014, 11:42) *
Она не выносится, она уже есть и является частью клавиатуры прибора. И используется обычно по своему назначению, а вызов загрузчика это её вторая скрытая функция, активируемая лишь в момент подачи питания на несколько миллисекунд.
Убеждать вас в её необходимости я не буду. Сами всё поймёте рано или поздно.

Может быть и так, но тогда есть вероятность получить такое:
Цитата(Golikov A. @ Jul 1 2014, 18:11) *
А у меня есть видеорегистратор, который виснет если при включении держать кнопку, и только ресетом через дырочку отвисает. Подозреваю как раз в загрузчик переходит. А вот что выйти кнопкой включения нельзя - руки бы поломал бы.... Да еще кнопки так стоят, что включая легко задеть ту самую заветную%)...

Ну и как же быть, если нет никаких кнопок. В нашей системе и без кнопок всё нормально работает, переход в загрузчик только по командам CAN, Ethernet. Не считаю наличие данной кнопки необходимостью любой системы и Вас также переубеждать не стану. Думаю, где-то может быть оправдано такое решение где-то нет.
ViKo
А вот можно ли зайти во встроенный загрузчик в STM32? Адрес известен, перенести таблицу векторов... Или там работает абсолютная адресация, и нужно отобразить System память на нулевые адреса (что делается ножками boot)?
Сергей Борщ
У ST есть несколько подробных аппнотов по загрузчику. Думаю, этот вопрос там освещен.
ViKo
Цитата(Сергей Борщ @ Jul 2 2014, 11:59) *
У ST есть несколько подробных аппнотов по загрузчику. Думаю, этот вопрос там освещен.

Листал. Там расписано, как работать со встроенным загрузчиком. Но чтобы из рабочей программы скакнуть, такого не помню. Впрочем, читал не внимательно.
demiurg_spb
Цитата(doom13 @ Jul 2 2014, 12:46) *
Может быть и так, но тогда есть вероятность получить такое:
Чтобы такого не было я использую таймаут и выхожу из загрузчика при его бездействии.
scifi
Цитата(ViKo @ Jul 2 2014, 13:05) *
Листал. Там расписано, как работать со встроенным загрузчиком. Но чтобы из рабочей программы скакнуть, такого не помню. Впрочем, читал не внимательно.

Эта фича не предусмотрена, насколько я понял. Но никто не мешает МК самому себе дёргать ногу BOOT0 и делать сброс (+конденсатор, чтобы нужный уровень на BOOT0 продержался до выхода из сброса).
DmitryM
Цитата(demiurg_spb @ Jul 2 2014, 11:42) *
И используется обычно по своему назначению, а вызов загрузчика это её вторая скрытая функция, активируемая лишь в момент подачи питания на несколько миллисекунд.

Правильно. Да, ограничения накладывает, но если продумать комбинацию (CTRL+ALT+DEL например :-)) В последних SAM3 именно так и сделана фунция ERASE. В момент подачи питания анализируется уровень PIO_ERASE, а потом программа в праве переключить на PIO или оставить как есть.
Сергей Борщ
Писал ответ в соседнюю тему и пришла в голову такая мысль: запустить загрузчик на Cortex-M3/M4 очень просто. Мы же знаем, где он находится. Значит знаем, где начинаются его вектора. Нам надо запретить прерывания, установить VTOR на вектора загрузчика, загрузить в MSP число из первого слова векторов, переключить стек на MSP и передать управление на адрес из второго слова векторов. То есть произвести те же действия, которые мы делаем при запуске приложения из самописного загрузчика.

P.S. Хм, ViKo как раз это и предлагал. Надо читать сообщения внимательнее.
A. Fig Lee
Цитата(Сергей Борщ @ Jul 4 2014, 13:37) *
Писал ответ в соседнюю тему и пришла в голову такая мысль: запустить загрузчик на Cortex-M3/M4 очень просто. Мы же знаем, где он находится. Значит знаем, где начинаются его вектора. Нам надо запретить прерывания, установить VTOR на вектора загрузчика, загрузить в MSP число из первого слова векторов, переключить стек на MSP и передать управление на адрес из второго слова векторов. То есть произвести те же действия, которые мы делаем при запуске приложения из самописного загрузчика.

P.S. Хм, ViKo как раз это и предлагал. Надо читать сообщения внимательнее.

А смысл? Входить в загрузчик без кнопки все равно не получится.
В смысле получится, пока прошивка нормальная, как только глюк - все.
Хотя если просто пользовать фирменный загрузчик в своем бутлоадере, то да.
Golikov A.
Чего то я не понял бизнеса...
Хотим загрузить загрузчик без ресета? Так столько копий сломано что это чревато. А если с ресетом, то вроде и так запуститься штатный загрузчик?

Чего я не понимаю? Или это способ ухода от вочдога? Так регистры то не сбросятся...
scifi
Цитата(Сергей Борщ @ Jul 4 2014, 21:37) *
Писал ответ в соседнюю тему и пришла в голову такая мысль: запустить загрузчик на Cortex-M3/M4 очень просто.

Я поспешил со своим ответом. У них так и написано:
Цитата
In addition to patterns described below, user can execute bootloader by performing a jump
to system memory from user code. Befor jumping to Bootloader user must :
• Disable all peripheral clocks
• Disable used PLL
• Disable interrupts
• Clear pending interrupts
System memory boot mode can be exited by getting out from bootloader activation
condition and generating hardware reset or using Go command to execute user code.
Сергей Борщ
Цитата(Golikov A. @ Jul 4 2014, 21:20) *
А если с ресетом, то вроде и так запустится штатный загрузчик?
Возможно хочется обновляться штатным, но по возможности не добираясь до ноги BOOT, по команде приложению?
A. Fig Lee
Цитата(Сергей Борщ @ Jul 4 2014, 14:42) *
Возможно хочется обновляться штатным, но по возможности не добираясь до ноги BOOT, по команде приложению?

Только не приложению, а бутлоадеру.
Приложение может работать, а может не работать.
А свой бутлоадер может запускатся не от кнопки, или от кнопки, но от другой.
Но пользовать стандартный механизм загрузки..
Golikov A.
Ну то есть у нас штатный запуск проца на прошивку пользователя. Которая в самом начале имеет ветвления
свой бут
стандартный бут
рабочая прошивка

и мы не трогая ножку бут имеем возможность обновить прошивку через UART?

Ну да, наверное это интересная мысль. Главное не затереть начальный разветвитель, а то придем к кирпичуsm.gif
ViKo
Так же можно потерять и самопальный загрузчик. Вероятность, конечно, меньше, чем основную программу (судя по размерам), но... терять, так терять. И тогда остается только встроенный системный загрузчик, или специально предназначенные для программирования средства.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.