stm32f103cbt6 bootloader

/* USER CODE BEGIN Header /
/
*


  • @file : main.c
  • @brief : Main program body

  • @attention
  • Copyright © 2024 STMicroelectronics.
  • All rights reserved.
  • This software is licensed under terms that can be found in the LICENSE file
  • in the root directory of this software component.
  • If no LICENSE file comes with this software, it is provided AS-IS.

/
/
USER CODE END Header /
/
Includes ------------------------------------------------------------------*/
#include “main.h”

/* Private includes ----------------------------------------------------------/
/
USER CODE BEGIN Includes */
#include <string.h>
#include “stm32f1xx_hal.h”

#include “btld.h”
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------/
/
USER CODE BEGIN PTD */
My_struct Rx_data;
My_struct Rx_M_data;
uint32_t Data_Length;
uint32_t Multiple_of_6;
uint32_t Remainder_of_6;
uint16_t App_crc;

uint32_t Data_Count;
bool Count_Flag = false;
uint8_t Err_CAN ;

CAN_TxHeaderTypeDef TxHeader;
uint8_t TxData[8];
uint32_t TxMailbox;

uint8_t G_loader_mode=0;
uint8_t G_flash_erase_CMD = 0;
uint8_t G_flash_pre_Program_CMD = 0;
uint8_t G_run_app_CMD=0;
uint8_t G_return_CRC_CMD=0;
uint8_t G_return_BOOT_CRC_CMD=0;
uint8_t G_end_flash_CMD=0;
uint8_t G_FlashInProgress=0;
uint32_t Sequence_Num = 0;
uint32_t Lastdata_Of_Arr = 0;
uint32_t test_count = 0;

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------/
/
USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------/
/
USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
/
USER CODE BEGIN PFP /
void send_confirm_msg(uint8_t status);
void Run_Application(void);
/
USER CODE END PFP */

/* Private user code ---------------------------------------------------------/
/
USER CODE BEGIN 0 /
void config_can_filter(void);
/
USER CODE END 0 */

/**

  • @brief The application entry point.
  • @retval int
    */
    int main(void)
    {

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals /
MX_GPIO_Init();
MX_CAN_Init();
/
USER CODE BEGIN 2 */
config_can_filter();

/* USER CODE END 2 */

/* Infinite loop /
/
USER CODE BEGIN WHILE */
while (1)
{

/* Erase Flash */
if(G_flash_erase_CMD){
	if(btld_EraseFlash()==HAL_OK){
		/* Erase Success */
		//Send CAN message to know we are in loader mode
		TxHeader.ExtId= 0x1809FEC8;//TX_FEEDBACK_CANID + CANTX_SA;
		TxHeader.IDE=CAN_ID_EXT;
		TxHeader.RTR=CAN_RTR_DATA;
		TxHeader.DLC=1;
		TxData[0]=0xF0;

		HAL_CAN_AddTxMessage(&hcan,&TxHeader,TxData,&TxMailbox);
	}else{
		/* Erase failed */
		//Send CAN message to know we are in loader mode
		TxHeader.ExtId = 0xff0055;//TX_FEEDBACK_CANID + CANTX_SA;
		TxHeader.IDE=CAN_ID_EXT;
		TxHeader.RTR=CAN_RTR_DATA;
		TxHeader.DLC=1;
		TxData[0]=0xFF;

		HAL_CAN_AddTxMessage(&hcan,&TxHeader,TxData,&TxMailbox);
	}
	G_flash_erase_CMD=0;
}

if(G_flash_pre_Program_CMD == 1)
{
	G_flash_pre_Program_CMD = 0;
	btld_FlashBegin();
	send_confirm_msg(0xff);
}

/* Run Application command */
	if(G_run_app_CMD){
		//btld_JumpToApp();

// Run_Application();
}

	/* Calculate and send APPLICATION CRC */
	if(G_return_CRC_CMD){
		uint16_t checksum;

// if(Data_Length == btld_GetAppLength())
// {
checksum=btld_GetChecksum(Data_Length);//
if(App_crc == checksum)
{
TxHeader.ExtId = 0x1809FEC8;//
TxHeader.IDE = CAN_ID_EXT;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.DLC = 4;
TxData[0] = 0xF6;
TxData[1] = 0x00;//0xFF = Success, 0x00 = failed
TxData[2] = 0x00;//index & 0x00FF;
TxData[3] = 0x00;//(index & 0xFF00)>>8;

				HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox);
				}

// }

		/* Send Available flash size for application */
		G_return_CRC_CMD=0;
	}

	/* Calculate and send BOOTLOADER CRC */
	if (G_return_BOOT_CRC_CMD) {
		uint32_t checksum;

// checksum = btld_GetBootChecksum();

		/* Send Achecksu, */
		TxHeader.ExtId = 0xff0088;//TX_FEEDBACK_CANID + CANTX_SA;
		TxHeader.IDE = CAN_ID_EXT;
		TxHeader.RTR = CAN_RTR_DATA;
		TxHeader.DLC = 5;
		TxData[0] = 0x0F;

		TxData[1] = (checksum & 0xFF000000) >> 24;
		TxData[2] = (checksum & 0x00FF0000) >> 16;
		TxData[3] = (checksum & 0x0000FF00) >> 8;
		TxData[4] = (checksum & 0x000000FF);

		HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox);

		G_return_BOOT_CRC_CMD = 0;
	}

	/* End Falshing and respond success */
	if (G_end_flash_CMD && G_FlashInProgress){

// btld_FlashEnd();
// btld_SaveAppLength();
// btld_SaveAppChecksum();
G_FlashInProgress=0;
G_end_flash_CMD=0;
// led_state = 1;

		// request next WORD
		/* Send success */
		TxHeader.ExtId= 0xff0077;//TX_FEEDBACK_CANID + CANTX_SA;
		TxHeader.IDE=CAN_ID_EXT;
		TxHeader.RTR=CAN_RTR_DATA;
		TxHeader.DLC=2;
		TxData[0]=0xF7;
		TxData[1]=0xFF;	//Success

		HAL_CAN_AddTxMessage(&hcan,&TxHeader,TxData,&TxMailbox);
	}
	if(Err_CAN == BL_CHKS_ERROR)
		send_confirm_msg(0x00);

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}
/* USER CODE END 3 */
}

/**

  • @brief System Clock Configuration
  • @retval None
    */
    void SystemClock_Config(void)
    {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Initializes the RCC Oscillators according to the specified parameters

  • in the RCC_OscInitTypeDef structure.
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV2;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
    Error_Handler();
    }

/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}

/**

  • @brief CAN Initialization Function
  • @param None
  • @retval None
    */
    static void MX_CAN_Init(void)
    {

/* USER CODE BEGIN CAN_Init 0 */

/* USER CODE END CAN_Init 0 */

/* USER CODE BEGIN CAN_Init 1 */

/* USER CODE END CAN_Init 1 /
hcan.Instance = CAN1;
hcan.Init.Prescaler = 18;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_3TQ;
hcan.Init.TimeSeg2 = CAN_BS2_4TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = DISABLE;
hcan.Init.AutoWakeUp = DISABLE;
hcan.Init.AutoRetransmission = DISABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
Error_Handler();
}
/
USER CODE BEGIN CAN_Init 2 */

/* USER CODE END CAN_Init 2 */

}

/**

  • @brief GPIO Initialization Function
  • @param None
  • @retval None
    /
    static void MX_GPIO_Init(void)
    {
    /
    USER CODE BEGIN MX_GPIO_Init_1 /
    /
    USER CODE END MX_GPIO_Init_1 */

/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();

/* USER CODE BEGIN MX_GPIO_Init_2 /
/
USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 /
/
config_can_filter ---------------------------------------------------------/
/
Setup Can-Filter /
/
----------------------------------------------------------------------------*/
void config_can_filter(void){
CAN_FilterTypeDef sFilterConfig;

   	   	   	   	   	   	  /* Leave mask bits for different messages commands
   	   	   	   	   	   	  |  	  	  	  	  	  	  	  	  	  	  	  	 */

uint32_t filterMask= RXFILTERMASK;
uint32_t filterID= RXFILTERID; // Only accept bootloader CAN message ID

/##-2- Configure the CAN Filter ###########################################/
//sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0;
sFilterConfig.FilterIdLow = 0;
sFilterConfig.FilterMaskIdHigh = 0;
sFilterConfig.FilterMaskIdLow = 0;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.FilterBank = 0;

// 配置过滤器
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}

if(HAL_CAN_Start(&hcan) != HAL_OK)
{

}
// 使能FIFO接收到一个新报文中断
if(HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{

}

}

/* HAL_CAN_RxCpltCallback ----------------------------------------------------/
/
Interrupt callback to manage Can Rx message ready to read /
/
----------------------------------------------------------------------------/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef
phcan)
{
CAN_RxHeaderTypeDef rxheader;
uint8_t data[8];
static uint16_t num = 0;

HAL_CAN_GetRxMessage(phcan,CAN_RX_FIFO0,&rxheader,data);

if (data[0]==0xF0){
	G_loader_mode=1;
}

/* erease flash cmd ----------------------------------------------*/
if (rxheader.ExtId == CANID_S_B){
	G_flash_erase_CMD=1;
}

/* run app cmd ----------------------------------------------*/
if (data[0]==0xF2 && G_loader_mode==1){

// if(btld_CheckForApplication()==BL_OK){
// G_run_app_CMD=1;
// }
}
/* ask bootloader crc cmd ----------------------------------------------*/
if (data[0]0x0F && G_loader_mode1){
G_return_BOOT_CRC_CMD=1;
}

/* ask for app crc cmd ----------------------------------------------*/
if (data[0]==0xF4 && G_loader_mode==1){
	G_return_CRC_CMD=1;
}
/* start flash cmd ----------------------------------------------*/
if (data[0]==0xF5 && G_loader_mode==1){

// G_index=0;
// G_start_flash_CMD=1;
}

/* flash done cmd ----------------------------------------------*/
if (data[0]==0xF7 && G_loader_mode==1){
	G_end_flash_CMD=1;
}

if(Count_Flag == true)
	Data_Count ++;
if(rxheader.ExtId == CANID_UM_BF)//message base information
{
	Count_Flag = true;
	Data_Length = (uint32_t)data[5] | ((uint32_t)data[4] << 8) | ((uint32_t)data[3] << 16) | ((uint32_t)data[2] << 24);
	Multiple_of_6 = Data_Length / 6;
	Remainder_of_6 = Data_Length % 6;

	App_crc = (uint16_t)data[7] | ((uint16_t)data[6] << 8);
	G_flash_pre_Program_CMD = 1;
}

if(rxheader.ExtId == CANID_B_END)//end frame
{
	int32_t jack = 0;
	jack = (Data_Count - 1) * 6 - Data_Length;
	if((jack > 6)||(jack < 0))
	{
		Data_Count = 0;
		Data_Length = 0;
		Count_Flag = false;
		Err_CAN = BL_CHKS_ERROR;
	}
}

/* next flash data cmd ----------------------------------------------*/
if(rxheader.ExtId == CANID_UM_DP)//data frame
{
uint64_t G_uint64_to_write = 0;
uint32_t G_uint32_to_write = 0;
uint16_t G_uint16_to_write = 0;
uint32_t index;
test_count++;
Sequence_Num = (data[0] << 8) | data[1];

	G_uint32_to_write = (uint32_t) data[2]
						| (((uint32_t) data[3]) << 8)| (((uint32_t) data[4]) << 16)
						| (((uint32_t) data[5]) << 24) ;

	G_uint16_to_write =  (uint16_t) data[6]
						| (((uint16_t) data[7]) << 8);

	HAL_CAN_DeactivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	if(btld_FlashNext_32(G_uint32_to_write,&index) == BL_OK){
		if(btld_FlashNext_16(G_uint16_to_write,&index) == BL_OK){
		if(HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) == HAL_OK){
			send_confirm_msg(0xff);
		}
		else
			send_confirm_msg(0x01);
	}
	else
		send_confirm_msg(0x00);
	}
	if(Sequence_Num  == (Multiple_of_6 + 1)){//last frame


		btld_FlashEnd();
		G_return_CRC_CMD = 1;
	}

#if 0
test_count++;
Sequence_Num = (data[0] << 8) | data[1];

	if(Sequence_Num  == (Multiple_of_6 + 1))
	{
		if(num < 170){
			Rx_data.Remainder_Count = num;
			Rx_data.Lastdata_Of_Arr = num * 6 + Remainder_of_6 -1;
			memcpy(&Rx_data.buf[num*6],&data[2],6);
			memset(&Rx_data.buf[(num+1)*6],0xff,1020-(num+1)*6);
			Rx_data.Recv_Finish = true;

		}
		else{
			Rx_M_data.r_count = num;
			Rx_M_data.Lastdata_Of_Arr = (num-170) * 6 + Remainder_of_6;
			memcpy(&Rx_M_data.buf[(num-170)*6],&data[2],6);
			memset(&Rx_data.buf[(num-170+1)*6],0xff,1020-(num-170+1)*6);
			Rx_M_data.Recv_Finish = true;

		}
		num = 0;
	}
	else
	{
		if(num < 170) // for 1020 bytes data
		{
			memcpy(&Rx_data.buf[num*6],&data[2],6);
			if(num == 169)
			{
				Rx_data.r_count++;
				Rx_data.Recv_Finish = true;
			}
			else
				send_confirm_msg(0xff);
		}
		else if(num < 340)
		{
			memcpy(&Rx_M_data.buf[(num-170)*6],&data[2],6);
			if(num == 339)
			{
				Rx_M_data.r_count ++;
				Rx_M_data.Recv_Finish = true;
				num = 0;
			}
			else
				send_confirm_msg(0xff);
		}
		num++;
	}

#endif
}

}

/* Run_Application -----------------------------------------------------------/
/
Bootloader is done. Prepare the mcu for application-Start and finaly Start /
/
----------------------------------------------------------------------------*/
void Run_Application(void){
// HAL_TIM_Base_Stop_IT(&htim4);
// HAL_TIM_Base_DeInit(&htim4);
HAL_CAN_DeactivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING);
// HAL_CAN_Stop(&hcan);
HAL_CAN_DeInit(&hcan);
btld_JumpToApp();
}

/* send_confirm_msg ---------------------------------------------------------/
/
replay to can-massege /
/
----------------------------------------------------------------------------*/
void send_confirm_msg(uint8_t status){
// uint16_t index;

// index = G_index/4;

TxHeader.ExtId = 0x1808FEC8;//0x00FE00 + CANTX_SA;
TxHeader.IDE = CAN_ID_EXT;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.DLC = 4;
TxData[0] = 0xF6;
TxData[1] = status;//0xFF = Success, 0x00 = failed
TxData[2] = 0x00;//index & 0x00FF;
TxData[3] = 0x00;//(index & 0xFF00)>>8;

HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox);

}
/* USER CODE END 4 */

/**

  • @brief This function is executed in case of error occurrence.
  • @retval None
    /
    void Error_Handler(void)
    {
    /
    USER CODE BEGIN Error_Handler_Debug /
    /
    User can add his own implementation to report the HAL error return state /
    __disable_irq();
    while (1)
    {
    }
    /
    USER CODE END Error_Handler_Debug */
    }

#ifdef USE_FULL_ASSERT
/**

  • @brief Reports the name of the source file and the source line number
  •     where the assert_param error has occurred.
    
  • @param file: pointer to the source file name
  • @param line: assert_param error line source number
  • @retval None
    */
    void assert_failed(uint8_t file, uint32_t line)
    {
    /
    USER CODE BEGIN 6 /
    /
    User can add his own implementation to report the file name and line number,
    ex: printf(“Wrong parameters value: file %s on line %d\r\n”, file, line) /
    /
    USER CODE END 6 /
    }
    #endif /
    USE_FULL_ASSERT */
  • 23
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值