这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【S32K146】S32K146片内flash 适配Rt-thread MTD驱

共1条 1/1 1 跳转至

【S32K146】S32K146片内flash 适配Rt-thread MTD驱动

高工
2025-06-16 15:43:36     打赏

【简介】

我们在上一篇基于S32K146 完成了片内flash 驱动的编写(【S32K146】S32K146片内flash编程),RT-thread 将常用的存储设备抽象成MTD(Memory Technology Device)设备驱动,S32K146 的片内有1M的NOR flash,大部分都是空闲未使用状态,本次试验将使用后512K进行验证将这部分flash 通过RT-thread 的MTD nor 设备进行管理。

【MTD驱动适配】

MTD NOR 设备通过结构体struct rt_mtd_nor_device 进行管理,包含了设备基类结构体,Flash 块大小,块起始地址,块结束地址,以及NOR 设备操作方法,定义如下:

struct rt_mtd_nor_device
{
    struct rt_device parent;

    rt_uint32_t block_size;         /* The Block size in the flash */
    rt_uint32_t block_start;        /* The start of available block*/
    rt_uint32_t block_end;          /* The end of available block */

    /* operations interface */
    const struct rt_mtd_nor_driver_ops* ops;
};

struct rt_mtd_nor_driver_ops
{
    rt_err_t (*read_id) (struct rt_mtd_nor_device* device);

    rt_ssize_t (*read)    (struct rt_mtd_nor_device* device, rt_off_t offset, rt_uint8_t* data, rt_size_t length);
    rt_ssize_t (*write)   (struct rt_mtd_nor_device* device, rt_off_t offset, const rt_uint8_t* data, rt_size_t length);

    rt_err_t (*erase_block)(struct rt_mtd_nor_device* device, rt_off_t offset, rt_size_t length);
};

我们按照老套路将片内flash 相关操作函数及属性信息填充到struct rt_mtd_nor_device 结构并注册到系统内部交由系统管理完成驱动的适配,具体适配函数如下:

#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"

struct mflash_mtd
{
        struct rt_mtd_nor_device mtd_device;
        struct rt_mutex lock;
        flash_ssd_config_t SSDConfig;
        uint32_t mflash_start;
        void * user_data;
};


rt_ssize_t mlash_write(struct rt_mtd_nor_device* device, rt_off_t offset, const rt_uint8_t* data, rt_size_t length)
{
    status_t ret;
    uint32_t dest;

    struct mflash_mtd * p_mflash_mtd = (struct mflash_mtd *)device;

    dest = p_mflash_mtd->mflash_start + offset;

    if((dest + length) > (device->block_end*device->block_size))
        return 0;

    ret = FLASH_DRV_Program(&p_mflash_mtd->SSDConfig,dest,length,data);


    return ret == STATUS_SUCCESS ? length : 0;
}


rt_ssize_t mflash_read(struct rt_mtd_nor_device* device, rt_off_t offset, rt_uint8_t* data, rt_size_t length)
{
    uint32_t dest;

    struct mflash_mtd * p_mflash_mtd = (struct mflash_mtd *)device;

    dest = p_mflash_mtd->mflash_start + offset;

    if((dest + length) > (device->block_end*device->block_size))
        return 0;

    for(uint32_t i=0; i < length; i++)
    {
        data[i] = *((__IO rt_uint8_t*)dest);
        dest++;
    }

    return length;
}


rt_err_t mflash_erase_block(struct rt_mtd_nor_device* device, rt_off_t offset, rt_size_t length)
{

    status_t ret;
    uint32_t addr;

    struct mflash_mtd * p_mflash_mtd = (struct mflash_mtd *)device;

    addr = p_mflash_mtd->mflash_start + offset;

    ret = FLASH_DRV_EraseSector(&p_mflash_mtd->SSDConfig,addr,length);

    return ret == STATUS_SUCCESS ? RT_EOK : -1;

}


const static struct rt_mtd_nor_driver_ops mflash_ops =
{
    .read_id = NULL,
    .read = mflash_read,
    .write = mlash_write,
    .erase_block = mflash_erase_block,
};


int rt_hw_mflash_init(void)
{
    static struct mflash_mtd mflash;

    mflash.mtd_device.ops = &mflash_ops;
    mflash.mtd_device.block_size = FEATURE_FLS_PF_BLOCK_SECTOR_SIZE;
    mflash.mtd_device.block_start = 128;
    mflash.mtd_device.block_end = 255;
    mflash.mflash_start = 0X80000;
    
    FLASH_DRV_Init(&Flash_InitConfig0,&mflash.SSDConfig);

    rt_mtd_nor_register_device("mflash",&mflash.mtd_device);

    return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_mflash_init);

将上述设备驱动注册进入系统后通过list device 命令查看系统设备节点发现mflash 对应的MTD设备已经按照预期注册进系统:

image.png

【测试验证】

我们在RT-thread 下编写如下测试代码验证mtd 驱动的读写功能

static void mflash(int argc,char *argv[])
{
    static rt_device_t mtd = RT_NULL;

    if(!strcmp(argv[1], "open"))
    {
        mtd = rt_device_find("mflash");

        if(!mtd)
            rt_kprintf("rt find device failed.\n");
        else
            rt_kprintf("rt find device ok.\n");
    }
    else if(!strcmp(argv[1], "erase"))
    {
        rt_mtd_nor_erase_block((struct rt_mtd_nor_device*)mtd,0x00,4096);
    }
    else if(!strcmp(argv[1], "write"))
    {
        char * writetest = " hello world   ";
        
        rt_mtd_nor_write((struct rt_mtd_nor_device*)mtd,0,writetest,16);
    }
    else if(!strcmp(argv[1], "read"))
    {
        char readbuff[16];
        
        rt_mtd_nor_read((struct rt_mtd_nor_device*)mtd,0,readbuff,16);
                          
        rt_kprintf("read test data is %s \n",readbuff);
    }

}
MSH_CMD_EXPORT(mflash, mflash mtd test);

上述代码运行验证如下,open/erase/write 后去读取测试数据和测试代码写入的一致,至此已经将片内flash 对接到Rt-thread 的MTD驱动。

image.png






共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]