KDocs 研发资料库
  • 音频技术应用文档入口汇总
  • 杰理WINDOWS环境安装及其他事项
  • LINUX安装和编译
  • Linux环境编译SDK教程(ubuntu18.04)
  • 音频类补丁汇总表
  • 认证资料获取汇总(最新资料后台会更新)
  • 《Hi-Res申请指南v1.0》
  • FreeRTOS 开源协议版本
  • uCOS 开源协议版本信息
  • 各个模块关键资料汇总
  • 软件调试方法
  • Makefile编译
  • 提bug的规范
  • 常规设备使用指导
  • 对外特别发布开发注意点信息汇总
  • AD697X软件问题整理
  • AC700N软件问题整理
  • AC701X耳机软件问题整理
  • 951&961软件问题整理
  • AC104X软件问题整理
  • AC128N问题整理文档
  • 可视化工具调试问题整理
  • 耳机资料汇总
  • AC704N、 AC705N相关应用
  • AC695N&AC696N&AC608N音箱问题整理
  • JL701N音箱问题整理
  • AC692X软件问题整理
  • AC706N音箱问题整理
  • JL701N音箱问题整理(可视化工具SDK)
  • JL703N音箱问题整理
  • JL709N(JL689N)音箱问题整理
  • JL7094系列-入门到进阶开发指导
  • AC210N音箱问题整理
  • 无线麦系列版本支持指南
  • AW32N无线麦问题整理
  • lAD697X&JL701X 无线麦软件共性问题整理
  • AC706N无线麦问题整理
  • AW36N无线麦问题整理
  • AC710X无线麦问题整理
  • 唤醒源获取及唤醒IO设置
  • 电源
  • LVD
  • 长按复位配置方法
  • 低功耗应用
  • TIMER
  • UART
  • SPI
  • 内部FLASH空间添加用户自定义区域
  • IIC
  • GPIO
  • MCPWM
  • SD&U盘
  • 时钟&晶振
  • GPCNT
  • IO口crossbar映射功能
  • 文件系统使用总结
  • 复用应用
  • LINEIN_AUX相关应用
  • IIS音频接口应用
  • SPDIF模式相关(HDMI_ARC、光纤、同轴)
  • PDM LINK
  • 外设相关应用
  • 蓝牙相关
  • 杰理蓝牙距离调试文档
  • TWS耳机配对方式使用及生产把控指南
  • GFP谷歌快连及其认证流程指引
  • 蓝牙发射器(bt_emitter)相关
  • BLE应用
  • 关于提升BLE传输速率说明
  • BLE测试数据
  • MUSIC 模式相关应用
  • MIDI音乐实现
  • PC相关应用
  • FM相关应用
  • AC695N_AC696N FM天线ESD静电防护措施说明V2.0_20250107
  • fm应用详细设计说明书
  • 杰理FM硬件指南-20230315
  • ADC模块
  • AUDIO相关应用
  • 新Tools的音效调试使用
  • 混响应用使用说明
  • 音效调式
  • 音箱耳机低音小音量增强实现方法
  • DAC输出功率调试
  • DAC性能测试指南
  • 针对各类底噪、电流声分析流程
  • 录音相关应用
  • OPUS编解码相关
  • RTC相关应用
  • 升级相关
  • UI相关应用
  • 通话调试流程指南
  • 通话相关应用
  • 省电容mic使用手册
  • 如何测试验证手表通话系统的语音失真 V1.0
  • AC695X_AC696X_AD697X 常见通话问题处理参考资料
  • 通话调试问题确定步骤
  • 内置触摸调试指南
  • 低功耗内置触摸介绍V2.2
  • 触摸相关文档
  • AC697X、AC698X内置触摸调试及整改方法V1.0
  • 产测相关应用
  • AC63X BLE DUT测试介绍
  • 兆华序列使用简易说明
  • JL_1T2蓝牙测试盒音频文件更换说明
  • ENC相关应用入口汇总
  • ANC相关应用入口汇总
  • JL DMS通话调试手册-V3.9.4
  • ANC-ENC结构设计要点-20240407
  • 半入耳式ANC耳机器件选型与结构设计指南V1.0
  • JL 耳道自适应调试指南
  • ANC相关问题处理
  • ANC调试文档
  • 评估蓝牙耳机通话上行降噪性能的方法 V1.0 (2)
  • FCC 或者 BQB 认证相关应用
  • BQB profile 测试中常遇到的问题点汇总
  • 蓝牙参数整理20210811
  • 杰理科技认证问题参考
  • 无线音频产品开发指南
  • 无线麦系列从入门到进阶开发指导
  • 量产烧录相关说明
  • 一拖八烧录器远程过程调用说明
  • 量产相关建议
  • EffectTool(eq)调试工具说明文档
  • AC897AD697系列的EQ调试方法-V3
  • 杰理调音指南-20220622
  • 音效模块总结
  • 简要调音步骤指引(可视化)
  • 耳机充电与通信调试指南
  • 充电仓硬件调试指南
  • 充电仓软件问题整理
  • AC951常用说明
  • AC951_AC961_开发板使用说明V1.0
  • 彩屏仓AC982 入门指导及FAQ
  • 蓝牙音频APP相关应用
  • 手机APP的简介和开发流程
  • 蓝牙音频系列-硬件设计指南
  • 静电测试及整改方法-20220706
  • TWS耳机底噪整改指南V1.2
  • 杰理蓝牙距离调试文档
  • 蓝牙RF硬件设计与调试V1.1-20250219
  • AC695N_AC696N FM天线ESD静电防护措施说明V2.0_20241228
  • 音效调试指南
  • 无线话筒K歌音箱标准开发流程
  • 杰理科技 700N TWS耳机产品标准-202303
  • 杰理科技 701N 广播产品标准-202303
  • JL-HAT ANC高效产测自适应
  • 无线话筒测试板使用介绍
  • 一拖八频偏校准使用说明
  • 领夹麦产测工具使用介绍
  • Dongle量产测试说明
  • Dongle+Tws或头戴式 SDK通过工具绑定配对功能说明文档
  • 双麦ENC产测宏配置验证方法 V1.0
  • JL耳机方案麦克风声学测试指令_V1.0
  • JL耳机方案麦克风声学测试指令_V2.0
  • JL_ENC自动测试命令_V0.0.1
  • JL蓝牙测试盒用例说明
  • LDAC自测环境搭建_ubuntu
  • 延迟小板使用手册
  • 杰理库文件的制作及添加实现过程
  • 关于 AC635N&AC636N系列免晶振兼容性补丁 说明
  • 关于 AC63系列VM兼容性修复补丁_20250224 说明
  • 关于 AC632N &AE632N_ 蓝牙& 低功耗兼容性修复补丁 说明
  • AD698N和AC638N电压优化补丁V3说明
  • 关于 AC635N&AC636N漏电和E&G版兼容联合补丁 说明
  • AD698N和AC638N电压优化补丁V2说明
  • 702相关应用
  • 2024-4-30 发布歌词显示SDK开发注意事项
  • BQB RF & FCC 认证测试固件问题汇总及源码
  • BQB profile 测试中常遇到的问题点汇总
  • 进dut测试模式方法及固件
  • 704-频偏修改bin文件合集
  • 701手表BQB PROFILE认证注意事项
  • 认证的干扰规避整改
  • 海外CRA认证报告生成说明
  • JL700N可视化工具问题处理文档
  • JL701X可视化工具问题处理文档
  • JL701N_earphone_release_v1.6.0_ANC 低功耗问题补丁
  • JL708X可视化工具问题处理文档
  • JL709N可视化工具问题处理文档
  • JLstudio可视化工具使用说明
  • 一拖二-串口_蓝牙_app在线EQ、通话参数及调试方式和内置触摸调试
  • 可视化JL701M_DONGLE_SDK添加MIC为发射源
  • 可视化JL701M_DONGLE_SDK添加按键切换usb audio与MIC发射源
  • JL701M_DONGLE_SDK_1.0.0_dongle输入linein输出dac
  • 701可视化_a2dp_to_le_demo说明
  • 耳机系列demo汇总
  • JL7018F&JL7006F_7003F AUX IIS
  • 一键连接应用
  • 普通SDK动态开关一拖二功能
  • 蓝牙分析仪(EllisysBluetoothAnalyzer)抓包例程
  • TWS配对常见应用
  • APP自定义按键的demo
  • AC700N 播歌双EQ DEMO示例及说明
  • AC698V164 MIC与蓝牙音乐共同输出DAC demo
  • 添加第三方算法以及多算法授权流程
  • 空间音频配置方法
  • 普通高低电平TWS耳机控制通讯
  • 入耳检测状态更新demo解析
  • 资源优化(非可视化的SDK)
  • 资源优化(可视化SDK)
  • 翻译耳机、语音识别应用demo
  • 耳机抗干扰问题排查和优化
  • AC698D2 抗干扰优化
  • AC696X软件问题整理
  • AC695X软件问题整理
  • AC695X软件问题整理_1722249702
  • AC608X软件问题整理
  • JL701N_2T1_DUPLEX 应用软件问题汇总
  • le_audio_1.0.0_patch05 以及之前的版本IRkey 功能异常修改
  • AC706N-le_audio-200SDK有线_无线麦录音demo
  • jl701n_le_audio_v200patch02 IO串口升级修改串口单次发送字节长度的修改办法
  • 703创建IIS 输入dac输出音频流demo
  • 703将媒体流音频同时上传PC_mic录音demo实现
  • 703四路IIS输入输出demo
  • 底噪调试
  • AW328A烧录说明
  • 文档合集
  • AC706N_wireless_mic_release_PATCH_20240712 补丁 说明
  • AC706N_wireless_mic_release_PATCH_20240726 补丁 说明
  • AC706N_wireless_mic_release_V1.0.0、1.0.1、1.0.2 补丁 说明
  • AC706N_wireless_mic_release_V1.1.2 中的2T1应用 RX端不绑定配对,TX端实现绑定配对的修改方法
  • 各系列省晶振实现方法
  • iis tx rx说明文档
  • spdif信号
  • 蓝牙电话本
  • 安卓手机同步时间补丁
  • CDC配置
  • PC模式下增加Teams唤起功能
  • 杰理HDMIARC开发实现过程
  • AC701N patch06之前的版本用第三方算法节点实现新版本的pcm delay节点功能
  • (K歌音箱)各SDK音效配置相关说明
  • 长文件录音
  • 点阵屏歌词字库相关(蓝牙歌词,普通歌词)
  • 字模提取工具说明
  • 音箱可视化彩屏-入门到进阶开发指导
  • 彩屏LVGL UI设计及工具使用
  • 使用内部UI框架进行UI调试的系列步骤
  • AD101C使用强制升级工具spi 烧录不了问题处理(测试版本)
  • AD161扩展灯板说明文档
  • 歌词显示器开发注意项
  • 使用硬件数字增益控制通话下行音量(可视化)
  • 杰理小牛产测资料
  • ENC配置说明
  • 通话调试流程指引
  • ANC相关功能demo
  • 无线麦硬件资料汇总
  • 无线麦相关应用
  • 无线麦复杂功能补丁包汇总
  • 无线话筒形态SDK程序&开发经验&问题点分享
  • 双模式结合应用问题汇总
  • 无线麦距离优化案例
  • 无线麦系列中的双工形态(duplex)演变开发对讲机方案开发资料
  • 音箱入门到进阶指导文档(编写中)
  • 蓝牙耳机品控和生产技巧
  • 982过_欠压标志获取异常
  • 如何获取最新涂鸦SDK及库文件
  • 无线话筒K歌音响-调音标准流程
  • 无线话筒产测流程

内部FLASH空间添加用户自定义区域

📎 原始文档:https://www.kdocs.cn/l/cvVDkgDEyHZO 内部FLASH空间添加用户自定义区域

内部FLASH空间添加用户自定义区域

参考资料: 添加用户自定义区域 :https://kdocs.cn/l/cszLZSN40zWI
补充说明如下:

  1. 修改 isd_config.ini 文件, 配置 user_info 区域大小和名称 注意:有些SDK是修改isd_config_rule.c,编译的时候由isd_config_rule.c去生成isd_config.ini 注意修改的位置
    image isd_config.ini 修改如下:
USER_ADR=AUTO;

USER_LEN=0x1000;

USER_OPT=1;

添加 user 存储区域描述, 名称为”USER”。需要跟程序上的fopen对应。如下图。
USER_ADR=AUTO; 表示地址由工具自动分配, 默认即可, 用户不需要修改;
USER_LEN=0x1000; 表示区域大小, 用户可以根据需求配置;
USER_OPT=1; 表示下载代码时对该区域的操作, 用户一般不需要修改;
image 2. 修改 sdk_ld 文件中的链接地址 imageimage - 如果是0x1E00020的话,就改成0x1E00040 3. 添加 user_info_demo.c 文件中的代码测试 相关接口:读写接口跟文件系统接口一致,但由于flash的特性需要写之前需要自己去管理擦除user_info区域。

//打开文件

fp = fopen("mnt/sdfile/app/user", "wr"); //字符: mnt/sdfile/app/ 固定; 字符user对应ini文件里配置的名称



//文件偏移

fseek(user_fp, -wbuf_len, SEEK_CUR); //把文件指针移到刚写的位置

//把buf写入区域

ret = fwrite(user_fp, wbuf, wbuf_len);

//读出写入buf内容

fread(user_fp, rbuf, rbuf_len);



//擦除区域操作(物理地址)

 norflash_ioctl(NULL, erase_cmd, erase_addr);
 #if 1//for test

        FILE *user_fp;     //区域读写句柄
        struct vfs_attr attr = {0}; //user_info区域属性, sclust: 区域地址, fsize: 区域大小
        extern FILE *user_info_zone_init(struct vfs_attr *attr);
        user_fp = user_info_zone_init(&attr);
        int ret = 0;     //区域操作返回值

        u8 r_test_buf[80] = {0};
        u8 test_buf[32] = {0};//test buffer
        for(int i=0;i<sizeof(test_buf);i++) {
            test_buf[i]=i;//给数组赋值
        }
        while(1)
        {
            os_time_dly(100);

            //写 从起始地址开始写
            ret = fwrite(user_fp, test_buf, sizeof(test_buf));
            printf("write len = %d\r\n",ret);
            if(ret != sizeof(test_buf)) {
                printf("write err\r\n");
                printf("earse all\r\n");
                user_info_zone_earse(user_fp, &attr);

            }

            // 读出刚才写入的内容, 检查是否写入正确;
            fseek(user_fp, -sizeof(test_buf), SEEK_CUR); //把文件指针移到刚写的位置
            ret = fread(user_fp, r_test_buf, sizeof(test_buf));//读32个字节
            if(ret != sizeof(test_buf)) {
                printf("read err\r\n");
            }
            put_buf(r_test_buf,sizeof(r_test_buf));


        }
    #endif
  1. 自定义区域保存音频文件,并播放出来demo 测试代码:
  • 添加从提示音资源区copy文件到自定义区接口
int user_copy_file(const char *src_file_name,const char *dest_file_name){
    FILE *src_file = NULL;
    FILE *dest_file = NULL;
    char buff[100];
    int ret;


    src_file=fopen(src_file_name,"rb");
    if(!src_file)return -1;

    dest_file=fopen(dest_file_name,"wb");
    if(!dest_file)return -1;

    struct vfs_attr attr;
    ret=fget_attrs(src_file,&attr);
    g_printf("ret -- %d fsize=%d\r\n",ret,attr.fsize);

    do{
        ret=fread(src_file,buff,sizeof(buff));
        r_printf("read file ret=%d\r\n",ret);
        if(ret>0)fwrite(dest_file,buff,ret);
    }while(ret>0);

    fclose(src_file);
    fclose(dest_file);
    return 0;
}
  • 初始化调用添加接口
    //提示音写入 user_info
    //ini RESERVED_CONFIG 区路径 "mnt/sdfile/app/"
    //ini RESERVED_EXPAND_CONFIG 区路径 ""mnt/sdfile/EXT_RESERVED/"
    int uret=user_copy_file("mnt/sdfile/res/tone/0.wtg","mnt/sdfile/app/user");
  • 播放自定义接口中保存的提示音
//ini RESERVED_CONFIG 区路径 "mnt/sdfile/app/"
//ini RESERVED_EXPAND_CONFIG 区路径 ""mnt/sdfile/EXT_RESERVED/"
tone_play_by_path("mnt/sdfile/app/user", 0);
  • ini文件配置为下载程序时擦除USER区域
[RESERVED_CONFIG]
USER0_ADR=AUTO;
USER0_LEN=0xf000;
USER0_OPT=0;

[RESERVED_EXPAND_CONFIG]
USER1_ADR=AUTO;
USER1_LEN=0xf000;
USER1_OPT=0;
  • 如果需要换提示音需要擦除一遍该区域再进行更改数据,参考内部FLASH空间添加用户自定义区域
  • DEMO:

696:下载、 内部

695:下载、 内部 (下载代码之后需要换库修复进music死机问题)

  1. 703soundbox 200P01 SDK 内部flash读写参考代码 测试SDK版本:
    image 参考代码包括:
  • 文件目录的初始化
  • 文件的创建 image
  1. 703soundbox 200P02 SDK 内部flash读写参考代码
  2. demo cfg_private.c
    image
  3. 注意点:
    1. 接口说明 /**
  • 此cfg_private_write接口有如下问题:
    1. 使用resfile_seek接口偏移后resfile_get_pos获取到的值不正确,在改写数据时达不到想要的效果
      */
/**
 * 此cfg_private_write接口有如下问题:
 * 1. 使用resfile_seek接口偏移后resfile_get_pos获取到的值不正确,在改写数据时达不到想要的效果
 */
int cfg_private_write(RESFILE *file, void *buf, u32 len)
{
    struct resfile_attrs attrs = {0};
    //获取当前资源文件的属性信息
    resfile_get_attrs(file, &attrs);
    /* r_printf(">>>[test]:attrs.sclust = 0x%x\n", attrs.sclust); */
    //地址映射 cpu addr  -> flash addr
    attrs.sclust = sdfile_cpu_addr2flash_addr(attrs.sclust);
    //获取当前资源文件读写指针位置
    u32 fptr = resfile_get_pos(file);
    /* r_printf(">>>[test]:addr = 0x%x, fsize = %d, fptr = %d, w_len = %d\n", attrs.sclust, attrs.fsize, fptr, len); */
    if (len + fptr > attrs.fsize) {
        r_printf(">>>[test]:error, write over!!!!!!!!\n");
        return -1;
    }
    char *buf_temp = (char *)malloc(cp_hdl->cfg_private_align_size);
    int res = len;


    for (int wlen = 0; len > 0;) {
        //计算写地址对应的flash对齐块地址
        u32 align_addr = (attrs.sclust + fptr) / cp_hdl->cfg_private_align_size * cp_hdl->cfg_private_align_size;
        //计算块内偏移地址
        u32 w_pos = attrs.sclust + fptr - align_addr;
        //计算写数据的长度
        wlen = cp_hdl->cfg_private_align_size - w_pos;
        /* y_printf(">>>[test]:wpos = %d, wlen = %d\n", w_pos, wlen); */
        //判断块数据长度大于写的数据长度,如果小于需要再次写一个块单位的数据
        if (wlen > len) {
            wlen = len;
        }
        //判断数据是否需要擦除
        norflash_read(NULL, (void *)buf_temp, cp_hdl->cfg_private_align_size, align_addr);
        if (0 == cfg_private_check(buf_temp, cp_hdl->cfg_private_align_size)) {
            cfg_private_erase(align_addr, cp_hdl->cfg_private_align_size);
        }
        //把需要些的数据复制到文件最后
        memcpy(buf_temp + w_pos, buf, wlen);
        /* put_buf(buf_temp, cp_hdl->cfg_private_align_size); */
        //写一个块单位的数据
        norflash_write(NULL, (void *)buf_temp, cp_hdl->cfg_private_align_size, align_addr);
        fptr += wlen;
        len -= wlen;
    }
__exit:
    //是否临时申请到的内存
    free(buf_temp);
    //文件偏移到末尾
    resfile_seek(file, fptr, SEEK_SET);
    return res;
}
2. 参考修改(未经过测试)
int cfg_private_write(RESFILE *file,u32 offset, void *buf, u32 len)
{
    struct resfile_attrs attrs = {0};
    //获取当前资源文件的属性信息
    resfile_get_attrs(file, &attrs);
    /* r_printf(">>>[test]:attrs.sclust = 0x%x\n", attrs.sclust); */
    //地址映射 cpu addr  -> flash addr
    attrs.sclust = sdfile_cpu_addr2flash_addr(attrs.sclust);
    //获取当前资源文件读写指针位置
    u32 fptr = resfile_get_pos(file);
    //error
    if(offset>fptr)return -1;
    if(offset && offset<fptr)fptr=offset;
    
    /* r_printf(">>>[test]:addr = 0x%x, fsize = %d, fptr = %d, w_len = %d\n", attrs.sclust, attrs.fsize, fptr, len); */
    if (len + fptr > attrs.fsize) {
        r_printf(">>>[test]:error, write over!!!!!!!!\n");
        return -1;
    }
    char *buf_temp = (char *)malloc(cp_hdl->cfg_private_align_size);
    int res = len;

    for (int wlen = 0; len > 0;) {
        //计算写地址对应的flash对齐块地址
        u32 align_addr = (attrs.sclust + fptr) / cp_hdl->cfg_private_align_size * cp_hdl->cfg_private_align_size;
        //计算块内偏移地址
        u32 w_pos = attrs.sclust + fptr - align_addr;
        //计算写数据的长度
        wlen = cp_hdl->cfg_private_align_size - w_pos;
        /* y_printf(">>>[test]:wpos = %d, wlen = %d\n", w_pos, wlen); */
        //判断块数据长度大于写的数据长度,如果小于需要再次写一个块单位的数据
        if (wlen > len) {
            wlen = len;
        }
        //判断数据是否需要擦除
        norflash_read(NULL, (void *)buf_temp, cp_hdl->cfg_private_align_size, align_addr);
        if (0 == cfg_private_check(buf_temp, cp_hdl->cfg_private_align_size)) {
            cfg_private_erase(align_addr, cp_hdl->cfg_private_align_size);
        }
        //把需要些的数据复制到文件最后
        memcpy(buf_temp + w_pos, buf, wlen);
        /* put_buf(buf_temp, cp_hdl->cfg_private_align_size); */
        //写一个块单位的数据
        norflash_write(NULL, (void *)buf_temp, cp_hdl->cfg_private_align_size, align_addr);
        fptr += wlen;
        len -= wlen;
    }
__exit:
    //是否临时申请到的内存
    free(buf_temp);
    //文件偏移到末尾
    resfile_seek(file, fptr, SEEK_SET);
    return res;
}
  1. AC210N_le_audio_1.3.1 内部flash自定义区的读写 AC210N音箱问题整理.otl

注:

1. FLASH的对齐方式可以从code block的编译输出信息中看到(256Bytes对齐、4K对齐),如下图:

image

b.4K对齐的FLASH如果使用page擦除,会导致擦除的sector出现不可预知的错误,所以操作FLASH的时候请考虑操作的规范性

image

本文档包含以下子页面

Prev
SPI
Next
IIC