基于stm32的HID设备的简单boot设计(不含CRC校验)自动断开连接问题

首先介绍一下boot的设计过程步骤: 

创建一个boot工程,设置boot起开始地址,其大小根据自己需求分配如下图所示:

                              

创建一个APP工程,app起始地址为你的boot起始地址+boot size,app size其大小根据自己需求分配,设置如下:

单片机上电,通过按键操作或者指令操作,启动boot,跳转到app地址。

 boot代码如下:

	while(1)
	{
		ret=USB_GetData(Rcvdata,sizeof(Rcvdata));
		if(USB_Received_Flag==1)
		{
		if(ret&& strcmp((const char*)Rcvdata,"boot")==0)
		{
		memcpy(SendLedata,"bootloader...",sizeof(SendLedata));
		USB_SendData(SendLedata,sizeof(SendLedata));
			for(int i=0;i<=10;i++)
			{
				LED1_ON;
				delay_ms(100);
				LED1_OFF;
				delay_ms(100);
			}
				// __disable_irq();
		if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
			{	 
				iap_load_app(0x8004000);
			}	
			
	  } 
	}
  }

    注意在main函数前面加入中断向量表偏移: NVIC_SetVectorTable(0x8000000,0x4000);    并做如下修改,flash偏移量:


/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET  0x0 /*!< Vector Table base offset field. 
                                  This value must be a multiple of 0x200. */

改为

/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET  0x4000 /*!< Vector Table base offset field. 
                                  This value must be a multiple of 0x200. */

#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif 
/**
  * @brief  Sets the vector table location and Offset.
  * @param  NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory.
  *   This parameter can be one of the following values:
  *     @arg NVIC_VectTab_RAM
  *     @arg NVIC_VectTab_FLASH
  * @param  Offset: Vector Table base offset field. This value must be a multiple 
  *         of 0x200.
  * @retval None
  */
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
{ 
  /* Check the parameters */
  assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
  assert_param(IS_NVIC_OFFSET(Offset));  
   
  SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
}

     app代码如下:

while(1)
	{
    if(i<=3)
		{
	  memcpy(SendLedata,"app...",sizeof(SendLedata));
		USB_SendData(SendLedata,sizeof(SendLedata));
		delay_ms(1000);
		i++;
		}
		LED3_ON;
		delay_ms(100);
		LED3_OFF;
		delay_ms(100);
}

 跳转函数如下:

//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(u32 appxaddr)
{
	if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)	//检查栈顶地址是否合法.
	{ 
		jump2app=(iapfun)*(vu32*)(appxaddr+4);		//用户代码区第二个字为程序开始地址(复位地址)		
		MSR_MSP(*(vu32*)appxaddr);					//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
//    for(int i = 0; i < 8; i++)
//		{			
//			NVIC->ICER[i] = 0xFFFFFFFF;	/* 关闭中断*/
//			NVIC->ICPR[i] = 0xFFFFFFFF;	/* 清除中断标志位 */
//		}	
		jump2app();									//跳转到APP.
	}
}		

//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(uint32_t addr) 
{
    MSR MSP, r0 			//set Main Stack value
    BX r14
}

       一般来说,都需要关闭所有的中断,才不会在boot向app跳转过程中跳飞,这里我没有关闭中断,如果需要则在boot工程中main函数第一行加入关闭中断__disable_irq();在app的main函数第一行加入中断使能__enable_irq();,这里我的HID设备中usb设备中断的优先级是最高的,保证单片机上电后,计算机可以识别到自己的HID设备,如若关闭,则一直显示是设备已经断开连接,或者在你的设备管理器中显示的是未知的设备描述符,这是因为下位机的HID设备驱动未正确初始化即关闭了中断。

 另注意事项:在你的boot工程中,不能是初始化后在while(1)中就是执行跳转到app的函数,这样的话,设备是连接不上去的,如下表示:

	while(1)
	{
		
		memcpy(SendLedata,"bootloader...",sizeof(SendLedata));
		USB_SendData(SendLedata,sizeof(SendLedata));
			for(int i=0;i<=10;i++)
			{
				LED1_ON;
				delay_ms(100);
				LED1_OFF;
				delay_ms(100);
			}
				// __disable_irq();
		if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
			{	 
				iap_load_app(0x8004000);
			}	
			
	}
  }

测试结果如下:

正确做法是通过按键或者是发送跳转指令去操作,我的boot操作如下:

	while(1)
	{
		ret=USB_GetData(Rcvdata,sizeof(Rcvdata));
		if(USB_Received_Flag==1)
		{
		if(ret&& strcmp((const char*)Rcvdata,"boot")==0)
		{
		memcpy(SendLedata,"bootloader...",sizeof(SendLedata));
		USB_SendData(SendLedata,sizeof(SendLedata));
			for(int i=0;i<=10;i++)
			{
				LED1_ON;
				delay_ms(100);
				LED1_OFF;
				delay_ms(100);
			}
				// __disable_irq();
		if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
			{	 
				iap_load_app(0x8004000);
			}	
			
	  } 
	}
  }

  测试结果如下:

boot:点击下载

app:点击下载

猜你喜欢

转载自blog.csdn.net/github_37687123/article/details/81099892