Renesa 瑞萨 RA4M2 移植文件系统FAT32

工程创建

Resc进行可视化配置工程

在这里插入图片描述

选定芯片型号
在这里插入图片描述

在这里插入图片描述

配置SDIO底层驱动(SD card)在这里插入图片描述

跳到对应GPIO,进行复用
在这里插入图片描述
将Operation Mode配置 SD_MMC 4Bit,系统会自动配置
在这里插入图片描述

会到stacks
在这里插入图片描述
根据上面提示,解决错误。
解决第一个error
在这里插入图片描述
SDHI配置
在这里插入图片描述
SD配置信息
在这里插入图片描述
以上SD卡底层配置完成

使用串口作为Debug 日志输出

SCI/UART
在这里插入图片描述
UART复用
在这里插入图片描述
uart配置
在这里插入图片描述

最后构建工程,工程构建完成。
在这里插入图片描述

debug 日志输出编写

/* 调试串口 UART0 初始化 */
void Debug_UART0_Init(void)
{
    fsp_err_t err = FSP_SUCCESS;
    
    err = R_SCI_UART_Open (&g_uart0_ctrl, &g_uart0_cfg);
    assert(FSP_SUCCESS == err);
}
/* 发送完成标志 */
volatile bool uart_send_complete_flag = false;

void debug_uart0_callback(uart_callback_args_t * p_args)
{
	switch (p_args->event)
    {
        case UART_EVENT_RX_CHAR:
        {
            /* 把串口接收到的数据发送回去 */
            R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)&(p_args->data), 1);
            break;
        }
        case UART_EVENT_TX_COMPLETE:
        {
            uart_send_complete_flag = true;
            break;
        }
        default:
            break;
    }
}
/* 重定向 printf 输出 */
#if defined __GNUC__ && !defined __clang__
int _write(int fd, char *pBuffer, int size); //防止编译警告
int _write(int fd, char *pBuffer, int size)
{
    (void)fd;
    R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)pBuffer, (uint32_t)size);
    while(uart_send_complete_flag == false);
    uart_send_complete_flag = false;
    return size;
}
#else
int fputc(int ch, FILE *f)
{
    (void)f;
    R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
    while(uart_send_complete_flag == false);
    uart_send_complete_flag = false;
    return ch;
}
#endif

验证输出

void hal_entry(void)
{
    /* TODO: add your own code here */
		Debug_UART0_Init();
	
	
		while(1)
		{
			R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
			printf("小昭debug\r\n");
		}
	
#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

在这里插入图片描述

SD card 初始化

FSPy已经写好了接口 直接调用就行
在这里插入图片描述

初始化SD card

void SDCard_Init(void)
{
    fsp_err_t err;
    
    /* 打开SDHI */
    err = g_sdmmc_on_sdhi.open(&g_sdmmc0_ctrl, &g_sdmmc0_cfg);
    assert(FSP_SUCCESS == err);
}

中断回调函数

__IO uint32_t g_transfer_complete = 0;
__IO uint32_t g_card_erase_complete = 0;
__IO bool g_card_inserted = false;

void g_sdnnc0_back(sdmmc_callback_args_t *p_args)
{
	if (SDMMC_EVENT_TRANSFER_COMPLETE == p_args->event)  //读取或写入完成
    {
        g_transfer_complete = 1;
    }
    if (SDMMC_EVENT_CARD_INSERTED == p_args->event)  //卡插入中断
    {
        g_card_inserted = true;
    }
    if (SDMMC_EVENT_CARD_REMOVED == p_args->event)   //卡拔出中断
    {
        g_card_inserted = false;
    }
    if (SDMMC_EVENT_ERASE_COMPLETE == p_args->event)  //擦除完成
    {
        g_card_erase_complete = 1;
    }
    if (SDMMC_EVENT_ERASE_BUSY == p_args->event)  //擦除超时
    {
        g_card_erase_complete = 2;
    }
}

SDMMC事件
在这里插入图片描述
测试验证读写SD卡功能

g_sdmmc_on_sdhi.statusGet(&g_sdmmc0_ctrl, &status);  //先判断SD卡是否被插上

g_sdmmc_on_sdhi.mediaInit(&g_sdmmc0_ctrl, &my_sdmmc_device);//确保sd卡被插上时,在初始化

g_sdmmc_on_sdhi.write(&g_sdmmc0_ctrl, g_src, 1, 1);    //写数据   前面设置了,写入512字节,512为一块  在第一个sector地址写入一个块大小的数据

g_sdmmc_on_sdhi.read(&g_sdmmc0_ctrl, g_dest, 1, 1);  //读数据

移植FAT32文件系统

FatFs 官网
FatFs 源码下载连接
在这里插入图片描述
下载源代码
在这里插入图片描述
document 介绍FAT32介绍、使用和移植,非常友好。

可以支持64位寻址
在这里插入图片描述
FAT限制
• 文件系统类型: FAT、 FAT32(rev0.0)和 exFAT(rev1.0)。
• 打开的文件数量:无限制。(取决于可用内存)
• 卷数:最多 10 个。
• 扇区大小: 512、 1024、 2048 和 4096 字节。
• 最小卷大小: 128 个扇区。
• 最大卷大小: 32 位 LBA 中的 2^32 - 1 扇区,在带有 exFAT 的 64 位 LBA 中几乎不受限制。
• 最大文件大小: FAT 卷上为 2^32 - 1 字节, exFAT 卷上几乎不受限制。
• 群集大小: FAT 卷上最多 128 个扇区, exFAT 卷上最多 16 MB。

目标:
简单实现文件读写和创建

会涉及到IO层中diskio.c/.h,以及配置文件 ffconf.h。

diskio.c

/* 为每个设备定义一个物理编号 */
#define ATA          0  // SD 卡
#define QSPI_FLASH   1  // 外部 QSPI Flash

// SD 卡块大小
#define SD_BLOCKSIZE 512
//
DSTATUS disk_status (
    BYTE pdrv               /* Physical drive nmuber to identify the drive */
)
{
    DSTATUS stat = 0;

    switch (pdrv) {
    case ATA :  /* SD CARD */

        stat = RES_OK;
        return stat;

    case QSPI_FLASH :  /* QSPI FLASH */
        break;
    }
    return STA_NOINIT;
}


DSTATUS disk_initialize (
    BYTE pdrv                               /* Physical drive nmuber to identify the drive */
)
{
    DSTATUS stat;
    fsp_err_t err;

    switch (pdrv) {
    case ATA :  /* SD CARD */

        /* Open the SDHI driver. */
        err = g_sdmmc_on_sdhi.open(&g_sdmmc0_ctrl, &g_sdmmc0_cfg);
        assert(FSP_SUCCESS == err);

        /* 设备应在检测到VDD最小值后1ms内准备好接受第一个命令。参考SD物理层简化规范6.00版第6.4.1.1节“卡的通电时间”。 */
        R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
        /* Initialize the SD card.  This should not be done until the card is plugged in for SD devices. */
        err = g_sdmmc_on_sdhi.mediaInit(&g_sdmmc0_ctrl, &my_sdmmc_device);
        assert(FSP_SUCCESS == err);

        stat = RES_OK;
        return stat;

    case QSPI_FLASH :  /* QSPI FLASH */
        break;
    }
    return STA_NOINIT;
}


DRESULT disk_read (
    BYTE pdrv,              /* Physical drive nmuber to identify the drive */
    BYTE *buff,             /* Data buffer to store read data */
    LBA_t sector,   /* Start sector in LBA */
    UINT count              /* Number of sectors to read */
)
{
    DRESULT res = RES_PARERR;
    fsp_err_t err;

    switch (pdrv) {
    case ATA :  /* SD CARD */
        err = g_sdmmc_on_sdhi.read(&g_sdmmc0_ctrl, buff, sector, count);
        assert(FSP_SUCCESS == err);
        while (g_transfer_complete == 0);
        g_transfer_complete = 0;

        res = RES_OK;
        return res;

    case QSPI_FLASH :  /* QSPI FLASH */
        break;
    }

    return RES_PARERR;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                            */
/*-----------------------------------------------------------------------*/

#if FF_FS_READONLY == 0

DRESULT disk_write (
    BYTE pdrv,                      /* Physical drive nmuber to identify the drive */
    const BYTE *buff,       /* Data to be written */
    LBA_t sector,           /* Start sector in LBA */
    UINT count                      /* Number of sectors to write */
)
{
    DRESULT res = RES_PARERR;
    fsp_err_t err;

    switch (pdrv) {
    case ATA :  /* SD CARD */
        err = g_sdmmc_on_sdhi.write(&g_sdmmc0_ctrl, buff, sector, count);
        assert(FSP_SUCCESS == err);
        while (g_transfer_complete == 0);
        g_transfer_complete = 0;

        res = RES_OK;
        return res;

    case QSPI_FLASH :  /* QSPI FLASH */
        break;
    }

    return RES_PARERR;
}

#endif


DRESULT disk_ioctl (
    BYTE pdrv,              /* Physical drive nmuber (0..) */
    BYTE cmd,               /* Control code */
    void *buff              /* Buffer to send/receive control data */
)
{
    DRESULT res;

    switch (pdrv) {
    case ATA :  /* SD CARD */
        switch (cmd)
        {
            // 扇区大小。仅当FF_MAX_SS > FF_MIN_SS时,才需要此命令。
            case GET_SECTOR_SIZE :
                *(WORD * )buff = (WORD)my_sdmmc_device.sector_size_bytes;
            break;
            // 擦除块大小(以扇区为单位)
            case GET_BLOCK_SIZE :
                *(DWORD * )buff = my_sdmmc_device.erase_sector_count;
            break;
            //可用扇区数
            case GET_SECTOR_COUNT:
                *(DWORD * )buff = my_sdmmc_device.sector_count;
                break;
            case CTRL_SYNC :
            break;
        }

        res = RES_OK;
        return res;

    case QSPI_FLASH :  /* QSPI FLASH */
        break;
    }

    return RES_PARERR;
}


//ffconf.h
#define FF_VOLUMES		2  
#define FF_FS_NORTC		1   //关闭时间戳

测试验证

g_sdmmc_on_sdhi.statusGet(&g_sdmmc0_ctrl, &status);
g_sdmmc_on_sdhi.mediaInit(&g_sdmmc0_ctrl, &my_sdmmc_device);

f_mount(&fs, "0:", 1);  //挂载

f_mkfs("0:", NULL, work, sizeof(work)); f_setlabel()//没有文件系统,进行格式化  设置盘符名称

f_open(&fnew, "0:FatFs_debug.txt", FA_CREATE_ALWAYS | FA_WRITE);
f_close(&fnew);

f_open(&fnew, "0:FatFs_debug.txt", FA_OPEN_EXISTING | FA_READ);
f_close(&fnew);
f_mount(NULL, "0:", 1);

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 这个错误的直接原因是系统无法找到文件"c:\program files(x86)\renesa",这可能是由于该文件被误删除、文件路径被改变或者系统出现了错误等原因造成的。当尝试运行某个程序时,如果需要用到这个文件,但是系统无法找到该文件,则会产生以上的错误信息。针对这个错误,我们可以采取一些措施来尝试解决问题。首先,我们可以检查该文件是否已经被误删除或者被其他程序占用。如果文件没有问题,则我们可以尝试更改文件的路径,以避免与其他程序出现冲突。同时,我们也可以尝试重新安装软件,并确保安装过程中没有出现任何异常,这有可能会解决该问题。如果以上措施都无法解决问题,则可能需要联系软件的开发商,寻求更专业的技术支持。总之,针对这个错误,我们需要先了解其直接原因,并采取一些行动来解决问题,以确保软件能够正常运行。 ### 回答2: 这个错误提示意味着系统找不到指定路径下的"renesa"产品文件。通常几种情况会导致这个错误: 第一,该产品文件已经被删除或移动到其他位置。如果之前曾经在这个路径安装过该文件,但是现在找不到,那么很有可能是该文件被删除或者移动到了其他地方。在这种情况下,我们需要重新安装该产品文件。 第二,该产品文件被某种软件或者安全性程序误判为病毒或者不安全的文件。这种情况下,该文件可能被安全性程序给隔离或者删除了。如果是这种情况,我们需要先检查一下自己的安全性程序,看该文件是否被隔离,并将其恢复或者从白名单中添加该文件。 第三,该产品文件路径有误。有时候,我们可能会将该文件放在其他地方,或者修改了该文件的路径,这种情况下系统的程序就无法找到该文件。如果是这种情况,我们需要找到该文件的正确路径,并将其修改为正确路径。 总结来说,导致系统无法找到指定路径下的产品文件有多种情况。我们需要仔细检查程序文件的位置及其路径,确定路径是否正确,文件是否存在或者被误判为不安全文件。只有检测出具体原因,我们才能解决该问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小昭dedug

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

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

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

打赏作者

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

抵扣说明:

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

余额充值