用J-LINK的RTT输入输出文本会死循环或者HardFault

2019-12-19 18:11发布

本帖最后由 gamethink 于 2018-4-20 18:14 编辑

J-LINK V8的,驱动是5.03不敢用太高,RTT的头文件也是5.03配套的,出现这些怪问题,调试几天不解
首先,RTT的所有代码没有修改过,SEGGER_RTT_Conf.h也没有修改,使用默认值,MDK为最新的5.25
第一种情况,单纯输出字符也死循环。

int main(void)
{
        SEGGER_RTT_Init();
       
        SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
       
        SEGGER_RTT_WriteString(0, "SEGGER Real-Time-Terminal Sample ");
        SEGGER_RTT_printf(0, "Len = %d ", 10);                                                                                                 \极其怪异!如果%d修改为%.1d则不会进入RTT的函数死循环,很怪异!
            while(1);
}

RTT输出窗口可以输出SEGGER Real-Time-Terminal Sample,然后第二行Len = 10没有输出,然后是死循环在RTT的处理函数,里面函数还没看明白,但是一直在循环。
但如果改成%.1d则正常输出,是这样子:
SEGGER Real-Time-Terminal Sample

Len = 10




第二种情况,输入一串数字,返回数字的长度,还有显示,比如输入123,输出Len = 4, Data = 123,因为RTT输入界面包含换行符,所以长度是4。
void TestTimer(void)                                                                                                        \这个函数会1秒钟执行一次,是M3的SYSTICK中断里调用的
{
        uint8_t rttData[32] = {0};
        static uint8_t len;
       
        if(SEGGER_RTT_HasKey() == 1)
        {
                len = SEGGER_RTT_Read(0, &rttData[0], sizeof(rttData));
                rttData[len] = '';
               
                SEGGER_RTT_printf(0, "Len = %.1d, Data = %s ",len, rttData);                        \用%1.d也是第一种情况的原因,如果用%d,当输入达到10以上就会进入RTT自己的函数死循环跳不出
        }                                                                                                                                       
}

int main(void)
{
        volatile int _Cnt;

        SEGGER_RTT_Init();
        SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);

        SEGGER_RTT_WriteString(0, "SEGGER Real-Time-Terminal Sample ");

        TimerInit(1000000);
        TimerAddISR(TestTimer);

            while(1)
        {
                Routine();
        }
}

刚开始如果输入123abc,MCU收到后回发给电脑,电脑显示Len = 7, Data = 123abc,好像很正常,但是如果不停往RTT输入字符,比如123,123,123....很快不用10次,就会死机,进入hardfault的状态
微信图片_20180420180842.png (39.68 KB, 下载次数: 0) 下载附件 2018-4-20 18:09 上传
可以看到图的死机位置,和RTT终端窗口实际我只发了很少数据,而且不是连续发的,是几秒钟发一个123也会hardfault
已经调了几天了,好郁闷,有哪位朋友懂这个东西?


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
小小菜
1楼-- · 2019-12-19 19:04
建议换个高版本的驱动,现在用的6.31,感觉性能很不错,之前用的6.14,偶尔会进入HardFault,原因未明。
gamethink
2楼-- · 2019-12-19 23:24
 精彩回答 2  元偷偷看……
gamethink
3楼-- · 2019-12-20 05:19

微信图片_20180420180842.png (30.9 KB, 下载次数: 0)

下载附件

2018-4-21 08:59 上传


晚上想了一下,怀疑是不是CPU内核问题,于是又选了另外一款M3内核的CPU测试,这次选择的是STM32F103RC

第一种情况以及第二种情况,通通中招,估计真的不是CPU的问题了。

不过我留意到J-LINK的RTT窗口有点奇怪
右上方的RTT address 是空白的,不是系统自动填的?我看到论坛有高手讨论RTT的截图是有地址数据的。
另外我每发一次数据,红圈的total和buffer都会递增,而且两个数量是一样的,感觉非常不合理,我明明已经读取了怎么这个数字会越来越大????
gamethink
4楼-- · 2019-12-20 10:09
这次干脆用官方例程原封不动测试

int main(void)
{
        volatile int _Cnt;
        volatile int _Delay;

        static char r;
        SEGGER_RTT_WriteString(0, "SEGGER Real-Time-Terminal Sample ");
        SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
        do
        {
                r = SEGGER_RTT_WaitKey();
                SEGGER_RTT_Write(0, &r, 1);
                r++;
        }
        while(1);
}

功能是这样的:在RTT的显示终端你发什么,CPU返回什么,然后大概发了几十个字节后,进入HalfFault.........
justdomyself
5楼-- · 2019-12-20 15:42
这玩意是环形队列加共享内存实现的,照理说不会出现这种问题,因为你所谓的打印实际就是在写队列,你看下是不是rtt 的队列开太小了
gamethink
6楼-- · 2019-12-20 20:01
justdomyself 发表于 2018-4-22 06:17
这玩意是环形队列加共享内存实现的,照理说不会出现这种问题,因为你所谓的打印实际就是在写队列,你看下是 ...

我也是这样理解的,按道理不会出错,即便是缓冲爆了也不应该hardfault才对。而且我是一两秒输入一次数据而已不可能性能那么差吧?

第二种情况假如是缓冲区问题,第一种情况也奇怪了吧,输出10卡死。。

一周热门 更多>