RT-Thread Studio移植EasyFlash和ulog_easyflash注意事项

08/17 17:23
阅读数 716

Github官方源码及文档看这里:
https://github.com/armink/EasyFlash
https://github.com/armink-rtt-pkgs/ulog_easyflash

移植过程参考官方文档即可,这里简单说一下我自己在移植过程中踩过的坑以及一些注意事项:

  1. 尽量在RT-Thread里面使用一种日志,ulog和easylogger尽可能选择其中一个即可,否则会造成一些不必要的麻烦。我原先在开启ulog的基础上配置easylogger的时候,INFO初始化时遇到了问题,后来发现ulog的配置和EasyLogger的有一部分串了,修改起来也比较麻烦。ulog_easyflash其实就是ulog的一种后端,已经能够完美对接easyflash了,因此如果使用ulog就能完成,尽可能还是选择官方推荐的ulog吧。

  2. EasyFlash目前支持的硬件平台仅3种(截止我写博客时间2020/8/15):stm32f10x和stm32f40x的片内Flash,还有基于SPI(QSPI)的片外FLASH,因此如果不是f1或f4的芯片还是用片外FLASH比较好。其中片外Flash的移植方式又分为两种:基于fal库和基于SFUD库的,因此在如果是使用片外Flash的话记得先配置以上这两种库。官方手册给出的配置方式如下,本次博主使用的是F7系列芯片,因此采用QSPI和SFUD为基础的配置(详见我的上一篇博客:RT-Thread Studio配置QSPI和SFUD)。
    在这里插入图片描述
    在这里插入图片描述

  3. 在RT-Thread Studio中配置软件包时直接添加ulog_easyflash即会把easyflash也一块配置尽量,然后进入软件包的更多配置选项中,主要是对EasyFlash进行配置,参考官方给出的配置信息,如果是基于SPI的片外Flash,那么最小擦除粒度为4K=4096,最小写入粒度为1bit,为了配合ulog使用,开启log功能,配置保存的日志区大小为255*4096=1044480。并且开启ulog_easyflash软件包的Flash后端功能。
    在这里插入图片描述

  4. 配置完成之后保存让软件包进行更新,然后需要把EasyFlash软件包下的port文件夹内的ef_sfud_port.c文件(路径/ports/ef_sfud_port.c)拷贝至src路径下。如果移植不成功请仔细检查一下/inc下面的头文件和rtconfig.h内部的相关配置,一般是内部宏定义相关参数的时候出现了问题。注意在RT-Thread Studio中RT-Thread Settings基本取代了ENV的作用,因此各种应用检查、配置和使能主要还是在这里面完成。

  5. 如果编译过程中出现了如 “sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk’” 之类的错误,那是因为RT-Studio内部使用的是gcc编译,一些嵌入式底层的C语言库编译可能不支持,因此请在RT-Thread Settings的“组件和服务层”菜单栏中选择开启libc

  6. 注意需要先声明设备才能在EasyFlash初始化的时候找到这个东西,才能初始化成功,在ef_sfud_port.c文件中定义了如下函数。主要看备注下方的,它声明了一个spi_flash设备叫做w25q64,也就是说你之后再EasyFlash初始化前声明设备时也应该使用这个名称。

static const sfud_flash *flash;
EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size) {
    EfErrCode result = EF_NO_ERR;
    ...
    /* 从 RT-Thread 的 SPI Flash 设备中获取 SFUD Flash 设备对象 */
    extern rt_spi_flash_device_t w25q64;
    flash = (sfud_flash_t)(w25q64->user_data);
    return result;
}
  1. 当然你也可以进行修改,由于我使用的F7开发板上面的是W25Q254的片外FLASH,因此我就直接把该段程序中的名字进行修改,然后在main函数中进行初始化。
EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size) {
    EfErrCode result = EF_NO_ERR;

    *default_env = default_env_set;
    *default_env_size = sizeof(default_env_set) / sizeof(default_env_set[0]);

    rt_sem_init(&env_cache_lock, "env lock", 1, RT_IPC_FLAG_PRIO);

    extern rt_spi_flash_device_t w25q256;
    flash = (sfud_flash_t)(w25q256->user_data);

    return result;
}
  1. 注意ulog只有在写入日志后才能成功读取,因此我们可以在main中配置程序如下
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <sfud.h>
#include <sfud_def.h>
#include <spi_flash_sfud.h>
#include <easyflash.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

rt_spi_flash_device_t w25q256;

int main(void)
{
    if ((w25q256 = rt_sfud_flash_probe("W25Q256FV", "qspi10")) == NULL) {
        rt_kprintf("Error! W25Q256FV NOT FOUND!");
    }
    easyflash_init();
    LOG_D("Hello world!");
    
    while (1)
    {
        rt_thread_mdelay(1000);
    }

    return RT_EOK;
}

之后你看的如下输出就证明EasyFlash初始化完成
在这里插入图片描述
简单测试一下,由于我们在main()函数中已经输出了一条日志“Hello world”,因此使用ulog_easyflash的命令ulog_flash read得到的结果如下(请忽略前一条clean信息,这是我之前自己写程序测试时的遗留结果)
在这里插入图片描述
以上就是全部内容,如有错误请及时留言告知。



展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部