RT-Thread Studio学习记录(三)SFUD挂载W25QXX使用FAL和EasyFlash

参考文章:https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi

一、概述

使用SFUD通用驱动程序挂载W25QXX,使用FAL和EasyFlash管理Flash。
操作步骤如下:1挂载SPI FLASH W25Qxx到SPI总线
2使用Fal及EasyFlash

二、SPI挂载W25QXX

1、在applications文件夹下新建文件夹w25qxx,新建w25qxx.c及w25qxx.h文件。
2.RT Thread Studio配置。
main线程栈大小改为8192
在这里插入图片描述
board中打开SPI2
在这里插入图片描述
stm32f1xx_hal_conf_bak.h中使能SPI模块(不知此步是否为必须)
在这里插入图片描述
打开STM32 CubeMX,配置SPI,配置mode,定义使用的引脚
配置其他参数
在这里插入图片描述
生成后关闭CubeMX。重新编译。
3.w25qxx.c文件编写

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-02-23     admin       the first version
 */

/*
 * 程序清单:这是一个 SPI 设备使用例程
 * 例程导出了 spi_w25q_sample 命令到控制终端
 * 命令调用格式:spi_w25q_sample spi10
 * 命令解释:命令第二个参数是要使用的SPI设备名称,为空则使用默认的SPI设备
 * 程序功能:通过SPI设备读取 w25q 的 ID 数据
*/

#include <rtthread.h>
#include <rtdevice.h>
#include <w25qxx.h>
#include "drv_spi.h"
#include "spi_flash.h"
#include "spi_flash_sfud.h"
#include <define_common.h>
#include <drv_common.h>


struct rt_spi_device *spi_device;

static int rt_hw_spi_flash_init(void)
{
    __HAL_RCC_GPIOB_CLK_ENABLE();
    rt_hw_spi_device_attach("spi2", W25Q_SPI_DEVICE_NAME, GPIOB, GPIO_PIN_12);
    if (RT_NULL == rt_sfud_flash_probe("W25Q128", W25Q_SPI_DEVICE_NAME))
    {
        return -RT_ERROR;
    };
    return RT_EOK;
}
void spi_w25q_sample(int argc, char *argv[])
{
    struct rt_spi_device *spi_dev_w25q;
    char name[RT_NAME_MAX];
    rt_uint8_t w25x_read_id = 0x90;
    rt_uint8_t id[5] = {0};
    rt_hw_spi_flash_init();
    if (argc == 2)
    {
        rt_strncpy(name, argv[1], RT_NAME_MAX);
    }
    else
    {
        rt_strncpy(name, W25Q_SPI_DEVICE_NAME, RT_NAME_MAX);
    }

    /* 查找 spi 设备获取设备句柄 */
    spi_dev_w25q = (struct rt_spi_device *)rt_device_find(name);
    if (!spi_dev_w25q)
    {
        rt_kprintf("spi sample run failed! can't find %s device!\n", name);
    }
    else
    {
        /* 方式1:使用 rt_spi_send_then_recv()发送命令读取ID */
        rt_spi_send_then_recv(spi_dev_w25q, &w25x_read_id, 1, id, 5);
        rt_kprintf("use rt_spi_send_then_recv() read w25q ID is:%x%x\n", id[3], id[4]);

        /* 方式2:使用 rt_spi_transfer_message()发送命令读取ID */
        struct rt_spi_message msg1, msg2;

        msg1.send_buf   = &w25x_read_id;
        msg1.recv_buf   = RT_NULL;
        msg1.length     = 1;
        msg1.cs_take    = 1;
        msg1.cs_release = 0;
        msg1.next       = &msg2;

        msg2.send_buf   = RT_NULL;
        msg2.recv_buf   = id;
        msg2.length     = 5;
        msg2.cs_take    = 0;
        msg2.cs_release = 1;
        msg2.next       = RT_NULL;

        rt_spi_transfer_message(spi_dev_w25q, &msg1);
        rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", id[3], id[4]);

    }
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(spi_w25q_sample, spi w25q sample);

w25qxx.h文件代码

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-02-23     admin       the first version
 */
#ifndef APPLICATIONS_W25QXX_W25QXX_H_
#define APPLICATIONS_W25QXX_W25QXX_H_
#include <define_common.h>

void spi_w25q_sample(int argc, char *argv[]);
#endif /* APPLICATIONS_W25QXX_W25QXX_H_ */

在main函数中调用

int main(void)
{
    led_init();
    uart_init();
    spi_w25q_sample(1, RT_NULL);
}

下载运行后课打印w25qxx已挂载,并读出ID号

三、使用EasyFlash软件包

1.打开RT-Thread Settings,添加软件包,搜索“EasyFlash”并添加。
在这里插入图片描述
点击编译出现50多个错误。(系统版本为4.1.1)。
2.在组件中启用FAL
在这里插入图片描述
3.在项目中添加ef_fal_port.c和fal_cfg.h
4.main函数编写

/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-02-21     RT-Thread    first version
 */

#include <rtthread.h>
#include <rtdevice.h>
#include <drv_common.h>
#include <define_common.h>
#include <uart.h>
#include <w25qxx.h>
#include <fal.h>
#include <easyflash.h>
#include <stdlib.h>
#include <pump.h>

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

#define LED_PIN GET_PIN(C, 8)
//#define SAMPLE_UART_NAME       "uart1"

//static rt_device_t serial;//设备变量
//static struct rt_semaphore rx_sem;//用于接收消息的信号量
//led flah
int led_init(void)
{
    rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
    return RT_EOK;
}

INIT_ENV_EXPORT(fal_init);

int main(void)
{
//    led_init();
//    uart_init();
//    rt_thread_mdelay(100);
//    spi_w25q_sample(1, RT_NULL);
//    fal_init();
//    rt_thread_mdelay(100);

    if(easyflash_init() == EF_NO_ERR)
    {
        rt_uint32_t i_boot_times = 0;
        size_t len = 0;
//        rt_uint32_t len = 0;
        char c_new_boot_times[11] = {0};
        /* 如果环境变量长度未知,可以先获取 Flash 上存储的实际长度,将通过 len 返回 */
        ef_get_env_blob("startup_times", NULL, 0, &len);
        /* 如果长度已知,使用 value 缓冲区,存放读取回来的环境变量值数据,并将实际长度返回 */
        ef_get_env_blob("startup_times", c_new_boot_times, len , NULL);
        i_boot_times = atol(c_new_boot_times);
        i_boot_times ++;
        rt_kprintf("===============================================<br>");
        rt_kprintf("The system now boot %d times<br>", i_boot_times);
        rt_kprintf("===============================================<br>");
        sprintf(c_new_boot_times, "%ld", i_boot_times);
        ef_set_env("startup_times", c_new_boot_times);
        ef_save_env();
    }
    pump_test();
}

编译通过。
使用的芯片为STM32F103RCT6,发现一个问题,偶尔的时候下载后运行main函数进入hardware fault,有的时候重新编译一次就可以了。不知道是什么原因,还有待解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值