发福利啦~~~STM32F407通过SD卡进行升级的程序已经修改好并且上传。该bootloader是直接把bin文件烧写到flash里面去,不是原子哥的跳转哦,理论上可以烧写960k的bin程序。程序流程是把一个需要烧写的bin文件放到SD卡里面,然后在bootloader程序里读出来并把bin文件烧写到指定的FLASH区域,并且让该程序运行。
说说辛酸史~~~~刚开始的时候走了很多弯路,第一个思路是像原子哥那样,通过把bin文件的内容复制到SRAM然后进行跳转运行,但后来仔细看了资料和他的程序,发现他的程序有限制,要在100k左右,太大了无法放得下,而且这个不是烧写到FLASH去运行,于是放弃这个思路。第二思路是把bin文件的内容复制到外部SRAM里面去,然后在外部SRAM里面运行时候,再把外部SRAM里面的bin内容给烧写到FLASH,相当于一开始从FLASH运行的程序跳转到外部SRAM去运行,然后通过外部SRAM运行的这个程序去把FLASH的内容给修改了,就是烧写新的程序。按照思路,在外部SRAM运行的程序是能够“独立”运行了,已经和FLASH没有关系,那时也能够对FLASH进行烧写,烧写地址是从0x8000000开始的,但烧写到16K以后就死掉了,就是整个程序都崩溃了。以为是在外部SRAM运行的程序不能把它自身的内容给复制出去,外部SRAM的程序存放地址是0x6800000,然后我又把0x6800000这个地址开始的数据复制出来烧写到FLASH去,有点像是一个人在跑步的时候把腿提起来给别人看一样,想想都觉得问题会出现在这里,使劲折腾验证了半天,发现不是这个问题,跑步的时候提起腿来给别人看居然没有“摔倒”~~~后来又去看了资料,发现所有运行的程序中断时都需要跑到FLASH的复位中断向量那里,但我都烧写到16K了,才跑出来折腾,这有点说不过去~~~反正到现在我也不知道是什么鬼在影响,哪位大神了解得可以解释解释。。。后来没办法了,只能换第三个思路,就是老老实实的写一个bootloader引导程序,然后把需要烧写的bin文件烧写到指定的FLASH里去。这个思路是通的,结果也是可以的。而且通过这种方式升级,速度比用FlyMcu.exe串口烧写的快很多很多。具体思路是通过修改原子哥第五十五章串口IAP实验里面的那个bootloader程序,把串口的那些功能全部去掉(串口升级的限制是120K左右,完全不够用啊,分包升级的方式感觉没什么思路也懒得动~~),把原子哥最后那个综合实验里面的 exeplay程序给移植进来,把打开SD卡进行选择文件升级直接给固定死成到SD卡里面的某个文件夹下面去找bin文件,比如在update文件夹下面找,目前只做了把一个bin文件放到这个文件夹下,然后直接升级,直接去掉人工选择的方式(人工选择的方式其实也挺好的,就是觉得固定死文件路径更加方便,避免麻烦)。在bootloader程序里面读到升级的标志位或者检测到按键按下,然后就去SD卡的update文件夹下读bin文件,并且把内容复制到外部SRAM(外部SRAM开辟了960K可以用来存这些数据),然后把从0x08010000到末尾的FLASH区域数据全部删除,再把外部SRAM的bin文件数据从0x08010000开始开始烧写进FLASH,烧写完成了,就把升级标志位清零,然后重启,重启时当然还是先从bootloader的程序开始运行,但判断到到标志位为0后以及0x08010000开始的数据不为FFFF则进行程序跳转。需要注意的是,用来升级的bin文件的起始地址要从0x08010000开始,设置好就可以了。现在还想通过网页传送bin文件的方式进行程序升级,可是网页方面没怎么接触,真希望有思路的大神能指导一二呀。至于这个SD卡升级的程序我就不敢贴出来献丑啦,现在加了网络的程序进去,基本上面目全非~~重要的SD卡升级程序部分还是有的,大神们也可以通过改改原子哥的程序来实现。其实SD卡升级在很多地方还是很有必要的,比如生产的时候,烧写好bootloader程序之后,插个有bin文件的SD卡进去升级就可以了,那速度真心快啊。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
可以啊,我开定时器3,中断里面就LED1闪烁,没有任何问题,主函数里面放TIM3_Int_Init(5000-1,8400-1); ,中断里:void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
{
LED1=!LED1;//D
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
},定时器初始化函数就用原子哥的,
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///ê1ÄüTIM3ê±Öó
TIM_TimeBaseInitStructure.TIM_Period = arr; //×Ô¶ˉÖØ×°ÔØÖμ
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //¶¨ê±Æ÷·ÖÆμ
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //ÏòéϼÆêyÄ£ê½
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //ÔêDí¶¨ê±Æ÷3¸üDÂÖD¶Ï
TIM_Cmd(TIM3,ENABLE); //ê1Äü¶¨ê±Æ÷3
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //¶¨ê±Æ÷3ÖD¶Ï
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //ÇàÕ¼óÅÏ輶2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00; //×óóÅÏ輶0
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
现在发现不是定时器的问题,应该是中断向量没有找到,所以一直没有进入中断处理函数,现在还是没有解决问题, void NVIC_Configuration()
{
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x10000);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
}
int main(void)
{
// RCC_DeInit();
// NVIC_DeInit();
RCC_Configuration();
// NVIC_SetVectorTable(0x08000000,0x0010000);
SCB->VTOR = FLASH_BASE | 0x10000;
// NVIC_Configuration();
// __disable_irq();
__enable_irq();
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 | 0x10000;
// SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
}
这些都试过了,还是没能解决问题,请问大神现在要怎么弄了?
现在发现并不是定时器和中断向量的问题,定时器中断可以正常运行,现在可能是串口问题,BOOT初始化了串口和一个中断函数,APP里面又初始化了两个串口和一个串口中断处理函数,现在通过BOOT运行APP除了串口不输出数据,其他都是正常的,单独APP烧录是可以输出数据的,这问题怎么解决?
一周热门 更多>