You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Linux 4.14下VS1053播放MP3提示:设备无剩余空间写入错误

VS1053字符设备写入MP3报"No space left on device"问题排查与解决

首先得明确一个关键误区:你遇到的No space left on device和磁盘空间/Inode完全无关——字符设备本身没有实际的存储介质,这个错误是驱动程序在write函数里主动返回的ENOSPC错误码,和磁盘状态没关系。结合你WAV播放正常、MP3报错的现象,问题大概率出在驱动对VS1053硬件解码逻辑的处理上,下面给你梳理排查方向和解决方案:

可能的核心原因

VS1053是硬件解码器,WAV是无压缩的PCM数据,驱动处理时可以直接把数据喂给解码缓冲区;但MP3是压缩格式,需要解码器先解析帧结构再解码,驱动如果没有适配MP3的流处理逻辑,就会出现缓冲区"假满"的误判。

具体排查步骤

1. 检查驱动write函数的实现逻辑

直接去看基于rvp-nl/vs10xx-linux修改的驱动代码,重点看write函数里什么时候返回-ENOSPC

  • 有没有忽略VS1053的DREQ信号?VS1053的SCI_REG_STATUS寄存器里的DREQ位表示解码器是否准备好接收新数据,驱动必须等待DREQ为高时才能写入数据。如果驱动处理WAV时是硬编码了缓冲区大小,没做DREQ等待,MP3的压缩数据写入时因为解码耗时更长,缓冲区会更快被填满,驱动就直接返回空间不足。
  • 有没有区分音频格式的处理逻辑?比如驱动默认只初始化了WAV解码模式,没有切换到MP3解码模式,导致解码器无法处理MP3数据,缓冲区数据无法被消耗,最终触发错误。

2. 验证VS1053的解码器初始化状态

VS1053需要通过SPI配置寄存器来切换解码模式,你可以在驱动初始化或第一次写入数据时,检查是否正确设置了MP3相关参数:

  • 确认SCI_MODE寄存器的设置是否开启了MP3解码支持(VS1053原生支持MP3,但需要正确配置模式位)。
  • 可以尝试在写入MP3文件前,通过SPI手动发送MP3解码初始化命令,再测试写入。

3. 给驱动添加调试日志

在驱动的write函数里添加打印信息,输出每次写入的字节数、当前SCI_REG_STATUS寄存器的DREQ位状态,看报错时是不是真的缓冲区满了,还是驱动逻辑误判。比如:

dev_info(vs1053_dev, "Write count: %zu, DREQ status: %d\n", count, 
         !!(vs1053_read_reg(SCI_REG_STATUS) & SCI_STATUS_DREQ));

针对性解决方案

1. 修复write函数的等待逻辑

修改驱动的write函数,实现循环写入+DREQ等待的逻辑,确保解码器准备好后再继续写入数据,示例代码如下:

ssize_t vs1053_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
    ssize_t total_written = 0;
    unsigned char local_buf[32]; // VS1053单次最多接收32字节数据
    size_t write_chunk;

    while (count > 0) {
        // 等待DREQ信号,确保解码器可以接收数据
        while (!(vs1053_read_reg(SCI_REG_STATUS) & SCI_STATUS_DREQ)) {
            msleep(1); // 短延时等待,避免CPU空转
        }

        write_chunk = min(count, sizeof(local_buf));
        if (copy_from_user(local_buf, buf + total_written, write_chunk)) {
            return -EFAULT;
        }

        // 写入VS1053的数据缓冲区
        vs1053_write_data(local_buf, write_chunk);
        
        total_written += write_chunk;
        count -= write_chunk;
    }

    return total_written;
}

2. 确保MP3解码模式正确初始化

在驱动的probe函数或open函数中,添加MP3解码器的初始化代码:

// 设置SCI_MODE寄存器,开启MP3解码
vs1053_write_reg(SCI_REG_MODE, SM_SDINEW | SM_RESET);
msleep(100); // 等待复位完成
vs1053_write_reg(SCI_REG_MODE, SM_SDINEW);
// 可以根据需要设置解码音量等参数
vs1053_write_reg(SCI_REG_VOL, 0x2020);

3. 检查MP3文件的兼容性

少数情况下,某些特殊编码的MP3文件(比如非标准采样率、比特率)可能导致VS1053解码异常,缓冲区无法释放。可以换几个标准的MP3文件测试,排除文件本身的问题。

内容的提问来源于stack exchange,提问作者Gerald

火山引擎 最新活动