STM32 BOOT跳转到APP后初始化完后成死机 用了FREERTOS
本帖最后由 liyancao001 于 2024-11-26 15:57 编辑<p>芯片时STM32F767ZGT6,以前同样芯片的另一个板子做过CAN的IAP,是测试通了的,现在又不行了。。</p>
<p>使用STM32CUBEMX建的工程,BOOT和APP都是用了FREERTOS,然后跳转到APP是正常的,但是死在MX_FREERTOS_Init();</p>
<p>求指点啊,之前做过CAN的IAP,运行正常,现在弄串口结果不行了。。。</p>
<p> </p>
<p>我在MX_FREERTOS_Init();里面加了串口打印,函数下面也加了,发现里面需要打印的数据都是输出正常的,但是到函数下面就不行了。</p>
<p> MX_FREERTOS_Init();//<span style="color:#e74c3c;">这个函数体里面的最后加了一句串口打印,打印是正常的</span>。。<br />
printf("ADECU_APP_2,0x%X\r\n",SCB->VTOR);//<span style="color:#e74c3c;">这句一直打印不出来。</span><br />
/* Start scheduler */<br />
osKernelStart();</p>
<p> </p>
<p>其中BOOT跳转前把中断也都关了</p>
<p>APP相比没做IAP之前,就增加了2项:(没做IAP之前程序运行正常)</p>
<p>1)MAIN开头的中断向量偏移</p>
<p> int main(void)<br />
{<br />
/* USER CODE BEGIN 1 */<br />
SCB->VTOR = FLASH_BASE | 0x80000;//设置偏移量</p>
<p> </p>
<p>2)option for target里把IROM1的起始地址改为了0x8080000,start改为了0x40000</p>
<p> </p>
<p>而BOOT跳转函数如下:</p>
<p>void iap_load_app(uint32_t appxaddr)// 调用时参数为0x08080000<br />
{<br />
if(((*(vu32*)appxaddr)&0x2FF00000)==0x20000000) { //检查栈顶地址是否合法.<br />
HAL_RCC_DeInit();<br />
INTX_DISABLE();<br />
SysTick->CTRL = 0X00;//卡死后新增的,但是没有用,跟上面应该是功能重复的<br />
SysTick->LOAD = 0;//卡死后新增的,但是没有用,跟上面应该是功能重复的<br />
SysTick->VAL = 0;//卡死后新增的,但是没有用,跟上面应该是功能重复的<br />
__disable_irq();//卡死后新增的,但是没有用,跟上面应该是功能重复的<br />
<br />
jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)<br />
MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)<br />
jump2app(); //跳转到APP.<br />
}<br />
}</p>
<p> </p>
<p> </p>
<p>241126上午又做了一些测试:</p>
<p>改了一版APP程序,把FREERTOS给关掉了,其他程序给屏蔽了,WHILE主循环只保留两个功能:</p>
<p>1)延时并且打印999,</p>
<p>2)查询1ms定时器累加变量值,超过1000则清零并打印888.</p>
<p>结果实测只打印了999,没有打印888,因此就是中断没有打开,所以BOOT的程序不能只关不开?</p>
<p>于是重新改写BOOT程序: </p>
<pre>
<code> HAL_Init();
INTX_DISABLE();
/* 关闭所有中断,清除所有中断挂起标志 */
for (i = 0; i < 8; i++)
{
NVIC->ICER=0xFFFFFFFF;
NVIC->ICPR=0xFFFFFFFF;
}
__set_PRIMASK(0);//开启总中断
__set_CONTROL(0);
jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
jump2app(); //跳转到APP.</code></pre>
<p>结果:</p>
<p> 999和888都打印正常了。。。于是乎很高兴的回到原始APP(有freertos)中。发现跳转过去立刻死掉。。。悲剧了</p>
<p>用在线调试查看死掉的位置,发现卡在SPI_WaitFifoStateUntilTimeout中,一直等待flag。</p>
<p>于是乎把SPI的几个初始化都注释掉,发现又一直卡在__HAL_TIM_GET_FLAG里,等于定时器初始化一直没过。倒是没有进硬件错误。</p>
<p>简单来说BOOT最后把中断关了的话APP里初始化正常,不是进不去中断,而BOOT最后把中断打开的话APP连初始化都过不了。</p>
<p>不明白原因,然后把APP的偏移和option for target都去掉,回归普通的程序,下载程序发现freertos中任务里串口1s间隔打印的数据都是正常的。</p>
<p>更迷糊了,我这问题到底是出在BOOT上还是APP上。。。</p>
<p>APP必须自己开中断吗?以前做CAN刷写时,BOOT只用以下语句:</p>
<pre>
<code> HAL_RCC_DeInit();
INTX_DISABLE();
jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
jump2app(); </code></pre>
<p>而APP也不用管开中断的事。。</p>
<p> </p>
<p> </p>
<p>FREERTOS现在用的还是挺多的,不过MCU还是喜欢裸开发 </p>
qzc飘曳 发表于 2024-11-26 09:21
FREERTOS现在用的还是挺多的,不过MCU还是喜欢裸开发
<p>外设少的话裸机开发更直观,但是外设多的话还是用系统好,</p>
<p>还停留在轮询的代码水平上,所以只能路过帮顶了。</p>
<p>串口和FreeRTOS有冲突?</p>
本帖最后由 hello_mcu 于 2024-11-26 14:31 编辑
<p>试试加上这么一句呢,其他看上去都一样。</p>
<p> </p>
<p> </p>
<div class='shownolgin' data-isdigest='no'>hello_mcu 发表于 2024-11-26 14:30
试试加上这么一句呢,其他看上去都一样。
<p>这句加上试了,还加了别的,最终就是没有freertos的app运行正常,加了freertos的卡在初始化里。关键加了freertos的app程序去掉偏移等单独运行也是正常的。</p>
</div><script>showreplylogin();</script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script> <div class='shownolgin' data-isdigest='no'>wangerxian 发表于 2024-11-26 14:12
串口和FreeRTOS有冲突?
<p>串口只是个通讯方式,跟系统应该没关系。我的BOOT也用的freertos,也是能接收app并跳转的。 难道是堆栈之类的问题?这个会产生这种问题吗?</p>
</div><script>showreplylogin();</script> <div class='shownolgin' data-isdigest='no'>liyancao001 发表于 2024-11-26 14:55
串口只是个通讯方式,跟系统应该没关系。我的BOOT也用的freertos,也是能接收app并跳转的。 难道是堆栈之 ...
<p>boot弄成裸机的试一下,有这种可能。</p>
</div><script>showreplylogin();</script> <div class='shownolgin' data-isdigest='no'>hello_mcu 发表于 2024-11-26 14:30
试试加上这么一句呢,其他看上去都一样。
<p>通了,实测跳转前不能重新开中断。为啥通的也没搞懂,只需要三句话:</p>
<ul>
<li> HAL_Init();</li>
<li> INTX_DISABLE();</li>
<li> __set_CONTROL(0);</li>
</ul>
</div><script>showreplylogin();</script> <div class='shownolgin' data-isdigest='no'>liyancao001 发表于 2024-11-26 20:48
通了,实测跳转前不能重新开中断。为啥通的也没搞懂,只需要三句话:
HAL_Init();
I ...
<p>我也是搜了,看到别人这么解决的,至于为什么,也不懂。希望有大佬看到了,给解答下。</p>
</div><script>showreplylogin();</script> <div class='shownolgin' data-isdigest='no'>hello_mcu 发表于 2024-11-27 08:51
我也是搜了,看到别人这么解决的,至于为什么,也不懂。希望有大佬看到了,给解答下。
<p>试了几天发现还有BUG,电路用了3个SPI扩展的CAN芯片,实际应用中有2路CAN接了设备,结果有一路正常,另一路接收不到数据,但是只要把APP程序的地址偏移等去掉,扩展CAN就正常,改为APP就不行,关键APP里其他的功能都还是正常的。。。</p>
<p>扩展CAN是初始化以后,如果有新的CAN数据到来,则在芯片端口产生边沿跳变,然后STM32采用外部中断监测这个跳变后读取寄存器数据的,实际监测只有开始进了一次中断,后面就进不去了。。。</p>
<p>还不知道这个APP里会不会还有其他BUG。。。</p>
</div><script>showreplylogin();</script>
页:
[1]