Lichee (五) sysconfig1.fex 配置系统

sysconfig配置系统,作为一个通用的软件平台,还希望通过它,可以适应用户不同的方案。通过给出一个对应的配置,用户的方案就可以自动运行,而不需要修改系统里面的代码,或者重新给出参数。 


一、 sysconfig1.fex简述

配置脚本的本意是给系统传递参数。作为一个稳定的系统,本身应该和方案无关, 不管不同方案的差别有多大,系统都不应该重新编译才能运行。这里所说的系统,不单单指操作系统,也包括其中的驱动,模块,等等。 
不同方案的差别,通常体现在:
1) 使用的硬件模块不同,比如使用了不同的NAND FLASH,RTC模块,等等。
2) 相同模块使用的参数不同,其中包括GPIO不同,比如卡检测脚不同,SPI的引
脚不同,等等;包括执行的频率不同,如DRAM的频率,CPU的频率,等等。
3) 走线的方式不同。
4) 没有列举出的差别。
通常说来,上面列举的方案差别中,(3)和(4)对于一个系统来说没有任何差别,只
有(1)和(2),才可能导致一个系统需要重新编译。

例如:
[uart_para0]
uart_used = 1
uart_port = 0
uart_type = 2
uart_tx = port:PB22<2><1><default><default>
uart_rx = port:PB23<2><1><default><default>

uart_para0是主键 uart_used uart_port uart_type uart_tx uart_rx 分别是uart_para0的子键,而uart_tx uart_rx对应着A10的GPIO

; 说明: 脚本中的字符串区分大小写,用户可以修改"="后面的数值,但是不要修改前面的字符串
; 描述gpio的形式:Port:端口+组内序号<功能分配><内部电阻状态><驱动能力><输出电平状态>

这是一种典型的管理配置的方式,简单地归纳特点如下
1) 配置独立于代码,用文件的方式存储、可读写
2) 集中管理,具有一定的规范,多种模块遵循同一种配置规则
3) 有专门一套代码去管理配置,读取相应的配置提供给程序

二、 解析过程思路


 PC端配置数据的生成

配置脚本本质上是PC端的一个文本文件,通过一个固定的格式形成可以被我们使用的文件,里面保存了大量的配置信息。在图一中,可以看到,PC端的一个数据文件如何变成了小机端可以用到的文件。




 


图一 小机端配置文件生成

图一中可以看出,当用户生成一个配置文件之后,不需要做额外的操作,只要按照正常的打包,烧写过程,配置文件的数据就自动被嵌入到boot相关的数据中了。



3.2 系统启动的数据传递

在小机端,系统启动之后存在数据传递的过程,这个过程主要是数据从boot中读出,然后存放到操作系统指定的位置。然后操作系统可以自己搬移这块数据,或者直接使用这块和配置有关的数据。相关的处理过程可以参见图二。

 


图二 配置系统在系统中的流程


从图二中可以看出,boot阶段把数据从boot1.bin中读出,然后传递给了操作系统。操作系统拿到数据之后,做一次初始化动作,然后就一直等待用户进行操作。当系统关机的时候,操作系统需要调用一次配置管理的退出函数,然后,整个配置系统的运行就结束。

3.3 用户调用配置系统的数据传递

当用户调用配置系统的时候,里面存在数据传递。图三表示了用户的数据如何传递到系统,以及系统如何做出相应的。



 

 

 

图三  配置系统使用中数据传递流程

通过图三,用户可以看出,当调用配置相关的函数的时候,系统中以及配置管理模块如何管理用户传入的数据。



三、 关键函数分析


在系统中,提供了如下的几个函数,提供给用户在系统中读取配置信息的数据。

函数原型: int Script_parser_fetch(char *main_name, char *sub_name, int value[], int count);

参数:main_name 主键名称,即配置脚本中的主键名称,字符串形式

      sub_name  子键名称,配置脚本中的子键名称,字符串形式

      value      数据指针,用于存放用户获取的数据

      count      用户传进的数据空间的最大word个数

返回值:        成功返回0

                失败返回-1

 

 

这个函数的功能很强大,可以获取配置脚本中任意一项的值。

比如,用户需要获取配置脚本中,主键target下的子键boot_clock的值,可以写成

 

{

    int  value;

    int  ret;

 

    ret = Script_parser_fetch(“target”, “boot_clock”, &value, 1);

    if(ret < 0)

        printf(“fetch script data fail\n”);

else

    printf(“fetch script data ok, value = %d\n”, value);

 

return ret;

}


在这个函数中,获取到的值存放在整型变量value中,正常情况下,函数调用的结果是 value = 406

如果要获取一个配置的GPIO信息,比如twi_paratwi_scl可以使用如下的形式

{

    user_gpio_set_t  gpio_info[1];

    int  ret;

 

    ret = Script_parser_fetch(“twi_para”, “twi_scl”, gpio_info, sizeof(user_gpio_set_t)/sizeof(int));

    if(ret < 0)

        printf(“fetch script gpio infomation fail\n”);

else

    printf(“fetch script gpio infomation ok \n”);

 

return ret;

}


这个函数将把获取到的GPIO信息存放到结构体gpio_info中。用户可以使用这个结果,来调用GPIO管理模块提供的函数。

用户也可以使用脚本函数来获取一个字符串。

比如,存在如下的一个主键和子键项目

[string_test]

string_demo = string:abcdefghijklmn

现在,可以用这个函数来获取出主键string_test的子键string_demo的值。正常情况下,调用如下的函数之后,string_info中保存的值将是“abcdefghijklmn(没有引号)

  

{

    char  string_info[128];

    int  ret;

 

    memset(string_info, 0, 128);

    ret = Script_parser_fetch(“string_test”, “string_demo”, string_info, 128/sizeof(int));

    if(ret < 0)

        printf(“fetch script string infomation fail\n”);

else

    printf(“fetch script string infomation ok \n”);

 

return ret;

}



 获取子键个数

函数原型:int  Script_parser_subkey_count(char *main_name);

参数:      main_name 主键名称,即配置脚本中的主键名称,字符串形式

 

返回值:  成功返回 主键下的子键个数

          失败返回 -1


这个函数返回的是一个主键下所有的子键的个数,通常用户不会关心它。这个函数更大的用途还在于做检查。

 

{

    int  sub_key_count;

 

    sub_key_count = Script_parser_subkey_count (“target”);

    if(sub_key_count < 0)

        printf(“fetch script sub key count fail\n”);

else

    printf(“fetch script sub key count ok , sub_key_count = %d\n”, sub_key_count);

 

return sub_key_count;

}


 调用如上的函数,将获取到主键target下的所有子键的个数,即得到数值4

 


获取主键个数

函数原型:int Script_parser_mainkey_count(void);

 

参数:无

返回值:  成功返回 配置脚本中主键的总的个数

          失败返回 -1


这个函数将获取所有主键的个数,和Script_parser_subkey_count一样,主要用途还是做检查使用。

 

{

    int  main_key_count;

 

    main_key_count = Script_parser_mainkey_count();

    if(main_key_count < 0)

        printf(“fetch script sub key count fail\n”);

else

    printf(“fetch script main key count ok , main_key_count = %d\n”, main_key_count);

 

return main_key_count;

}


 调用如上的函数,将获取到配置脚本中主键的个数。

函数原型:int Script_parser_mainkey_get_gpio_count(char *main_name);

 

参数:main_name  配置脚本中主键的名称,字符串形式

返回值:  成功返回 配置脚本中主键下的,数据GPIO类型的子键个数

          失败返回 -1



 获取主键下GPIO个数

 

这个函数的调用将得到主键下的子键中,值属于GPIO类型的子键个数。

比如,当获取twi_para下的子键中的GPIO类型时,将获取到数值2

 

{

    int  gpio_key_count;

 

    gpio_key_count = Script_parser_mainkey_get_gpio_count (“twi_para”);

    if(gpio_key_count < 0)

        printf(“fetch script sub key count fail\n”);

else

    printf(“fetch script gpio key count ok , gpio_key_count = %d\n”, gpio_key_count);

 

return gpio_key_count;

}


如果把上面函数的参数twi_para替换成target,则得到的将是0。如果把上面函数的参数twi_para替换成nand_para,则得到的将是23




 获取主键下GPIO配置

这个函数将获取一个主键下,所有属于GPIO的子键的GPIO描述值。

函数原型:int Script_parser_mainkey_get_gpio_cfg(char *main_name, void *gpio_cfg, int gpio_count);

参数:main_name 主键名称,即配置脚本中的主键名称,字符串形式

      gpio_cfg   用于存放GPIO信息的地址,应该是属于user_gpio_set_t的数据结构

      gpio_coumt 用户传进的结构体的个数

      返回值:   成功返回0

                 失败返回-1

 

 

调用这个函数,将把配置脚本中匹配主键名称的,属于GPIO类型的子键的个数。

 

{

    user_gpio_set_t  gpio_info[2];

    int  ret;

 

    ret = Script_parser_mainkey_get_gpio_cfg(“twi_para”,gpio_info, 2);

    if(ret < 0)

        printf(“fetch script gpio infomation fail\n”);

else

    printf(“fetch script gpio infomation ok \n”);

 

return ret;

}


调用这个函数,将获取配置脚本里,twi_para的子键中,属于GPIO类型的描述信息。


本文大致地将sysconfig1.fex简单介绍一下,主要是为了后面分析驱动的过程做准备,大部分SUN4I平台的驱动都是采用这种方式来管理配置的,我们不妨也用这种方式.






















<think>好的,我现在需要解决用户提到的无法打开文件amp_dsp0.fex的问题。首先,我应该回顾用户提供的引用内容,看看有没有相关的线索。用户提到了几个引用,其中引用[1]、[3]、[4]涉及类似的问题,比如无法打开boot-resource.fex、rootfs.fex等,这可能与全志平台的编译和打包过程有关。 首先,引用[2]提到sys_config.fex是全志平台的配置文件,类似于设备树,编译时会合并到dts中生成dtb。可能amp_dsp0.fex也是在类似的配置文件中被引用的。用户需要检查sys_config.fex或者sys_partition.fex是否有相关的配置项,确保文件路径正确,名称没有拼写错误。 然后,引用[4]提到修改sys_partition.fex中的分区大小来解决类似问题。可能amp_dsp0.fex在sys_partition.fex中被定义,需要检查该文件是否存在,或者在分区配置中是否正确指定了文件名。如果文件不存在,可能需要生成或从其他位置复制过来。 引用[3]提到使用pack时出现的问题,如rootfs.fex文件太大导致失败。这可能与文件大小或存储空间有关,但用户的问题是无法打开文件,所以更可能的原因是路径错误或文件缺失。需要确认amp_dsp0.fex是否存在于正确的路径下,比如在打包脚本指定的目录中。 接下来,用户可能需要检查编译过程中生成的文件路径,如引用[2]提到的lichee/out/sunXXXX/linux/common/.sunxi.dts,但这里可能更关注打包阶段。全志平台在打包时会根据sys_partition.fex中的配置来查找各个分区文件,如果某个文件不存在,就会报错。 可能的解决步骤包括: 1. 检查sys_partition.fex中的配置,确认amp_dsp0.fex是否被正确引用,文件名是否正确。 2. 确保amp_dsp0.fex文件存在于预期的路径下,通常是打包脚本的工作目录或指定的资源目录。 3. 如果文件缺失,可能需要从源码或其他地方获取该文件,或者检查是否有生成该文件的步骤被遗漏。 4. 检查编译日志,查看具体在哪个阶段报错,确定是生成文件的问题还是路径配置错误。 5. 如果文件路径正确但依然报错,可能需要调整分区的起始地址或大小,避免与其他分区重叠,如引用[4]中调整boot-resource.fex的大小。 此外,用户提到的引用[5]是关于摄像头驱动的路径,可能与当前问题无关,但如果有其他硬件配置问题,可能需要检查相关模块的配置。 最后,需要确保整个编译环境配置正确,包括工具链和依赖库,避免因环境问题导致文件生成失败。如果用户按照这些步骤排查,应该能解决无法打开amp_dsp0.fex的问题。</think>针对无法打开文件$amp\_dsp0.fex$的问题,以下是分步解决方案: ### 1. 验证文件路径与配置 - **检查$sys\_partition.fex$配置** 打开设备配置文件$sys\_partition.fex$(路径如$device/config/chips/t113/configs/evb1\_auto/longan/sys\_partition.fex$),确认$amp\_dsp0.fex$的引用路径是否正确。典型配置段如下: ```ini [partition] name = amp_dsp0 size = 2048 downloadfile = "amp_dsp0.fex" ``` 需保证$downloadfile$字段与实际文件名完全匹配[^4]。 - **确认文件物理存在性** 在编译环境中检查$amp\_dsp0.fex$是否存在于以下目录: - 打包工具默认资源目录(如$package\_dir$) - 项目自定义生成目录(如$out/sun8iw11p1/linux/common$) - 若文件缺失,需通过编译流程重新生成该文件或手动补全 ### 2. 调整分区参数 - **扩展分区容量限制** 若报错包含$dl\ file\ ...\ size\ too\ large$,需修改$sys\_partition.fex$中对应分区的$size$字段: ```ini [partition] name = amp_dsp0 size = 4096 # 原值加倍 ``` 该操作可避免因文件体积超出预设分区容量导致的加载失败[^3]。 - **校验分区地址冲突** 使用全志平台工具$pack$时,执行以下命令检查分区布局: ```bash ./pack -d ``` 输出日志中若显示$partition\ overlap$警告,需调整$start$字段的起始地址 ### 3. 环境与工具链验证 - **修复文件权限** 对$amp\_dsp0.fex$执行权限修正: ```bash chmod 644 amp_dsp0.fex ``` 避免因权限不足导致工具链无法读取 - **清理编译缓存** 执行深度清理后重新编译: ```bash ./build.sh clean ./build.sh -p sun8iw11p1 linux ``` 该操作可消除因中间文件残留引发的路径错乱[^1] ### 4. 特殊场景处理 - **动态生成文件场景** 若$amp\_dsp0.fex$应由脚本动态生成,检查: - 生成脚本执行权限(如$gen_amp_dsp.sh$) - 依赖工具链完整性(如全志专属$dsp\_packer$) - 日志中是否报错$Failed\ to\ generate\ amp\_dsp0.fex$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值