RTThread之FLASH操作详细介绍

FLASH操作

1.FAL组件

FAL组件的安装在我的其他章节中已经介绍过了,主要是先要将FLASH分块(区),然后在分块(区)中去处理。

->下面是我的分区,因为用到了串口升级功能,所以分了好多区(块)。
->这里面的设置放在了.h文件里面

// 
#define FAL_PART_TABLE                                                               \
{                                                                                    \
      {FAL_PART_MAGIC_WORD,   "bootloader",     "onchip_flash",    0,               14 * 1024,  0}, \
      {FAL_PART_MAGIC_WORD,   "bootflag",       "onchip_flash",    14 * 1024,       2 * 1024,  0}, \
      {FAL_PART_MAGIC_WORD,   "app",            "onchip_flash",    16 * 1024,       184 * 1024, 0}, \
      {FAL_PART_MAGIC_WORD,   "eeprom",         "onchip_flash",    200 * 1024,      12 * 1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */

-> 分块处理函数

// 块擦除函数
fal_partition_erase_all(fal_partition_find("bootflag")); //
// 块擦除函数,可以看到擦除的对象是*part部分起始地址为0偏移地址为块长度的区域
int fal_partition_erase_all(const struct fal_partition *part)
{
    return fal_partition_erase(part, 0, part->len);
}
// 块擦除函数的区域操作,做地址偏移
int fal_partition_erase(const struct fal_partition *part, uint32_t addr, size_t size)
{
    int ret = 0;
    const struct fal_flash_dev *flash_dev = NULL;

    //assert(part);

    if (addr + size > part->len)
    {
        log_e("Partition erase error! Partition address out of bound.");
        return -1;
    }

    flash_dev = fal_flash_device_find(part->flash_name);
    if (flash_dev == NULL)
    {
        log_e("Partition erase error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name);
        return -1;
    }

    ret = flash_dev->ops.erase(part->offset + addr, size);      //   error
    if (ret < 0)
    {
        log_e("Partition erase error! Flash device(%s) erase error!", part->flash_name);
    }

    return ret;
}
// 块读取函数,读取到某指针(数组)
int fal_partition_read(const struct fal_partition *part, uint32_t addr, uint8_t *buf, size_t size)
{
    int ret = 0;
    const struct fal_flash_dev *flash_dev = NULL;

    assert(part);
    assert(buf);

    if (addr + size > part->len)
    {
        log_e("Partition read error! Partition address out of bound.");
        return -1;
    }

    flash_dev = fal_flash_device_find(part->flash_name);
    if (flash_dev == NULL)
    {
        log_e("Partition read error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name);
        return -1;
    }

    ret = flash_dev->ops.read(part->offset + addr, buf, size);
    if (ret < 0)
    {
        log_e("Partition read error! Flash device(%s) read error!", part->flash_name);
    }

    return ret;
}
// 块写入函数,从某指针(数组)写入
int fal_partition_write(const struct fal_partition *part, uint32_t addr, const uint8_t *buf, size_t size)
{
    int ret = 0;
    const struct fal_flash_dev *flash_dev = NULL;

    assert(part);
    assert(buf);

    if (addr + size > part->len)
    {
        log_e("Partition write error! Partition address out of bound.");
        return -1;
    }

    flash_dev = fal_flash_device_find(part->flash_name);
    if (flash_dev == NULL)
    {
        log_e("Partition write error!  Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name);
        return -1;
    }

    ret = flash_dev->ops.write(part->offset + addr, buf, size);
    if (ret < 0)
    {
        log_e("Partition write error! Flash device(%s) write error!", part->flash_name);
    }

    return ret;
}

直接操作FLASH

相对于FAL,我比较喜欢直接操作FLASH,感觉更灵活。

FLASH 读

// FLASH读取函数
//addr-> 读取的地址
//buf读取数据保存的指针(数组)
//读取数据的大小(字节byte)
int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
{
    size_t i;

    if ((addr + size) > STM32_FLASH_END_ADDRESS)
    {
        LOG_E("read outrange flash size! addr is (0x%p)", (void *)(addr + size));
        return -RT_EINVAL;
    }

    for (i = 0; i < size; i++, buf++, addr++)
    {
        *buf = *(rt_uint8_t *) addr;
    }

    return size;
}

FLASH 写

//不用擦除的写
//addr -> 写的起始地址
//buf -> 写入数据来源指针(数组)
//size -> 写入大小(字节byte)
int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
{
    rt_err_t result        = RT_EOK;
    rt_uint32_t end_addr   = addr + size;

    if (addr % 4 != 0)
    {
        LOG_E("write addr must be 4-byte alignment");
        return -RT_EINVAL;
    }

    if ((end_addr) > STM32_FLASH_END_ADDRESS)
    {
        LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size));
        return -RT_EINVAL;
    }

    HAL_FLASH_Unlock();

    while (addr < end_addr)
    {
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, *((rt_uint32_t *)buf)) == HAL_OK)
        {
            if (*(rt_uint32_t *)addr != *(rt_uint32_t *)buf)
            {
                result = -RT_ERROR;
                break;
            }
            addr += 4;
            buf  += 4;
        }
        else
        {
            result = -RT_ERROR;
            break;
        }
    }

    HAL_FLASH_Lock();

    if (result != RT_EOK)
    {
        return result;
    }

    return size;
}

3.FAL组件对FLASH操作及FAL组件与FLASH底层之间的关系

调用关系

// 
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
{
    return stm32_flash_read(stm32_onchip_flash.addr + offset, buf, size);
}

static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size)
{
    return stm32_flash_write(stm32_onchip_flash.addr + offset, buf, size);
}

static int fal_flash_erase(long offset, size_t size)
{
    return stm32_flash_erase(stm32_onchip_flash.addr + offset, size);
}

OVER TY

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
风速监测报警作者:苏庆洪 概述风速监测报警系统基于 MCU芯片开发,支持采集多路从机分节点的风速数据,通过无线主从传输,主机收集数据,通过显示屏实时监视,在风速超过报警值时,通过GPIO输出接点信号,启动预警,降低自然风灾害对生命财产损失的风险。点对点无线传输距离可达 2000m ~ 3000m,具有传输距离远的特点,通过组网可以覆盖大面积预警区域,该系统适用于野外对风速敏感的设备,房屋进行监测,特别是各风景名胜区,地处名山大川,其载客索道缆车,当线路上风速过大时,可以和主控系统联动,进行减速和停机控制。 开发环境硬件:stm32f103-atk-mini RT-Thread版本:RT-Thread V 4.0.3 开发工具及版本:MDK 5.25 RT-Thread使用情况概述内核部分:调度器,信号量,消息队列。 调度器:创建多个线程来实现不同的工作。 信号量:用来同步线程。 设备框架:通过 RT-Thread提供的 I/O 设备管理接口来访问串口硬件。 硬件框架从机MCU 定时读取 风速传感器数据,然后通过 ATK-LORA 传输到主机,主机对数据进行比例运算处理,LCD显示和GPIO输出 软件框架说明MCU 上电之后首先完成板级外设的初始化,图形界面littleVGL初始化,定时请求数据,串口中断释放信号量,线程实时处理数据,并显示、控制。 软件模块说明主机创建了3个线程,1个信号量。 main:完成初始化,创建信号量,打开串口设备,设置中断响应函数,创建线程,定时请求从机数据。 lcd_thread_entry:开启littlevgl的事务处理lv_task_handler()。 usart_thread_entry:take信号量的方式,获取到信号量之后,开始数据接收,正确收到数据后,显示,并输出IO信号。 演示效果模拟仪表显示,绿色指针为当前风速值,红色指针为故障上限,黄色指针为报警上限 拖动滑块左右移动可以设定报警值 切换软件开关,对太阳能电池进行充电 B站地址 比赛感悟时代的发展,MCU的性能也越来越强,万物互联的需求也愈加强烈,使用RTOS来实现物与网的链接,是时代发展的潮流,当我接触到RT-Thread 这个国人自主RTOS后,经过对比其他的freertos,ucos等,RT-Thread代码很优雅,组件功能多,小而美,我开始了深入的学习。 通过 RT-Thread官网上的文档中心,我学习了多线程及其调度、信号量、邮箱、消息队列、内存管理、定时器等,但是感觉认识很肤浅,对于信号量是怎么实现的?rtos是怎么达到实时性?还是一头雾水。 于是又学习了火哥出版的《RT-Thread 内核实现与应用开发实战—基于STM32》,手把手,一步一步实现了RT-Thread,终于有了深刻认识,可以实际操作了。 通过这次比赛的项目实践,我对RT-Thread有了全新的认识,他不仅仅是一个嵌入式RTOS,当各种组件有序结合起来,必能够发挥出更大能量,体现无与伦比的扩展性和灵活性,无愧小而美物联网操作系统的称呼,现在RT-Thread smart已经上线了,无疑体现出来RT-Thread的蓬勃生命力和无限美好的发展前景,我相信选择RT-Thread绝对是正确的。 这个小作品,还有待完善,现在仅能通过触摸屏显示一些数据,并调整参数,还得增加一些功能,比如省电管理,远程开关机,还得解决开发硬件、软件的版权问题,在此仅作为演示,给下一步的开发提供一些思路,距离产品还有很长的路要走。 美中不足的地方,RT-Thread studio编译代码偏大,以至于我这个mini板flash和ram容量不够,下一步还得好好研究,怎样裁剪,用RT-Thread studio做产品的问题。 最后感谢主办方提供了这么好的一个平台,不仅能展示自我,也能学到很多知识,还要感谢论坛上那些解决我问题以及制作软件包的大佬,希望有朝一日我也能给开源社区贡献一份自己力量。
RT-Thread诞生于2006年,是一款以开源、中立、社区化发展起来的物联网操作系统。 RT-Thread主要采用 C 语言编写,浅显易懂,且具有方便移植的特性(可快速移植到多种主流 MCU 及模组芯片上)。RT-Thread把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。 RT-Thread有完整版和Nano版,对于资源受限的微控制器(MCU)系统,可通过简单易用的工具,裁剪出仅需要 3KB Flash、1.2KB RAM 内存资源的 NANO 内核版本;而相对资源丰富的物联网设备,可使用RT-Thread完整版,通过在线的软件包管理工具,配合系统配置工具实现直观快速的模块化裁剪,并且可以无缝地导入丰富的软件功能包,实现类似 Android 的图形界面及触摸滑动效果、智能语音交互效果等复杂功能。 RT-Thread架构 RT-Thread是一个集实时操作系统(RTOS)内核、中间件组件的物联网操作系统,架构如下: 内核层:RT-Thread内核,是 RT-Thread的核心部分,包括了内核系统中对象的实现,例如多线程及其调度、信号量、邮箱、消息队列、内存管理、定时器等;libcpu/BSP(芯片移植相关文件 / 板级支持包)与硬件密切相关,由外设驱动和 CPU 移植构成。 组件与服务层:组件是基于 RT-Thread内核之上的上层软件,例如虚拟文件系统、FinSH命令行界面、网络框架、设备框架等。采用模块化设计,做到组件内部高内聚,组件之间低耦合。 RT-Thread软件包:运行于 RT-Thread物联网操作系统平台上,面向不同应用领域的通用软件组件,由描述信息、源代码或库文件组成。RT-Thread提供了开放的软件包平台,这里存放了官方提供或开发者提供的软件包,该平台为开发者提供了众多可重用软件包的选择,这也是 RT-Thread生态的重要组成部分。软件包生态对于一个操作系统的选择至关重要,因为这些软件包具有很强的可重用性,模块化程度很高,极大的方便应用开发者在最短时间内,打造出自己想要的系统。RT-Thread已经支持的软件包数量已经达到 180+。 RT-Thread的特点: 资源占用极低,超低功耗设计,最小内核(Nano版本)仅需1.2KB RAM,3KB Flash。 组件丰富,繁荣发展的软件包生态 。 简单易用 ,优雅的代码风格,易于阅读、掌握。 高度可伸缩,优质的可伸缩的软件架构,松耦合,模块化,易于裁剪和扩展。 强大,支持高性能应用。 跨平台、芯片支持广泛。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LuDvei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值