stm32源码记录分析之sdio驱动问题(filex组件)

前言

  1. 此次记录是使用threadx+filex测试sd重复挂载时,第二次就会卡死在HAL的函数中
  2. 使用的是stm32f407zgt6

问题现象

测试代码(主要)

串口线程

c 复制代码
/*
 * Copyright (c) 2024-2024,shchl
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-4-4     shchl   first version
 */
#include "includes.h"

#if 1
#define APP_TASK_SERIAL_MONI_STK_SIZE 2048
#define APP_TASK_SERIAL_MONI_PRIO 10
/*
*******************************************************************************************************
*                               外部引入变量
*******************************************************************************************************
*/
extern app_msg filex_msg;
extern TX_QUEUE AppFilexQueue;
/*
*******************************************************************************************************
*                               变量
*******************************************************************************************************
*/

/*
*********************************************************************************************************
*                                       静态全局变量
*********************************************************************************************************
*/
static TX_THREAD serial_moni_thread;
static uint64_t serial_moni_task_stk[APP_TASK_SERIAL_MONI_STK_SIZE / 8];

/*
*********************************************************************************************************
*                                      函数声明
*********************************************************************************************************
*/
static void serial_moni_entry(ULONG input);
/*
*********************************************************************************************************
*                                      外部函数
*********************************************************************************************************
*/
/**
 * @brief cpu 状态任务
 */
void tx_task_serial_monitor_create() {


    tx_thread_create(&serial_moni_thread,              /* 任务控制块地址 */
                     "serial_moni",               /* 任务名 */
                     serial_moni_entry,                  /* 启动任务函数地址 */
                     0,                             /* 传递给任务的参数 */
                     &serial_moni_task_stk[0],            /* 堆栈基地址 */
                     APP_TASK_SERIAL_MONI_STK_SIZE,    /* 堆栈空间大小 */
                     APP_TASK_SERIAL_MONI_PRIO,        /* 任务优先级*/
                     APP_TASK_SERIAL_MONI_PRIO,        /* 任务抢占阀值 */
                     TX_NO_TIME_SLICE,               /* 不开启时间片 */
                     TX_AUTO_START);                 /* 创建后立即启动 */




}

/*
*********************************************************************************************************
*                                      内部函数
*********************************************************************************************************
*/
static inline void serial_filex_handle(const char *cmd);
static void serial_moni_entry(ULONG input) {
    static uint8_t buf[256];
    filex_msg.msg_id = 0;
    filex_msg.code = 0;
    while (1) {
        uint8_t *ptr = buf;
        while (comGetChar(COM1, ptr)) {
            ptr++;
            if (ptr > buf + 256) {

                break;
            }
        }
        if (ptr != buf) {
            *ptr = '\0';
            if (strstr((const char *) buf, "printf")) {
                app_task_info_out();
            } else {
                serial_filex_handle((const char *) buf);





                
                

                
            }

        }
        tx_thread_sleep(10);

    }

}


static inline void serial_filex_handle(const char *cmd) {
    static UINT msgAddr = (UINT) &filex_msg;
#define FILEX_CMD_PRE "filex_"
#define FILEX_CMD_PRE_LEN strlen(FILEX_CMD_PRE)
    if (strstr(cmd, FILEX_CMD_PRE) && strlen(cmd) > FILEX_CMD_PRE_LEN) {
        char ch = *(cmd + FILEX_CMD_PRE_LEN);
        if ('0' <= ch && ch < '9') {

            filex_msg.code = ch -'0';
            if (tx_queue_send(&AppFilexQueue, &msgAddr, 1000) == TX_SUCCESS) {
                tx_log("send ok,code is [%d]\r\n", filex_msg.code);
            }
            filex_msg.msg_id++;
        }

    }
}


#endif

处理filex文件线程

c 复制代码
/*
 * Copyright (c) 2024-2024,shchl
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-4-5     shchl   first version
 */
#include "includes.h"

#define FILEX_DEMO_STK_SIZE 4096
extern TX_QUEUE AppFilexQueue;


TX_THREAD filex_demo_thread;
static uint64_t filex_demo_stack[FILEX_DEMO_STK_SIZE / 8];

static VOID filex_demo_entry(ULONG input);

void app_task_filex_demo_create() {
    _txe_thread_create(
            &filex_demo_thread,
            "filex_demo_thread",
            filex_demo_entry,
            0,
            filex_demo_stack,
            FILEX_DEMO_STK_SIZE,
            15,
            15,
            TX_NO_TIME_SLICE,
            TX_AUTO_START,
            sizeof(TX_THREAD)
    );


}


extern void app_filex_sys_mount();
extern void app_filex_create_file_test();
static VOID filex_demo_entry(ULONG input) {

    app_msg *msg;
    UINT stat;
    UINT add;
    while (1) {

        stat = tx_queue_receive(&AppFilexQueue, &add, TX_WAIT_FOREVER);

        msg = (app_msg *)add;
        if(stat==TX_SUCCESS){
            switch (msg->code) {
                case 1: {
                    tx_log("app_filex_sys_mount func test\r\n");
                    app_filex_sys_mount();
                    break;
                }
                case 2:
                    tx_log("app_filex_create_file_test func test\r\n");
                    app_filex_create_file_test();
                    break;
                default:
                    tx_log("not implement\r\n");
                    break;


            }





        }


    }
}

filex 组件测试

c 复制代码
/*
 * Copyright (c) 2024-2024,shchl
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-4-5     shchl           文件系统挂载
 */
#include "includes.h"
#include "fx_stm32_sd_driver.h"

#define SD_MEDIA_MEM_SIZE 1024
static FX_MEDIA sd_media_disk;
static UCHAR sd_media_memmory[SD_MEDIA_MEM_SIZE];

/* FileX相关变量 */
static FX_FILE fx_file;
static CHAR entry_name[FX_MAX_LONG_NAME_LEN] = {0};
static volatile uint8_t mount_flag = 0;

static void app_dir_info_out(FX_MEDIA *media);


static inline UINT app_sd_mount() {
    UINT stat;
    if (!mount_flag) {
        stat = fx_media_open(&sd_media_disk, "STM32_SDIO_DISK", fx_stm32_sd_driver, 0, sd_media_memmory,
                             SD_MEDIA_MEM_SIZE);
    } else {
        return FX_SUCCESS;
    }
    if (stat == FX_SUCCESS) {
        mount_flag = 1;
    }

    return stat;


}

static inline UINT app_sd_unmount() {
    mount_flag = 0;
    return fx_media_close(&sd_media_disk);
}


void app_filex_sys_mount() {
    UINT status;
    UINT cnt;
    ULONG64 available_bytes;
    /* 挂载sd 媒体驱动*/
    status = app_sd_mount();
    if (status != FX_SUCCESS) {
        tx_log("fx_media_open is err[%]\r\n", status);
        return;
    }
    app_dir_info_out(&sd_media_disk);


    /* SD卡剩余容量大小 */
    status = fx_media_extended_space_available(&sd_media_disk, &available_bytes);
    if (status == FX_SUCCESS) {
        tx_log("SD卡剩余容量大小 -- %lldMB\r\n", available_bytes / 1024 / 1024);
    }
    /* 卸载SD卡 */
    status = app_sd_unmount();

    if (status != FX_SUCCESS) {
        printf("卸载文件系统卸载失败 -- %d\r\n", status);
    }
}

void app_filex_create_file_test() {

    UINT status;

    /* 挂载SD卡 */
    status = app_sd_mount();
    if (status != FX_SUCCESS) {
        tx_log("挂载文件系统失败 -- %d\r\n", status);
        return;
    }

    /* 创建文件 */
    status = fx_file_create(&sd_media_disk, "armfly.txt");

    /* 检测状态 */
    if (status != FX_SUCCESS) {
        /* 失败的话,可以考虑二次创建 */
        if (status != FX_ALREADY_CREATED) {
            printf("创建文件失败\r\n");
        }
    }


    /* 打开文件  */
    status = fx_file_open(&sd_media_disk, &fx_file, "armfly.txt", FX_OPEN_FOR_WRITE);


    if (status != FX_SUCCESS) {
        tx_log("打开文件失败\r\n");
    }

    /* 设置到起始位置读取  */
    status = fx_file_seek(&fx_file, 0);

    if (status != FX_SUCCESS) {
        tx_log("设置读取位置失败\r\n");
    }
#define WR_CONTENT_STR "hello filex, this is content"
#define WR_CONTENT_STR_LEN strlen(WR_CONTENT_STR)

    /* 写入字符串到文件  */
    status = fx_file_write(&fx_file, WR_CONTENT_STR, WR_CONTENT_STR_LEN);
#undef WR_CONTENT_STR
#undef WR_CONTENT_STR_LEN
    if (status == FX_SUCCESS) {
        tx_log("armfly.txt 文件写入成功\r\n");
    } else {
        tx_log("armfly.txt 文件写入失败 %d\r\n", status);
    }

    /* 关闭文件  */
    status = fx_file_close(&fx_file);

    /* Check the file close status.  */
    if (status != FX_SUCCESS) {
        tx_log("关闭文件失败\r\n");
    }

    /* 保证文件写入全部生效 */
    status = fx_media_flush(&sd_media_disk);

    if (status != FX_SUCCESS) {
        tx_log("flush失败\r\n");
    }

    /* 卸载SD卡 */
    status = app_sd_unmount();

    if (status != FX_SUCCESS) {
        tx_log("卸载文件系统卸载失败 -- %d\r\n", status);
    }
}


static void app_dir_info_out(FX_MEDIA *media) {
    UINT status;
    UINT attributes;
    ULONG size;
    UINT year;
    UINT month;
    UINT day;
    UINT hour;
    UINT minute;
    UINT second;
    tx_log("属性        |  文件大小 | 短文件名 | 长文件名\r\n");
    for (int cnt = 0;; cnt++) {
        /* 读取目录项,索引会自动下移 */
        status = fx_directory_next_full_entry_find(media,
                                                   entry_name,
                                                   &attributes,
                                                   &size,
                                                   &year, &month, &day,
                                                   &hour, &minute, &second);
        if (status != FX_SUCCESS || entry_name[0] == 0) {
            break;
        }
        if (entry_name[0] == '.') {
            continue;
        }
        /* 判断是文件还是子目录 */
        if (attributes & FX_DIRECTORY) {
            tx_log("目录  ");
        } else {
            tx_log("文件  ");
        }
        /* 打印文件大小, 最大4G */
        tx_log(" %10d", (int) size);
        tx_log("  %s\r\n", (char *) entry_name);    /* 长文件名 */
    }

}

通讯逻辑

解决方案

修改HAL库之SD初始化代码


测试结果

测试ok。

相关推荐
hollq21 分钟前
STM32F103RCT6+STM32CubeMX+keil5(MDK-ARM)+Flymcu实现串口重定向
arm开发·stm32·嵌入式硬件
小鱼儿电子2 小时前
17-基于STM32的宠物饲养系统设计与实现
stm32·嵌入式硬件·物联网·宠物·宠物饲养系统
小莞尔3 小时前
【51单片机】【protues仿真】基于51单片机四层电梯系统
单片机·嵌入式硬件
CFZPL3 小时前
使用江科大串口发送函数发送freertos的vTaskList出现跑飞
单片机
F133168929574 小时前
WD5030A,24V降5V,15A 大电流,应用于手机、平板、笔记本充电器
stm32·单片机·嵌入式硬件·51单片机·硬件工程·pcb工艺
易享电子5 小时前
基于单片机电器断路器保护器系统Proteus仿真(含全部资料)
单片机·嵌入式硬件·fpga开发·51单片机·proteus
爱倒腾的老唐8 小时前
01、如何学习单片机
单片机·嵌入式硬件·学习
点灯小铭8 小时前
基于单片机的夹具压力控制系统设计
单片机·嵌入式硬件·mongodb·毕业设计·课程设计
雾削木14 小时前
stm32解锁芯片
javascript·stm32·单片机·嵌入式硬件·gitee
热爱编程的小刘15 小时前
STM32学习路线开启篇:外部中断
stm32