全志sysconfig.fex配置系统解析

sysconfig配置系统,作为一个全志平台通用的配置方案,希望通过它,能够适应用户不同的方案。通过给出一个相应的配置方案,用户就能够自己主动执行,而不须要改动系统里面的代码,或者重新配置參数。 

一、 sysconfig.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:PIN+组内序号<功能分配><内部电阻状态><驱动能力><输出电平状态>

这是一种典型的管理配置的方式,简单地归纳特点如下:

  1. 配置独立于代码之外,用文件的方式存储、可读写。
  2. 集中管理,具有一定的规范,多种模块遵循同一种配置规则。
  3. 有专门一套代码去管理配置,读取对应的配置提供给程序

二、 解析过程思路

  • PC端配置数据的生成

配置脚本本质上是PC端的一个文本文件,通过一个固定的格式形成能够被我们使用的文件,里面保存了大量的配置信息。在图一中,能够看到:PC端的一个配置文件怎样变成了设备端能够用到的文件。

图一 小机端配置文件生成

图一中能够看出,当用户生成一个配置文件之后,不须要做额外的操作,仅仅要依照正常的打包,烧写过程(全志平台上即操作:sudo ./build.sh pack 即可,生成镜像包之后下载到设备即可)。 配置文件的数据就自己主动被嵌入到boot相关的数据中了。

  • 系统启动的数据传递

在设备端,系统启动之后存在数据传递的过程,这个过程主要是数据uboot给出,然后存放到操作系统指定的位置。操作系统能够自己搬移这块数据,或者直接使用这块和配置有关的数据。相关的处理过程能够參见图二。

 图二 配置系统在系统中读取流程

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

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

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

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

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

三、 关键函数分析

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

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

參数:  main_name  主键名称,即配置脚本中的主键名称,字符串形式
       sub_name   子键名称。配置脚本中的子键名称。字符串形式
       value      数据指针,用于存放用户获取的数据
       count      用户传进的数据空间的最大word个数

返回值:           成功返回0
                  失败返回-1

这个函数的功能非常强大,能够获取配置脚本中随意一项的值(与Json函数库的使用方法类似)

比方,用户须要获取配置脚本中,主键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_para的twi_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下的全部子键的个数(整形值)

  • 获取主键个数
函数原型: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;
}

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

  • 获取主键下GPIO个数
函数原型:int script_parser_mainkey_get_gpio_count(char *main_name);

參数:    main_name   配置脚本中主键的名称。字符串形式
返回值:  成功返回     配置脚本中主键下的,数据GPIO类型的子键个数
         失败返回     -1

调用这个函数将得到主键下的子键中,属于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类型的描写叙述信息。

本文大致地将sysconfig.fex简介一下。主要是为了后面分析驱动过程做准备,大部分全志平台的驱动都是采用这样的方式来管理配置,我们最好还是也用这样的方式。

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值