IAP注意事项

使用正点原子F407的IAP例程时,发现了一个问题,在进行IAP升级后,APP中的串口无法使使用,串口接收不到中断,printf会卡死。

造成这种现象的原因可能是因为外设在bootloader中初始化的时候,对串口进行了一些映射无法被复位中断重置。

在经过不(tong)懈(ku)的debug后,发现在跳转到APP之前,需要先关闭所有中断响应,并将初始化后的外设复位,跳转到app后再打开中断就解决了。

//jump2app之前操作
INTX_DISABLE();
USART_DeInit(USART1);
//进入main之后操作
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x10000);
INTX_ENABLE();

其中的开启中断和关闭中断是用汇编实现的,学过arm课程的应该都很容易看懂,没学过的也不用深究。

//关闭所有中断(但是不包括fault和NMI中断)
__asm void INTX_DISABLE(void)
{
	CPSID   I
	BX      LR	  
}
//开启所有中断
__asm void INTX_ENABLE(void)
{
	CPSIE   I
	BX      LR  
}

而对中断向量表进行偏移设置,网上包括原子都有大量文献说明。

对于工程:
其中bootloader其实什么都不用做修改。
在这里插入图片描述

target这里也不需要做什么修改。
在这里插入图片描述

代码这里做下修改就可以了。
在这里插入图片描述

而APP在编译前需要修改target:
在这里插入图片描述
如果不做修改,生成的map对应会有问题。app会从8000000开始找代码运行。

如果在下载那里改成对应的地址区域,就可以直接下载到0x08010000开始的地址。
在这里插入图片描述

下面随便记录一下其他内容~

void USART_DeInit(USART_TypeDef* USARTx)
{
  /* Check the parameters */
  assert_param(IS_USART_ALL_PERIPH(USARTx));

  if (USARTx == USART1)
  {
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
  }
  //省略其他外设枚举
}

再往下看可以发现:

void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_RCC_APB2_RESET_PERIPH(RCC_APB2Periph));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  if (NewState != DISABLE)
  {
    RCC->APB2RSTR |= RCC_APB2Periph;
  }
  else
  {
    RCC->APB2RSTR &= ~RCC_APB2Periph;
  }
}

查阅手册发现:
在这里插入图片描述
那么这里的操作就是先复位串口1,再取消复位串口1。
这样就可以解决因为bootloader初始化外设之后留下的bug。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值