当前位置: 首页 > news >正文

GD32F303-IAP的过程和实验

使用的芯片为GD32F303VC

什么是IAP呢?有个博主写的很清楚;就是远程升级;

【单片机开发】单片机的烧录方式详解(ICP、IAP、ISP)_isp烧录-CSDN博客

我们需要写一个boot 和APP 

通过 boot对APP的程序进行更新;操作;而不是像单个调试板子那样使用ISP 和 ICP进行烧录;升级过程:上位机和板子进行can通讯;上位机将APP的BIN文件给板子;Boot 进行 0x0801 0000处 的擦除和写入;进而完成APP的更新过程;

也可以看我上篇文章 如何进行在 0x0801 0000处进行擦除和写入的;

GD32F303----内部Flash读写-CSDN博客

 IAP(In-Application Programming):在应用编程

还需要了解一些关于Flash的内内容;

在手册里面对应的就是:

 GD32F303VCT6-MCU选择器-兆易创新 GigaDevice | 官方网站

前段时间 需要给电池系统升级 ,插上can线,还需要给电池断电,在开启的3s中进行上电;感觉很是麻烦;

实验过程

BOOT:

上电,LED1和LED2 同时闪烁200ms的间隔亮灭; 4s之内没有接收到更新固件的指定(can没有收到数据),那么如果进入can的函数,会更新这个全局变量 g_T_bootIdle ,即进入APP;


#include "gd32f30x.h"
#include "systick.h"
#include "Global.h"
#include "gpio.h"
#include "timer.h"
//#include "can.h"
#include "cancomm.h"
#include <stdbool.h>
#include <stdio.h>

#define DEV_VER  0x0200


CBL_CMD_LIST	CMD_List;
u32 g_T_bootIdle = 0;//boot idle timeout.

void GlobeInit(void);
void Init_CMD_List(void);

/*****************************************************************************
 * 函数名称: 	main
 *
 * 功能描述: 
 *
 * 调用条件限定:	None
 *						
 * 输入参数: 
 *
 * 返回结果: None
 *
 * 附属影响: None
 * 
 * 其他: 		主函数
 *					 
 *****************************************************************************/
int main(void)
{
	uint32_t u32T_Led		= 0;//led flash timeout.
	uint8_t  FlagLedToggle	= 0;//flag of led toggle

//	VECT_TAB_OFFSET-------0x10000		//Bootloader时需将system_stm32f10x.c文件更改此处为0x1000
	//nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x00000);
	
	GlobeInit();
	
	while(1)
	{		
		fnCan1DealProc();//receive data process.
		
		if(Timer_GetMsDif(g_T_bootIdle, Timer_GetMs()) >= 4000)//
		{
			if((*((uint32_t *)APP_START_ADDRESS)!=0xFFFFFFFF)) //跳转地址可能是0x08010000(64KB)  			  #define APP_START_ADDRESS			((uint32_t)0x08010000)																																									
			{
				//Disable the TIM Counter
				timer_disable(TIMER2);
				CAN_BOOT_JumpToApplication(APP_START_ADDRESS);	
			} else {
				g_T_bootIdle = Timer_GetMs();
			}
		}
		
		if(Timer_GetMsDif(u32T_Led, Timer_GetMs()) >= 200)//
		{
			u32T_Led = Timer_GetMs();
			
			if(FlagLedToggle == 0) {
				FlagLedToggle = 1;
				LED2 = 1;//灭
				LED1 = 1;//灭
			} else {
				FlagLedToggle = 0;
				LED2 = 0;//亮
				LED1 = 0;//亮
			}
		}
	}
}

/*****************************************************************************
 * 函数名称: 	GlobeInit
 *
 * 功能描述: 
 *
 * 调用条件限定:	None
 *						
 * 输入参数: 
 *
 * 返回结果: None
 *
 * 附属影响: None
 * 
 * 其他: 		系统总初始化
 *					 
 *****************************************************************************/
void GlobeInit(void)
{	
	SystemInit();  
	systick_config();
	TIMR2_Init(500,71);		//72M/72=1000Khz的计数频率,计数到500为500us		
	Can_Init();
	GPIOInit();
	Init_CMD_List();
}

/*****************************************************************************
 * 函数名称: 	TIM3_IRQHandler
 *
 * 功能描述: 
 *
 * 调用条件限定:	None
 *						
 * 输入参数: 
 *
 * 返回结果: None
 *
 * 附属影响: None
 * 
 * 其他: 		定时器2中断服务程序
 *					 
 *****************************************************************************/
void TIMER2_IRQHandler(void)   //TIM2中断
{
	if(timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP) != RESET)  //检查TIM2更新中断发生与否
	{	
		g_u32HalfMsCnt++;//0.5毫秒奇数器
		timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);  //清除TIMx更新中断标志 
	}
}


void Init_CMD_List(void)
{
	CMD_List.OnlineCheck		= 0x01;
	CMD_List.EraseFlash			= 0x03;
	CMD_List.SetBaudRate		= 0x04;
	CMD_List.BlockWriteInfo		= 0x05;
	CMD_List.WriteBlockFlash	= 0x06;
	CMD_List.BlockReadInfo		= 0x07;
	CMD_List.ReadBlockFlash		= 0x08;
	CMD_List.ExcuteApp			= 0x09;
	CMD_List.CmdFaild			= 0x00;
	CMD_List.CmdSuccess			= 0x0A;	
}

/**
  * @brief  控制程序跳转到指定位置开始执行 。
  * @param  Addr 程序执行地址。
  * @retval 程序跳转状态。
  */
void CAN_BOOT_JumpToApplication(__IO u32 Addr)
{
	pFunction Jump_To_Application;
	__IO u32 JumpAddress; 
	
	/* Test if user code is programmed starting from address "ApplicationAddress" */
	if (((*(__IO u32*)Addr) & 0x2FFE0000 ) == 0x20000000)
	{ 
	  /* Jump to user application */
	  JumpAddress = *(__IO u32*) (Addr + 4);
	  Jump_To_Application = (pFunction) JumpAddress;
		//__set_PRIMASK(1);//关闭所有中断
		//CAN_ITConfig(CAN1,CAN_IT_FMP0, DISABLE);
	  /* Initialize user application's Stack Pointer */
	  __set_MSP(*(__IO u32*)Addr);
	  Jump_To_Application();
	}
}

注意这里;

 

APP:

  GPIO_LedWork(); LED1和LED2 1s进行反转一次;8s之后再次进入boot,因此  NVIC_SystemReset();相当于掉电 在上电的过程。

#include "gd32f30x.h"
#include "systick.h"



void GlobeInit(void);


/*****************************************************************************
 * 函数名称:     main
 *
 * 功能描述: 
 *
 * 调用条件限定:    None
 *                        
 * 输入参数: 
 *
 * 返回结果: None
 *
 * 附属影响: None
 * 
 * 其他:         主函数
 *                     
 *****************************************************************************/
int main(void)
{    
//    VECT_TAB_OFFSET-------0x10000        //Bootloader时需将system_stm32f10x.c文件更改此处为0x1000
     //nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x10000);
    
    GlobeInit();
    
    while(1)
    {
        //GPIO_InputDetect();
        fnCan1DealProc();
         fnSampProc();//电压电流采样    
//        fnCheckProc();
         fnBmsCtrlProc();//BMS控制        
//         fnDataSave();
        //LEDDealCtrl();
        GPIO_LedWork();
        
    static uint32_t  s_u32Time = 0;
    if(Timer_Get5msDif(s_u32Time, Timer_Get5ms()) >= 1600) // 5*1600 = 8000ms 8s后进入boot,
    {
        s_u32Time = Timer_Get5ms();
        __set_FAULTMASK(1);
        NVIC_SystemReset();
        
    }
    }
}
void GPIO_LedWork(void)
{	
	static uint8_t   s_u8LedVal = 0;
	static uint32_t  s_u32Time = 0;
	
	if(Timer_Get5msDif(s_u32Time, Timer_Get5ms()) >= 200) // 5*200 = 1000ms 5ms增加一次 ,增加200次,
	{
		s_u32Time = Timer_Get5ms();
		
		s_u8LedVal ^= 1; // turn
		GPIO_LED1_WORK(s_u8LedVal); // on 1s,off 1s                                                                                           
		GPIO_LED2_WORK(s_u8LedVal); // on 1s,off 1s
	}
}

 

通过上位机和板子的can通信,可以发送一帧 让板子复位的命令; 进入BOOT 就是升级了 擦除APP的页地址;在写入;

相关文章:

  • 模型开发中的微调是干什么
  • OFDM CP 对解码影响
  • 质量属性场景:构成要素及常见示例精析
  • 制造一只电子喵 (qwen2.5:0.5b 微调 LoRA 使用 llama-factory)
  • 【3分钟准备前端面试】yarn
  • STM32LL库编程系列第八讲——ADC模数转换
  • SQL 全文检索原理
  • C#容器源码分析 --- Stack<T>
  • 蓝桥杯真题——好数、R格式
  • Linux-内核驱动-led
  • C# --- IEnumerable 和 IEnumerator
  • app逆向专题三:adb工具的使用
  • python格式化字符串漏洞
  • 想写回忆录了讲讲我的故事
  • 《汽车制造技术基础》第一次作业
  • FileOutputStream 详解与记忆方法
  • 第十六届蓝桥杯省赛JavaB组题解
  • Ansible-Playbook详解
  • 第十六届蓝桥杯大赛软件赛省赛 C/C++ 大学B组
  • 【图像处理基石】什么是抗锯齿(Anti-Aliasing)?
  • wordpress 注册菜单/seo经验
  • 兰州论坛网站建设/网络宣传渠道有哪些
  • 网站怎么做描文本/百度指数的主要功能有
  • 做筹款的网站需要什么资质/天津百度关键词推广公司
  • 网站开发语言查看器/营销网络是啥意思
  • 做数学题的网站/如何推广软件