This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

在调试C6748时,第二次调用FATFS的f_opendir()函数会导致DSP复位,怎么解决?



如题。

参考pdk_omapl138的例程写了一个函数,用于读取当前目录的文件列表信息:

/*========================================================================================================
函数名称: file_browser_update_file_info
功    能: 获取当前路径的文件夹或文件名称,存储到browser_filinfo中
输    入: path,访问路径;folder_level,文件夹层序号(0-9);folder_n,文件夹数量存储指针;file_n,文件数量存储指针
返    回: 无
========================================================================================================*/
static void file_browser_update_file_info(const char *path, uint8_t folder_level, uint16_t *folder_n, uint16_t *file_n)
{
    uint32_t totalSize = 0U;
    uint32_t fileCount = 0U;
    uint32_t dirCount = 0U;
    FRESULT fresult;
    DIR dir={0};
    FILINFO fno;

    if(dir_update_flag) {
        dir_update_flag = 0;
    } else {
        return;
    }

    /* Open the current directory for access. */
    fresult = f_opendir(&dir, path);

    /* Enter loop to enumerate through all directory entries. */
    while(FR_OK == fresult)
    {
        /* Read an entry from the directory. */
        fresult = f_readdir(&dir, &fno);

        /* Check for error and return if there is a problem. */
        if(FR_OK == fresult)
        {
            /* If the file name is blank, then this is the end of the listing. */
            if('\0' == fno.fname[0])
            {
                break;
            }

            /* If the attribute is directory, then increment the directory count. */
            if(AM_DIR == (fno.fattrib & AM_DIR))
            {
                if (strlen(fno.altname)) { // 如果短文件名有效,使用短文件名,否则使用长文件名
                    //memcpy((void*)browser_filinfo[folder_level]->lfoldername[dir_cnt], (void*)fno.altname, 13);
                    memcpy((void*)browser_filinfo[folder_level]->foldername[dirCount], (void*)fno.altname, 13);
                } else
                {
                    //memcpy((void*)browser_filinfo[folder_level]->lfoldername[dir_cnt], (void*)fno.fname, 13);
                    memcpy((void*)browser_filinfo[folder_level]->foldername[dirCount], (void*)fno.fname, 13);
                }
                dirCount++;
            }

            /*
             * Otherwise, it is a file.  Increment the file count, and add in the
             * file size to the total.
             */
            else
            {
                //if (extend_name_check(fno.fname, FILE_EXT_NAME))
                {
                    if (fno.fsize   // 文件大小不为0,才认为是有效文件
                     && (fileCount < MAX_FILE_NUM)) {   // 避免文件夹超过MAX_FILE_NUM(1000)个
                        if (strlen(fno.altname)) { // 如果短文件名有效,使用短文件名,否则使用长文件名
                            //memcpy((void*)browser_filinfo[folder_level]->lfname[f_cnt], (void*)fno.altname, 13);
                            memcpy((void*)browser_filinfo[folder_level]->fname[fileCount], (void*)fno.altname, 13);
                        } else
                        {
                            //memcpy((void*)browser_filinfo[folder_level]->lfname[f_cnt], (void*)fno.fname, 13);
                            memcpy((void*)browser_filinfo[folder_level]->fname[fileCount], (void*)fno.fname, 13);
                        }
                        fileCount++;
                    }
                }
            }

            /*
             * Print the entry information on a single line with formatting to show
             * the attributes, date, time, size, and name.
             */
            UARTprintf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9u  %s\n",
                               (fno.fattrib & AM_DIR) ? 'D' : '-',
                               (fno.fattrib & AM_RDO) ? 'R' : '-',
                               (fno.fattrib & AM_HID) ? 'H' : '-',
                               (fno.fattrib & AM_SYS) ? 'S' : '-',
                               (fno.fattrib & AM_ARC) ? 'A' : '-',
                               (fno.fdate >> 9) + 1980,
                               (fno.fdate >> 5) & 15,
                               fno.fdate & 31,
                               (fno.ftime >> 11),
                               (fno.ftime >> 5) & 63,
                               fno.fsize,
                               fno.fname);
        }
    }
    fresult = f_closedir(&dir);
    *folder_n = dirCount;
    *file_n = fileCount;
    total_num[folder_level] = fileCount + dirCount;
}

第一次调用时,path[] = "/";即读取的是根目录。可以正常获取根目录下的文件夹和文件的信息。

第二次调用前,修改为path[] = "/F1";即要读取的是根目录下的F1文件夹。运行到fresult = f_opendir(&dir, path);时,导致DSP复位!

如果第一次调用时,path[] = "/F1";是可以正常打开F1文件夹并获取文件列表信息的。

请问是什么原因导致的?该怎么解决?

原来使用的是pdk的fatfs驱动库。我以为是驱动库的问题,就把驱动库换成了FATFS源码驱动,结果问题还是没有得到解决。

  • 请问用的是哪个版本的Processor SDK?
  • pdk_omapl138_1_0_6
  • 你好,怎么就问个版本,就没下文了呢?
    现在又遇到类似的问题,还是因为调用fatfs的函数后导致DSP复位。
    是否是因为堆栈溢出造成的呢?是系统堆栈溢出还是任务堆栈溢出?如何验证?
    在SYS/BIOS中,在哪里设置系统堆栈?
  • 是自己的板子还是TI的开发板?

    可以用ROV (Runtime Object View)来查看堆栈使用情况。
    processors.wiki.ti.com/.../Runtime_Object_View_(ROV)
  • void record(const char *fname)
    {
        FRESULT res;
        unsigned int write_buf_cnt;
        unsigned int bytes_writed;
        RING_BUFFER  *p_queue = NULL;
    
        res = rec_wav_file_create(fname, &rec_file, REC_SAMPLING_RATE, REC_WORD_SIZE);
        if(FR_OK != res) {
            DEBUG_log("rec_wav_file_create ERROR.\r\n");
            return;
        }
        ring_buf_queue_init();
        record_clear_sem();
        DEBUG_log("Recording...\r\n");
        write_buf_cnt = 0;
        Task_setPri(h_sorting_task, 1);
        recording_flag = 1;
        while(write_buf_cnt < 102) {
            Semaphore_pend(sem_ch_lm_cnt, BIOS_WAIT_FOREVER);
            while (!Queue_empty(rec_buf_queue1)) {
                p_queue = Queue_get(rec_buf_queue1);
                res = f_write(&rec_file, p_queue->pdata, 512, &bytes_writed);// 运行该行代码,会导致DSP复位!
                if(FR_OK != res) {
                    DEBUG_log("rec_wav_file_write ERROR.\r\n");
                    break;
                }
                Queue_put(rec_free_queue1, &p_queue->elem);
                write_buf_cnt++;
            }
        }
        recording_flag = 0;
        Task_setPri(h_sorting_task, -1);
        rec_wav_file_close(&rec_file);
    }

    运行上面的f_write()函数会导致DSP复位,这是上面原因?

    单步调试,运行到f_write()行时任务栈如下图:

  • 该问题已解决。
    原因是,定义了几个较大数组,共约32M字节。使用的硬件平台配置和官方LCDC6748相同,DDR2容量128M字节。
    编译并没有错,运行时出错。
    解决方法:减小数组大小。