RT-Thread-Ulog-文件系统后端

文章目录

一、创建基本工程
二、配置RT-Thread Setting
三、挂载文件系统
四、实现ulog文件后端

前言
本文是文件系统挂载到 SPI FLASH上,实现ulog文件后端
需要提前将SPI FLASH挂载成功
SPI FLASH 采用的是W25Q64

一、请参考RT-Thread Studio官方文档的创建工程流程

二、配置RT-Thread Setting

在这里插入图片描述
①设置日志
在这里插入图片描述
尽量把异步输出线程的栈大小设置大一点,因为有可能会出现栈溢出

②设置文件系统
在这里插入图片描述

  • 文件的最大数目根据自己的需求来决定
  • 处理的最大扇区大小要根据自己使用的是flash还是sd卡来决定,因为我使用的是W25Q64
    最小擦除为一个扇区的大小,扇区为4096

三、挂载文件系统到SPI FLASH,(第一次挂载的话,需要对SPI FLASH进行格式化,否则可能挂载不成功)
先需要抽象SPI FLASH

/* SPI 设备初始化注册,此函数由系统自动调用  */
static int rt_hw_spi_flash_init(void)
{
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /* spi10 表示挂载在 spi1 总线上的 0 号设备,PC0是片选,这一步就可以将从设备挂在到总线中。 */
    rt_hw_spi_device_attach(SPI_BUS_NAME, W25Q64_SPI_DEVICE_NAME, GPIOC, GPIO_PIN_0);

    /* 注册块设备,这一步可以将外部flash抽象为系统的块设备  */
    if (RT_NULL == rt_sfud_flash_probe(W25Q64_BLOCK_DEVICE_NAME, W25Q64_SPI_DEVICE_NAME));
    {
        return -RT_ERROR;
    };

    return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
/**
 *  格式化SPI FLASH
 */
void formatting_device()
{
    /* 格式化块设备 */
    int err_result;
    err_result = dfs_mkfs("elm", W25Q64_BLOCK_DEVICE_NAME);
    if(err_result == 1)
    {
    rt_kprintf("dfs_mkfs is failure\n");
    }
}
/**
 * 挂载文件系统到SPI FLASH
 * @param parameter
 */
void spi_flash_mount(void *parameter)
{
    formatting_device();
    /* 挂载文件系统 */
    rt_thread_mdelay(500);
    if(rt_device_find(W25Q64_SPI_DEVICE_NAME) != RT_NULL)
    {
     if (dfs_mount(W25Q64_BLOCK_DEVICE_NAME, "/", "elm", 0, 0) == RT_EOK)
    {
         rt_kprintf("spi flash mount to success\n");
    }
    else
    {    rt_kprintf("spi flash mount to failed\n");

    }
    }

}
INIT_ENV_EXPORT(spi_flash_mount);

四、创建一个.c文件用来实现ulog文件后端,可以参考RT-Thread官方ulog组件后端的实现方法

/* 创建文件后端 */
static struct ulog_backend ulog_fat_file;
/* 文件后端初始化 */
int ulog_fat_file_backend_init(void)
{
    ulog_fat_file.output = ulog_fat_file_backend_output;
    ulog_backend_register(&ulog_fat_file, ULOG_FILE_BE_NAME, RT_FALSE);
    return 0;
}
INIT_APP_EXPORT(ulog_fat_file_backend_init);
/**
 * 后端输出函数
 * */
static void ulog_fat_file_backend_output(struct ulog_backend *backend, rt_uint32_t level,
            const char *tag, rt_bool_t is_raw, const char *log, size_t len)
{
			1.根据文件系统提供的open函数
				int open(const char *file, int flags, ...);
				该函数可以创建一个文件,用来存放项目输出的日志
			2.根据文件系统提供的write函数
				int write(int fd, const void *buf, size_t len);
				该函数可以向创建好的文件中写入输出的日志
}

注意:我最开始使用文件系统的时候也踩了很多的坑,我给大家列几点,可以稍微给大家提个醒

1.创建文件成功后,open函数会返回一个文件描述符 fd 这个东西非常重要,因为write函数就需要用到这个 fd
  ,一般第一个文件描述符的值是 3 (我也不知道为啥是3),然后如果创建打开了一个文件又继续创建下一个文件的话
  fd 的值就会发生改变,一般在前一个fd的值前 +1 ,但是如果关闭了上一个文件,继续创建下一个文件的时候,下
  一个文件的 fd 就和上一个文件的 fd相同
  
2.不要同时向几个文件写入日志,因为会导致文件里的内容会有缺失

3.如果需要读取文件的偏移量(每个文件的偏移量为 260)
/**
 * 读取logs目录下文件的偏移量
 */
long read_pos()
{
    struct dirent *d;
    DIR *auto_em;
    /* 获取文件偏移量 */
    long Position_offset;

    /* 首先读取logs目录 */
    auto_em = opendir("/logs");
    if(auto_em == RT_NULL)
    {
    rt_kprintf("open directory error!\n");
    }
    else
    {
    while ((d = readdir(auto_em)) != RT_NULL);
    /* 每个文件的偏移量为 260 */
    Position_offset = telldir(auto_em);
    rt_kprintf("Position_offset = %ld\n",Position_offset);
    }
    return Position_offset;
}
MSH_CMD_EXPORT(read_pos,XXXX);

4.可以参考一下RT-Thread组件里大神上传的ulog文件系统后端的实现

谢谢!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值