1. 程式人生 > >Lichee (五) sysconfig1.fex 配置系統

Lichee (五) sysconfig1.fex 配置系統

sysconf ont 類型 函數的調用 nbsp 等待 use min-width mil

sysconfig配置系統,作為一個通用的軟件平臺,還希望通過它,可以適應用戶不同的方案。通過給出一個對應的配置,用戶的方案就可以自動運行,而不需要修改系統裏面的代碼,或者重新給出參數。


配置腳本的本意是給系統傳遞參數。作為一個穩定的系統,本身應該和方案無關, 不管不同方案的差別有多大,系統都不應該重新編譯才能運行。這裏所說的系統,不單單指操作系統,也包括其中的驅動,模塊,等等。

不同方案的差別,通常體現在: 1) 使用的硬件模塊不同,比如使用了不同的NAND FLASH,RTC模塊,等等。 2) 相同模塊使用的參數不同,其中包括GPIO不同,比如卡檢測腳不同,SPI的引 腳不同,等等;包括執行的頻率不同,如DRAM的頻率,CPU的頻率,等等。
3) 走線的方式不同。 4) 沒有列舉出的差別。 通常說來,上面列舉的方案差別中,(3)和(4)對於一個系統來說沒有任何差別,只 有(1)和(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) 有專門一套代碼去管理配置,讀取相應的配置提供給程序

端配置數據的生成

配置腳本本質上是端的一個文本文件,通過一個固定的格式形成可以被我們使用的文件,裏面保存了大量的配置信息。在圖一中,可以看到,端的一個數據文件如何變成了小機端可以用到的文件。



圖一 小機端配置文件生成

圖一中可以看出,當用戶生成一個配置文件之後,不需要做額外的操作,只要按照正常的打包,燒寫過程,配置文件的數據就自動被嵌入到相關的數據中了。



系統啟動的數據傳遞

在小機端,系統啟動之後存在數據傳遞的過程,這個過程主要是數據從中讀出,然後存放到操作系統指定的位置。然後操作系統可以自己搬移這塊數據,或者直接使用這塊和配置有關的數據。相關的處理過程可以參見圖二。

圖二配置系統在系統中的流程


從圖二中可以看出,階段把數據從中讀出,然後傳遞給了操作系統。操作系統拿到數據之後,做一次初始化動作,然後就一直等待用戶進行操作。當系統關機的時候,操作系統需要調用一次配置管理的退出函數,然後,整個配置系統的運行就結束。

用戶調用配置系統的數據傳遞

當用戶調用配置系統的時候,裏面存在數據傳遞。圖三表示了用戶的數據如何傳遞到系統,以及系統如何做出相應的。

圖三配置系統使用中數據傳遞流程

通過圖三,用戶可以看出,當調用配置相關的函數的時候,系統中以及配置管理模塊如何管理用戶傳入的數據。




在系統中,提供了如下的幾個函數,提供給用戶在系統中讀取配置信息的數據。

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

參數:主鍵名稱,即配置腳本中的主鍵名稱,字符串形式

子鍵名稱,配置腳本中的子鍵名稱,字符串形式

數據指針,用於存放用戶獲取的數據

用戶傳進的數據空間的最大個數

返回值:成功返回失敗返回-1

這個函數的功能很強大,可以獲取配置腳本中任意一項的值。

比如,用戶需要獲取配置腳本中,主鍵下的子鍵的值,可以寫成

int value;

int ret;

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

if(ret < 0)

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

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

return ret;

在這個函數中,獲取到的值存放在整型變量中,正常情況下,函數調用的結果是 value = 406

如果要獲取一個配置的信息,比如可以使用如下的形式

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”);

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

return ret;

這個函數將把獲取到的信息存放到結構體中。用戶可以使用這個結果,來調用管理模塊提供的函數。

用戶也可以使用腳本函數來獲取一個字符串。

比如,存在如下的一個主鍵和子鍵項目

現在,可以用這個函數來獲取出主鍵的子鍵的值。正常情況下,調用如下的函數之後,中保存的值將是“沒有引號

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”);

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

return ret;

獲取子鍵個數

函數原型:int Script_parser_subkey_count(char *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”);

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

return sub_key_count;

調用如上的函數,將獲取到主鍵下的所有子鍵的個數,即得到數值


獲取主鍵個數

函數原型:int Script_parser_mainkey_count(void);

參數:無

返回值:成功返回 配置腳本中主鍵的總的個數

失敗返回 -1


這個函數將獲取所有主鍵的個數,和一樣,主要用途還是做檢查使用。

int main_key_count;

main_key_count = Script_parser_mainkey_count();

if(main_key_count < 0)

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

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);

參數:配置腳本中主鍵的名稱,字符串形式

返回值:成功返回 配置腳本中主鍵下的,數據類型的子鍵個數

失敗返回 -1

獲取主鍵下個數

這個函數的調用將得到主鍵下的子鍵中,值屬於類型的子鍵個數。

比如,當獲取下的子鍵中的類型時,將獲取到數值

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”);

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

return gpio_key_count;

如果把上面函數的參數替換成,則得到的將是。如果把上面函數的參數替換成,則得到的將是

獲取主鍵下配置

這個函數將獲取一個主鍵下,所有屬於的子鍵的描述值。

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

參數:主鍵名稱,即配置腳本中的主鍵名稱,字符串形式

用於存放信息的地址,應該是屬於的數據結構

用戶傳進的結構體的個數

返回值:成功返回失敗返回-1

調用這個函數,將把配置腳本中匹配主鍵名稱的,屬於類型的子鍵的個數。

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”);

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

return ret;


調用這個函數,將獲取配置腳本裏,twi_para的子鍵中,屬於GPIO類型的描述信息。



本文大致地將sysconfig1.fex簡單介紹一下,主要是為了後面分析驅動的過程做準備,大部分SUN4I平臺的驅動都是采用這種方式來管理配置的,我們不妨也用這種方式.

Lichee (五) sysconfig1.fex 配置系統