jenya7 0 28 апреля, 2016 Опубликовано 28 апреля, 2016 · Жалоба Я написал отдельную программу - бутлоадер. Чтоб разместить ее во флеш нужно изменить стартап файл и линкер файл. и тут у меня трудности. может кто нибудь рассказать как это делать? под бутлоадер я хочу отвести первые две страницы. линкер и стартап в принципе изменять не надо. насчет главной программы. в линкере заменил 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 а что еще надо поменять? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 28 апреля, 2016 Опубликовано 28 апреля, 2016 · Жалоба FLASH (rx) : ORIGIN = 0x08001000, LENGTH = 1024K Вы уехали за границу доступной памяти. Осетра-то урежте ;) , в смысле LENGTH укоротите на размер загрузчика. И в загрузчике аналогично, чтобы получить ошибку если он вдруг налезет на приложение. а что еще надо поменять?Зависит от того, что и как вы наворотили в загрузчике. У меня линкер сразу после векторов добавляет размер прошивки в словах (чтобы загрузчик знал, до куда считать CRC), а также резервируется место под CRC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 апреля, 2016 Опубликовано 28 апреля, 2016 (изменено) · Жалоба Вы уехали за границу доступной памяти. Осетра-то урежте ;) , в смысле 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 Изменено 28 апреля, 2016 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 28 апреля, 2016 Опубликовано 28 апреля, 2016 · Жалоба кстати а как линкер знает размер прошивки?Он же сам ее собрал, кто же лучше него может знать? .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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 28 апреля, 2016 Опубликовано 28 апреля, 2016 · Жалоба Он же сам ее собрал, кто же лучше него может знать? .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); Вы сами добавили? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 28 апреля, 2016 Опубликовано 28 апреля, 2016 · Жалоба А у меня в линкере этого нет LONG((_image_end - _image_start) / 4); Вы сами добавили? Пример просто он привел. С новой директивой линкера. Интересной. А Вы под Ac6 проект используете? Или под gcc. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 28 апреля, 2016 Опубликовано 28 апреля, 2016 · Жалоба А у меня в линкере этого нет LONG((_image_end - _image_start) / 4); Вы сами добавили?У вас там и резервирования места под CRC нет. Да, сам добавил. Скрипт линкера - не какая-нибудь священная корова, а такая же часть проекта, как и все остальные файлы исходников. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 29 апреля, 2016 Опубликовано 29 апреля, 2016 · Жалоба Пример просто он привел. С новой директивой линкера. Интересной. А Вы под Ac6 проект используете? Или под gcc. У меня Atollic TrueStudio. там GCC. У вас там и резервирования места под CRC нет. Да, сам добавил. Скрипт линкера - не какая-нибудь священная корова, а такая же часть проекта, как и все остальные файлы исходников. а как вы тогда определяете _image_end и _image_start? я не понимаю кто придумал такой ужасный смнтаксис в линкере. похоже на шпионскую шифровку. есть столько красивых скриптовых языков. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 29 апреля, 2016 Опубликовано 29 апреля, 2016 · Жалоба а как вы тогда определяете _image_end и _image_start?Там все показано: _image_start = .; ..... _image_end = .; Документацию на линкер пересказывать не буду, извините. "Чтение информации из интернета вслух - 100 евро в час". я не понимаю кто придумал такой ужасный смнтаксис в линкере. похоже на шпионскую шифровку. есть столько красивых скриптовых языков."Жалуйтесь в лигу сексуальных реформ" ;) или напишите свой линкер с красивым скриптовым языком. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 29 апреля, 2016 Опубликовано 29 апреля, 2016 · Жалоба Там все показано: _image_start = .; ..... _image_end = .; Документацию на линкер пересказывать не буду, извините. "Чтение информации из интернета вслух - 100 евро в час". "Жалуйтесь в лигу сексуальных реформ" ;) или напишите свой линкер с красивым скриптовым языком. спасибо. почитал по ссылке. довольно доходчивое объяснение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 2 мая, 2016 Опубликовано 2 мая, 2016 · Жалоба еще такой вопрос хотел задать. мне надо принять по CAN прошивку и положить во флеш. может есть пример как это делается? разбить hex файл на строки и посылать построчно? а как по CAN принимать? насколько я понимаю приемный FIFO содержит 8 байт. прошивать по 8 байт или накапливать пакет,скажем размером в страницу и затем прошивать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 2 мая, 2016 Опубликовано 2 мая, 2016 · Жалоба еще такой вопрос хотел задать. мне надо принять по CAN прошивку и положить во флеш. может есть пример как это делается? разбить hex файл на строки и посылать построчно? а как по CAN принимать? насколько я понимаю приемный FIFO содержит 8 байт. прошивать по 8 байт или накапливать пакет,скажем размером в страницу и затем прошивать? А зачем hex файл посылать? Он же текстовый. Сразу в бинарном виде же лучше - тем более тут CAN. И контрольную сумму не забыть потом. У Вас по CAN какой-то хост имеется что ли? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 2 мая, 2016 Опубликовано 2 мая, 2016 (изменено) · Жалоба А зачем 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(); } Изменено 2 мая, 2016 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться