Миландр

Ключевым подразделением нашей компании
является Центр Проектирования интегральных микросхем
Текущее время: 2020-май-25 05:07

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 12 сообщений ] 
Автор Сообщение
 Заголовок сообщения: Сделать "бутлоудер"
СообщениеДобавлено: 2016-апр-18 17:59 
Не в сети

Зарегистрирован: 2016-янв-29 17:53
Сообщения: 55
Организация: частное лицо
Надо принять прошивку через CAN, записать во флеш и запустить прошивку которую приняли. Как сделать?
Моя программа примерно выглядит так:
Открыть Программа
#define USE_MDR1986VE9x
#define USE_JTAG_A
#include "MDR32F9Qx_config.h"           // Keil::Device:Startup_MDR1986BE9x
#include "MDR32Fx.h"                    // Device header
#include "MDR32F9Qx_can.h"              // Keil::Drivers:CAN
#include "MDR32F9Qx_eeprom.h"           // Keil::Drivers:EEMPROM
#include "MDR32F9Qx_rst_clk.h"          // Keil::Drivers:RST_CLK
#include "MDR32F9Qx_port.h"             // Keil::Drivers:PORT
#define USE_MDR1986VE9x
#define USE_JTAG_A
////// Рабочая программа для записи во флеш

#define RX_BUF 0
#define TX_BUF 1
#define ADDRESS_APPS		(uint32_t) 0x8001000

__RAMFUNC void jumpToApplication(void){		// прыгает на программу)))
	typedef  void (*pFunction)(void);
	pFunction Jump_To_Application;
	uint32_t JumpAddress;

	if( (*(__IO uint32_t*)ADDRESS_APPS) != 0xffffffff){ 
//		deInitPeriph();
		SCB->VTOR = (uint32_t)(ADDRESS_APPS);
		JumpAddress = *(__IO uint32_t*) (ADDRESS_APPS+4);	
		Jump_To_Application = (pFunction) (JumpAddress);  
		__set_MSP(*(__IO uint32_t*) ADDRESS_APPS);  			
		Jump_To_Application();                            
	}
}
 __RAMFUNC void EEPROM_Reload()		// прошивка через CAN1	// my
 {
	uint32_t i;		// для считывание флеш памяти!
	
 	CAN_RxMsgTypeDef RxMsg;
 	uint16_t RxMsgID;
 	uint32_t AdressSdvig = 0;	//костыль! должно быть 0
 		// for tests******
 	CAN_TxMsgTypeDef TxMsg;
 	TxMsg.IDE     = CAN_ID_STD;
 	TxMsg.DLC     = 8;
 	TxMsg.PRIOR_0 = DISABLE;

 	//	EEPROM_EraseAllPages(EEPROM_All_Banks_Select);

	
 	while(1)
 	{
 		if((CAN_GetStatus(MDR_CAN1) & CAN_STATUS_RX_READY) == 1)
 		{
 			CAN_GetRawReceivedData(MDR_CAN1, RX_BUF, &RxMsg);
 			CAN_ITClearRxTxPendingBit(MDR_CAN1, RX_BUF, CAN_STATUS_RX_READY);
 			RxMsgID =  CAN_EXTID_TO_STDID(RxMsg.Rx_Header.ID);		// получение ID

 			if(RxMsgID == 2)		// получение BIN-file
 			{
 				EEPROM_ProgramWord((ADDRESS_APPS+4*AdressSdvig),EEPROM_All_Banks_Select,RxMsg.Data[1]);
 				AdressSdvig++;
 				EEPROM_ProgramWord((ADDRESS_APPS+4*AdressSdvig),EEPROM_All_Banks_Select,RxMsg.Data[0]);
 				AdressSdvig++;
 			}
 			if(RxMsgID == 3)		// конец передачи
 			{				
				jumpToApplication();
 			}
			TxMsg.Data[0] = RxMsg.Data[0];
			TxMsg.Data[1] = RxMsg.Data[1];
			CAN_Transmit(MDR_CAN1, TX_BUF, &TxMsg);
 		}
 	}
 }

void AllConfig(void);
/*
ID map
01 - начать передавать BIN-file
02 - передача BIN-file
03 - конец передачи
*/
int main(void)
{
	//	// for tests******
	CAN_TxMsgTypeDef TxMsg;
	TxMsg.IDE     = CAN_ID_STD;
	TxMsg.DLC     = 8;
	TxMsg.PRIOR_0 = DISABLE;
	
	CAN_RxMsgTypeDef RxMsg;
	volatile uint16_t RxMsgID;
	AllConfig();
	while(1)
	{
		if((CAN_GetStatus(MDR_CAN1) & CAN_STATUS_RX_READY) == 1)
		{
			CAN_GetRawReceivedData(MDR_CAN1, RX_BUF, &RxMsg);
			CAN_ITClearRxTxPendingBit(MDR_CAN1, RX_BUF, CAN_STATUS_RX_READY);
			RxMsgID =  CAN_EXTID_TO_STDID(RxMsg.Rx_Header.ID);		// получение ID
			TxMsg.Data[0] = RxMsg.Data[0];
			TxMsg.Data[1] = RxMsg.Data[1];
			CAN_Transmit(MDR_CAN1, TX_BUF, &TxMsg);
			if(RxMsgID == 1)
			{
				EEPROM_Reload();	// получение новой прошивки!
			}
		}
	}
}
void AllConfig()		// все настройки
{
	// настройки HSE & ConfigClock
	RST_CLK_DeInit();
	RST_CLK_HSEconfig(RST_CLK_HSE_ON);
	while (RST_CLK_HSEstatus() != SUCCESS);
	RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSEdiv1,RST_CLK_CPU_PLLmul1);//CPU_C1_SEL[1:0] and PLL multiplication factor
	RST_CLK_CPU_PLLcmd(DISABLE);
	RST_CLK_CPUclkPrescaler(RST_CLK_CPUclkDIV1);			//CPU_C3_SEL[3:0]
	RST_CLK_CPU_PLLuse(DISABLE);											//CPU_C2_SEL[1:0]??
	RST_CLK_CPUclkSelection(RST_CLK_CPUclkCPU_C3);		//Final MUX for CLK
	
	// Clock
	RST_CLK_PCLKcmd(RST_CLK_PCLK_RST_CLK, ENABLE);	// RST_CLK
	RST_CLK_PCLKcmd(RST_CLK_PCLK_CAN1, ENABLE);			// CAN1
	RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTA, ENABLE);		// PORTA
	RST_CLK_PCLKcmd(RST_CLK_PCLK_EEPROM, ENABLE);		// EEPROM 
	
	// PORTA pin6, pin7
	PORT_InitTypeDef PORT_InitStructure;
	PORT_StructInit(&PORT_InitStructure);
	PORT_Init(MDR_PORTA, &PORT_InitStructure);
	PORT_InitStructure.PORT_OE		= PORT_OE_IN;
	PORT_InitStructure.PORT_FUNC	=	PORT_FUNC_ALTER;
	PORT_InitStructure.PORT_MODE	=	PORT_MODE_DIGITAL;
	PORT_InitStructure.PORT_SPEED	=	PORT_SPEED_MAXFAST;
	PORT_InitStructure.PORT_Pin		= (PORT_Pin_6 | PORT_Pin_7);
	PORT_Init(MDR_PORTA, &PORT_InitStructure);
	
	// CAN1
	CAN_InitTypeDef  sCAN;
	CAN_BRGInit(MDR_CAN1,CAN_HCLKdiv1);
	CAN_DeInit(MDR_CAN1);
	CAN_StructInit (&sCAN);
  sCAN.CAN_ROP  = DISABLE;
  sCAN.CAN_SAP  = DISABLE;
  sCAN.CAN_STM  = DISABLE;
  sCAN.CAN_ROM  = DISABLE;
  sCAN.CAN_PSEG = CAN_PSEG_Mul_2TQ;
  sCAN.CAN_SEG1 = CAN_SEG1_Mul_4TQ;
  sCAN.CAN_SEG2 = CAN_SEG2_Mul_4TQ;
  sCAN.CAN_SJW  = CAN_SJW_Mul_4TQ;
  sCAN.CAN_SB   = CAN_SB_3_SAMPLE;
  sCAN.CAN_BRP  = 31;
  CAN_Init (MDR_CAN1,&sCAN);
  CAN_Cmd(MDR_CAN1, ENABLE);
	/* Disable all CAN1 interrupt */
	CAN_ITConfig( MDR_CAN1, CAN_IT_GLBINTEN | CAN_IT_RXINTEN | CAN_IT_TXINTEN |
                CAN_IT_ERRINTEN | CAN_IT_ERROVERINTEN, DISABLE);
  /* Enable CAN1 interrupt from receive buffer */
  CAN_RxITConfig( MDR_CAN1 ,(1<<RX_BUF), ENABLE);
  /* Enable CAN1 interrupt from transmit buffer */
  CAN_TxITConfig( MDR_CAN1 ,(1<<TX_BUF), ENABLE);
  /* receive buffer enable */
  CAN_Receive(MDR_CAN1, RX_BUF, DISABLE);
}
Закрыть
Библиотеки EEPROM и CAN поставил записываться в IRAM1. Прошивка корректно отправляется, запись во флеш тоже происходит корректно. А вот ф-ция jumpToApplication() не работает.
Кто может помочь? В чем может быть проблема?


Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2016-апр-18 22:40 
Не в сети
Аватара пользователя

Зарегистрирован: 2011-авг-21 18:55
Сообщения: 274
Переход на загрузчик я делаю так - первый спойлер viewtopic.php?p=13345#p13345
Кстати, не забыли прошивку разметить с адреса 0x8001000, а то, может там 0x8000000.

_________________
Hack the Planet!


Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2017-фев-27 11:51 
Не в сети

Зарегистрирован: 2012-апр-12 18:33
Сообщения: 14
Добрый день! Вопрос такой, как передать управление из загрузчика основной программе, которая лежит по адресу 0x08001000. При использовании ассемблерной инструкции BX микроконтроллер уходит в прерывание HardFault. Кусок кода, который дан выше в ссылке, не рабочий. Так как переходит там вообще не по адресу, а значению, которое лежит по нужному адресу. Помогите пожалуйста, вот сам код:
void main()
{
SCB->VTOR = Address_main_prog; //0x08001000

__DSB();
#pragma asm
LDR R0, = Address_main_prog
BX R0
#pragma endasm
}

P.S. Среда CodeMaster от Phyton.


Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2017-фев-27 13:45 
Не в сети

Зарегистрирован: 2010-авг-30 19:12
Сообщения: 487
читайте внимательно описание ядра.Первые два адреса прошивки содержат значение для инициализации стека и адрес первой инструкции для исполнения.
Поэтому выход из загрузчика сделан
Цитата:
там вообще не по адресу, а значению, которое лежит по нужному адресу.
а
Цитата:
При использовании ассемблерной инструкции BX микроконтроллер уходит в прерывание HardFault
потому, что не может найти инструкции для исполнения.

_________________
О сколько нам открытий чудных
Готовит просвященья дух,
И опыт - сын ошибок трудных ... (Пушкин)

Пергаменты не утоляют жажду ("Фауст",Гете)


Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2017-фев-28 08:01 
Не в сети

Зарегистрирован: 2012-апр-12 18:33
Сообщения: 14
Проверяла все с переходом программы на саму себя и не правильно задавала адрес, поэтому пример и не работал, теперь все понятно, спасибо.


Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2018-янв-09 13:47 
Не в сети

Зарегистрирован: 2012-июл-24 19:43
Сообщения: 79
Добрый день!
Тоже озадачился созданием вторичного загрузчика. Увидел в теме кусок кода от R Max - вставил его в свою программу. Пока что во Flash из программы не пишу, а только делаю переход. Конкретно записал сперва в микроконтроллер программу загрузчика, а потом без стирания предыдущих записей (отметил в опциях программирования "Do not erase") - программу мигания светодиодом.
По идее предполагал, что программа загрузчика отсчитает таймаут и передаст управление программе мигания светодиодом. Впринципе, после таймаута светодиод замигал, но при этом в терминал повалил мусор. Убираю переход по адресу из программы загрузчика - мусора после окончания отсчета нет. Записываю программу мигания светодиодом только одну - тоже мусора нет, а вместе есть..
Решил, может быть загрузчик занимает на флеши больший объем - поставил адрес перехода 0x08010000 - не помогло.
Попробовал вынести функцию перехода на исполняемую программу в отдельный файл и поставил исполнение из ОЗУ - все равно мусор. Что может быть за бяка.
Настройки проекта загрузчика
[ img ]
Настройки проекта мигания светодиодом
[ img ]
Проекты заготовки загрузчика и мигания светодиодом прилагаю
Loader.rar - проект заготовки загрузчика
LED_BL.rar - тестовая программа с которой проверялось
Заранее спасибо за помощь


Вложения:
LED_BL.rar [152.65 КБ]
225 скачиваний
Loader.rar [313.22 КБ]
173 скачивания
Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2018-янв-09 16:38 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 472
Организация: Milandr
Откуда: ПКК "Миландр"
На первый взгляд:
Цитата:
В терминал повалил мусор
- это какой терминал имеется ввиду?

Если Uart1 то,
После SCB->VTOR = MainVectorTableAddr, используемый в Loader Uart по идее должен был отрубиться при отработке SystemInit в новом Reset_Handler. Обработчик UART1_IRQHandler в светодиодах тоже стал по умолчанию из startup_MDR32F9x.s.


Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2018-янв-09 17:35 
Не в сети

Зарегистрирован: 2012-июл-24 19:43
Сообщения: 79
Добрый вечер!
Прошу прощения, не уточнил - для вывода сообщений использую терминал, подключенный к UART2.
Пока не было перехода, выводилась надпись о том, что далее будет загружаться программа.
После того, как ввел переход, надпись не выводится (потом вообще закомментировал :-)), а начинает сыпаться мусор.
По-идее, думал тоже, что UART отрубится.. или перед переходом его надо отключить в программе?
Поставил вместо мигания светодиодом программу, которая шлет "Hello world" в тот же UART - все равно отправляется мусор.


Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2018-янв-09 19:32 
Не в сети
Аватара пользователя

Зарегистрирован: 2011-авг-21 18:55
Сообщения: 274
Vasiliy писал(а):
На первый взгляд:
Цитата:
В терминал повалил мусор
- это какой терминал имеется ввиду?

Если Uart1 то,
После SCB->VTOR = MainVectorTableAddr, используемый в Loader Uart по идее должен был отрубиться при отработке SystemInit в новом Reset_Handler. Обработчик UART1_IRQHandler в светодиодах тоже стал по умолчанию из startup_MDR32F9x.s.
+1
Я использую свой Startup.s, в котором удалена функция SystemInit (кстати в Startup.s для 1986ВЕ1Т сделано также самими vendor-ами), чтобы обойтись без повторной настройки PLL и уже запущенной периферии:
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
LDR R0, =__main
BX R0
ENDP
А SystemInit, который отработает в Startup.s в основной программе по идее обнулит настройки UART_CLK и порта D

_________________
Hack the Planet!


Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2018-янв-09 20:00 
Не в сети

Зарегистрирован: 2012-июл-24 19:43
Сообщения: 79
2 R Max, огромное спасибо - мусор на терминале исчез после того, как закомментировал SystemInit. С остальным, думаю, завтра разбираться буду


Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2018-янв-18 08:38 
Не в сети

Зарегистрирован: 2012-июл-24 19:43
Сообщения: 79
Добавил в проект загрузчика функции записи и стирания флеши, но залитая через X-modem прошивка не хочет запускаться.
Функции работы с флеш-памятью сделал по образу и подобию функций из проекта DFU-загрузчика R Max. Единственное, что выделил отдельный таймер на формирование задержек.
Для загрузки использую BIN-файл, сгенерированный командой
SET PATH=C:\Keil\ARM\BIN40\
fromelf.exe ".\LED.axf" --bin --output ".\LED.bin"
Код вызова функций записи во флеш:
temp=(frame[t]<<24) | (frame[t+1]<<16) | (frame[t+2]<<8) | (frame[t+3]);
irqs=NVIC->ISER[0];
NVIC->ICER[0]=0xFFFFFFFF;
EEPROM_ErasePage((MainVectorTableAddr+addr_shift), 0);
EEPROM_Write((MainVectorTableAddr+addr_shift), temp, 0);
NVIC->ISER[0]=irqs;
t=t+4;
addr_shift=addr_shift+0x10;
менял строчку формирования temp на
temp=(frame[t+3]<<24) | (frame[t+2]<<16) | (frame[t+2]<<8) | (frame[t]);
результат такой же
В свойствах файла с функциями работы с флеш (flash.c) отмечено, чтоб запускался из оперативной памяти. Я так понимаю, что для заголовочного файла это не нужно.
Проект и BIN-файл во вложении
Loader2.rar - проект загрузчика
LED.rar - BIN файл загружаемой программы


Вложения:
LED.rar [810 байт]
170 скачиваний
Loader2.rar [458.81 КБ]
165 скачиваний
Вернуться к началу
 Заголовок сообщения: Re: Сделать "бутлоудер"
СообщениеДобавлено: 2018-янв-24 13:25 
Не в сети

Зарегистрирован: 2012-июл-24 19:43
Сообщения: 79
Вроде бы более-менее довел до кондиции проект.
Оказалось, что программа не стирала память - задержку поставил 40 мкс вместо 40 мс ну и небольшие доделки связанные с тем, что стирается страница, а записывается за один раз только 32-разрядное слово и т.д.
В общем, выкладываю проект на всеобщее обозрение - вдруг кому пригодится. Программа "кушает" BIN-файлы, загружаемые по протоколу X-modem. Терминал подключается к UART2 (RS232 платы LDM-Helper c 1986ВЕ92)Записываемая программа должна занимать адресное пространство во флеши начиная с 0x08001000.
HEX-файлы, выдаваемые Keil конвертировал в BIN утилитой, приложенной к сообщению. Также прикладываю и сам проект загрузчика.


Вложения:
hex2bin.rar [21.95 КБ]
170 скачиваний
Loader2.rar [474.69 КБ]
201 скачивание
Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 12 сообщений ] 

Часовой пояс: UTC+03:00


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и 3 гостя


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти: 

cron
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB