3. 打开和关闭媒体
任务目标
本案例演示ThreadX FileX文件系统中媒体(Media)的打开与关闭操作。通过调用fx_media_open和fx_media_close,完成对RAM磁盘的初始化与释放,并处理打开失败时的错误分支,最后通过媒体状态字段验证操作结果。
实现原理
fx_media_open将文件系统驱动程序与媒体控制块绑定,读取引导扇区并初始化FAT表;fx_media_close则刷新缓存并释放媒体占用的资源。打开失败时返回非FX_SUCCESS状态码,此时不应继续执行文件操作。媒体控制块的fx_media_open_count字段在打开成功后递增,关闭后递减,可用于状态检查。
关键完整代码
#include "tx_api.h"
#include "fx_api.h"
/* 定义媒体控制块和RAM驱动缓冲区 */
FX_MEDIA ram_disk;
UCHAR ram_disk_memory[512 * 64]; /* 64个扇区,每扇区512字节 */
UCHAR ram_disk_sector_cache[512]; /* 单扇区缓存 */
/* RAM磁盘驱动程序(最小实现,仅支持读写扇区) */
VOID _fx_ram_driver(FX_MEDIA *media_ptr)
{
UCHAR *source_ptr, *destination_ptr;
ULONG destination_sector;
/* 处理读写请求 */
if (media_ptr->fx_media_driver_request == FX_DRIVER_READ)
{
source_ptr = ram_disk_memory + (media_ptr->fx_media_driver_logical_sector * 512);
destination_ptr = media_ptr->fx_media_driver_buffer;
destination_sector = media_ptr->fx_media_driver_logical_sector;
/* 复制扇区数据到缓存 */
destination_ptr = media_ptr->fx_media_driver_buffer;
for (int i = 0; i < 512; i++)
{
*destination_ptr++ = *source_ptr++;
}
media_ptr->fx_media_driver_status = FX_SUCCESS;
}
else if (media_ptr->fx_media_driver_request == FX_DRIVER_WRITE)
{
source_ptr = media_ptr->fx_media_driver_buffer;
destination_ptr = ram_disk_memory + (media_ptr->fx_media_driver_logical_sector * 512);
for (int i = 0; i < 512; i++)
{
*destination_ptr++ = *source_ptr++;
}
media_ptr->fx_media_driver_status = FX_SUCCESS;
}
else if (media_ptr->fx_media_driver_request == FX_DRIVER_INIT)
{
/* 初始化时清零媒体内存 */
memset(ram_disk_memory, 0, sizeof(ram_disk_memory));
media_ptr->fx_media_driver_status = FX_SUCCESS;
}
else if (media_ptr->fx_media_driver_request == FX_DRIVER_UNINIT)
{
media_ptr->fx_media_driver_status = FX_SUCCESS;
}
else if (media_ptr->fx_media_driver_request == FX_DRIVER_ABORT)
{
media_ptr->fx_media_driver_status = FX_SUCCESS;
}
else
{
media_ptr->fx_media_driver_status = FX_UNSUPPORTED;
}
}
/* 应用入口函数 */
VOID media_open_close_demo(ULONG arg)
{
UINT status;
/* 第一次打开:应成功 */
status = fx_media_open(&ram_disk, "RAM_DISK", _fx_ram_driver,
FX_TRUE, ram_disk_sector_cache, sizeof(ram_disk_sector_cache));
if (status != FX_SUCCESS)
{
/* 打开失败处理 */
printf("媒体打开失败,错误码:0x%x\n", status);
return;
}
/* 检查打开计数 */
printf("媒体打开成功,打开计数:%lu\n", ram_disk.fx_media_open_count);
/* 关闭媒体 */
status = fx_media_close(&ram_disk);
if (status != FX_SUCCESS)
{
printf("媒体关闭失败,错误码:0x%x\n", status);
return;
}
/* 验证关闭后状态 */
printf("媒体关闭成功,打开计数:%lu\n", ram_disk.fx_media_open_count);
/* 第二次打开:模拟失败场景(使用无效的媒体指针) */
status = fx_media_open(FX_NULL, "BAD_DISK", _fx_ram_driver,
FX_TRUE, ram_disk_sector_cache, sizeof(ram_disk_sector_cache));
if (status != FX_SUCCESS)
{
printf("预期失败已捕获,错误码:0x%x\n", status);
}
}
/* ThreadX入口 */
VOID tx_application_define(VOID *first_unused_memory)
{
/* 创建演示线程 */
tx_thread_create(&demo_thread, "Demo", media_open_close_demo, 0,
stack_ptr, 2048, 1, 1, TX_NO_TIME_SLICE);
}
编译与运行
- 将以上代码与ThreadX库、FileX库一同编译链接;
- 确保
fx_api.h和tx_api.h头文件路径已包含; - 在嵌入式平台或模拟器中运行,观察串口输出。
验证方法
- 成功路径:第一次
fx_media_open返回FX_SUCCESS,且打印的打开计数为1; - 关闭验证:
fx_media_close返回FX_SUCCESS,关闭后打开计数恢复为0; - 失败路径:传入
FX_NULL媒体指针时,fx_media_open返回非成功状态码(预期为FX_PTR_ERROR),程序捕获并打印错误码。
若串口依次输出“媒体打开成功,打开计数:1”、“媒体关闭成功,打开计数:0”和“预期失败已捕获”,则说明媒体打开/关闭及错误处理逻辑均正确。