liyancao001 发表于 2024-11-25 21:15

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>&nbsp;</p>

<p>我在MX_FREERTOS_Init();里面加了串口打印,函数下面也加了,发现里面需要打印的数据都是输出正常的,但是到函数下面就不行了。</p>

<p>&nbsp; MX_FREERTOS_Init();//<span style="color:#e74c3c;">这个函数体里面的最后加了一句串口打印,打印是正常的</span>。。<br />
&nbsp; printf(&quot;ADECU_APP_2,0x%X\r\n&quot;,SCB-&gt;VTOR);//<span style="color:#e74c3c;">这句一直打印不出来。</span><br />
&nbsp; /* Start scheduler */<br />
&nbsp; osKernelStart();</p>

<p>&nbsp;</p>

<p>其中BOOT跳转前把中断也都关了</p>

<p>APP相比没做IAP之前,就增加了2项:(没做IAP之前程序运行正常)</p>

<p>1)MAIN开头的中断向量偏移</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;int main(void)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;/* USER CODE BEGIN 1 */<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SCB-&gt;VTOR = FLASH_BASE | 0x80000;//设置偏移量</p>

<p>&nbsp;</p>

<p>2)option for target里把IROM1的起始地址改为了0x8080000,start改为了0x40000</p>

<p>&nbsp;</p>

<p>而BOOT跳转函数如下:</p>

<p>void iap_load_app(uint32_t appxaddr)// 调用时参数为0x08080000<br />
{<br />
&nbsp; &nbsp; if(((*(vu32*)appxaddr)&amp;0x2FF00000)==0x20000000) {&nbsp;&nbsp; &nbsp;//检查栈顶地址是否合法.<br />
&nbsp; &nbsp; &nbsp; &nbsp; HAL_RCC_DeInit();<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;INTX_DISABLE();<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;SysTick-&gt;CTRL = 0X00;//卡死后新增的,但是没有用,跟上面应该是功能重复的<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;SysTick-&gt;LOAD = 0;//卡死后新增的,但是没有用,跟上面应该是功能重复的<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;SysTick-&gt;VAL = 0;//卡死后新增的,但是没有用,跟上面应该是功能重复的<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;__disable_irq();//卡死后新增的,但是没有用,跟上面应该是功能重复的<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; jump2app=(iapfun)*(vu32*)(appxaddr+4);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//用户代码区第二个字为程序开始地址(复位地址)<br />
&nbsp; &nbsp; &nbsp; &nbsp; MSR_MSP(*(vu32*)appxaddr);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)<br />
&nbsp; &nbsp; &nbsp; &nbsp; jump2app();&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//跳转到APP.<br />
&nbsp; &nbsp; }<br />
}</p>

<p>&nbsp;</p>

<p>&nbsp;</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程序:&nbsp;&nbsp;</p>

<pre>
<code>      HAL_Init();
        INTX_DISABLE();
        /* 关闭所有中断,清除所有中断挂起标志 */  
        for (i = 0; i &lt; 8; i++)
        {
            NVIC-&gt;ICER=0xFFFFFFFF;
            NVIC-&gt;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>&nbsp; &nbsp; 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>&nbsp;</p>

<p>&nbsp; &nbsp;</p>

qzc飘曳 发表于 2024-11-26 09:21

<p>FREERTOS现在用的还是挺多的,不过MCU还是喜欢裸开发&nbsp;&nbsp;</p>

liyancao001 发表于 2024-11-26 10:30

qzc飘曳 发表于 2024-11-26 09:21
FREERTOS现在用的还是挺多的,不过MCU还是喜欢裸开发&nbsp;&nbsp;

<p>外设少的话裸机开发更直观,但是外设多的话还是用系统好,</p>

hjh0512 发表于 2024-11-26 12:02

<p>还停留在轮询的代码水平上,所以只能路过帮顶了。</p>

wangerxian 发表于 2024-11-26 14:12

<p>串口和FreeRTOS有冲突?</p>

hello_mcu 发表于 2024-11-26 14:30

本帖最后由 hello_mcu 于 2024-11-26 14:31 编辑

<p>试试加上这么一句呢,其他看上去都一样。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

liyancao001 发表于 2024-11-26 14:47

<div class='shownolgin' data-isdigest='no'>hello_mcu 发表于 2024-11-26 14:30
试试加上这么一句呢,其他看上去都一样。

&nbsp;

&nbsp;

<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>

liyancao001 发表于 2024-11-26 14:55

<div class='shownolgin' data-isdigest='no'>wangerxian 发表于 2024-11-26 14:12
串口和FreeRTOS有冲突?

<p>串口只是个通讯方式,跟系统应该没关系。我的BOOT也用的freertos,也是能接收app并跳转的。 难道是堆栈之类的问题?这个会产生这种问题吗?</p>
</div><script>showreplylogin();</script>

wangerxian 发表于 2024-11-26 18:21

<div class='shownolgin' data-isdigest='no'>liyancao001 发表于 2024-11-26 14:55
串口只是个通讯方式,跟系统应该没关系。我的BOOT也用的freertos,也是能接收app并跳转的。 难道是堆栈之 ...

<p>boot弄成裸机的试一下,有这种可能。</p>
</div><script>showreplylogin();</script>

liyancao001 发表于 2024-11-26 20:48

<div class='shownolgin' data-isdigest='no'>hello_mcu 发表于 2024-11-26 14:30
试试加上这么一句呢,其他看上去都一样。

&nbsp;

&nbsp;

<p>通了,实测跳转前不能重新开中断。为啥通的也没搞懂,只需要三句话:</p>

<ul>
        <li>&nbsp;HAL_Init();</li>
        <li>&nbsp;INTX_DISABLE();</li>
        <li>&nbsp;__set_CONTROL(0);</li>
</ul>
</div><script>showreplylogin();</script>

hello_mcu 发表于 2024-11-27 08:51

<div class='shownolgin' data-isdigest='no'>liyancao001 发表于 2024-11-26 20:48
通了,实测跳转前不能重新开中断。为啥通的也没搞懂,只需要三句话:


        &nbsp;HAL_Init();
        &nbsp;I ...

<p>我也是搜了,看到别人这么解决的,至于为什么,也不懂。希望有大佬看到了,给解答下。</p>
</div><script>showreplylogin();</script>

liyancao001 发表于 2024-12-4 17:49

<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]
查看完整版本: STM32 BOOT跳转到APP后初始化完后成死机 用了FREERTOS