CUBEIDE+FATFS+RTthread开发STM32战舰卡死在HardFault_Handler:MRS r0, msp

开发平台:STMCUBEIDE 1.7.0
硬件:正点原子战舰V3
操作系统:rtthread
文件管理系统:FATFS

同一个函数运行不同位置但参数相同的情况下,发生不同的问题,以下是有问题的代码段:

//得到path路径下,目标文件的总个数
//path:路径
//返回值:总有效文件数
unsigned int mp3_get_tnum(TCHAR* path)
{
    printf("%s\r\n",path);
    unsigned char res;
    unsigned int rval=0;
    char *fn;
     DIR tdir;             //临时目录
    FILINFO* tfileinfo;    //临时文件信息
    tfileinfo=(FILINFO*)rt_malloc(sizeof(FILINFO));//申请内存
    #ifdef _USE_LFN
        tfileinfo->lfsize = _MAX_LFN;
        tfileinfo->lfname =(TCHAR *)rt_malloc(tfileinfo->lfsize*sizeof(TCHAR));
        rt_memset(tfileinfo->lfname,0,sizeof(tfileinfo->lfname));
    #endif
    res=f_opendir(&tdir,(const TCHAR*)path); //打开目录
    if(res==FR_OK)
    {

        while(1)//查询总的有效文件数
        {
            res=f_readdir(&tdir,tfileinfo);                   //读取目录下的一个文件
        #ifdef _USE_LFN
            fn = *tfileinfo->lfname?tfileinfo->lfname:tfileinfo->fname;
        #else                              
            fn = tfileinfo->fname;
        #endif
            if(res!=FR_OK||fn[0]==0)
            {
                break;    //错误了/到末尾了,退出
            }
            printf("%s\r\n",fn);    

            res=f_typetell((u8*)tfileinfo->lfname);    
            if((res&0XF0)==0X40)//取高四位,看看是不是音乐文件
            {
                rval++;//有效文件数增加1
            }        
        }  
        printf("音乐文件路径:%s\r\n",path);
        printf("音乐文件数量:%d\r\n",rval);
        HAL_Delay(100);
    } 
    #ifdef _USE_LFN      
        rt_free(tfileinfo->lfname);            
    #endif   
    rt_free(tfileinfo);//释放内存
    f_closedir(&tdir);  
    return rval;
}

当此函数(int mp3_get_tnum)执行于此位置时代码正常运行:

img

运行结果如图:

img

然而同一个函数当它运行在另外一个地方时(mp3_play函数内部),就会报错:

img

mp3_play函数内部:

img

此时调试后,报错地方在这里:

img

报错内容为跳转至context_gcc.s文件中,引发HardFault_Handler

img

卡死在MRS r0, msp语句,查看各个寄存器的值:

img

HAL使用的节拍由TIM7提供。
已经试验过,函数mp3_get_tnum单独在main中任意位置调用均不会发生这种错误,但是当其被mp3_play函数调用时就会引发错误,并且也实验过,被传入mp3_play的参数music_path并没有问题,在进一步传入函数mp3_get_tnum前通过串口打印查看是没有变化的,当想在mp3_get_tnum再次打印时就引发了错误。
麻烦大家帮忙看一下,为什么会这样,会不会是操作系统线程调度导致的问题,或者某些底层bug导致?