前言
開發了一款debug不同芯片的類link工具,不同芯片的具體實作有不同的人員開發實作,那么就有可能出現不同人員修改一份代碼的問題,極有可能會導致出現問題,為此采用一種新的方式,將指定的操作放在同一個段內,這樣link底層的實作和業務邏輯的實作就徹底的分割出來,
舊的實作
首先需要在業務邏輯里面實作相應的處理函式,例如下面的代碼,
void xx1_ops(void) {
...
}
void xx2_ops(void) {
...
}
然后在具體的呼叫函式里通過chip->name來區分不同芯片,然后執行對應的函式
void run(void) {
switch (chip->name) {
case xx1:
xx1_ops();
break;
case xx2:
xx2_ops();
break;
default:
braek;
}
}
這樣的方式在開發人員少的時候很合適,方便,但是人員多了以后,芯片種類多了以后,沒添加一個芯片就會修改run函式里面的內容,就可能會出現不確定的錯誤,所以需要采用更合適的方式,
新的實作
原理:最主要的就是要找到業務邏輯的函式入口,所以把所有函式入口放在統一的記憶體段中,run函式里面就從頭到尾遍歷,拿出要執行的是哪一個函式入口,這樣run里面并不確定有哪些芯片,而業務邏輯也不需要修改run函式,從而很好的實作了隔離,
下面是在keil中實作的代碼,在gcc環境下基本類似,只是段的定義和段首,段尾地址需要在ld檔案中顯示說明,
struct chip {
char name[8];
int ops;
};
#define SECTION __attribute__((used)) __attribute__((section("Chip")))
#define ADD_OPS(name,ops) \
SECTION const struct chip __chip_ops_##name = { \
#name,ops, \
} \
extern unsigned int Chip$$Base;
extern unsigned int Chip$$Limit;
struct chip * v;
for (v = (struct chip *)&(Chip$$Base);v < (struct chip *)&(Chip$$Limit)
;v++) {
LOG("%s\n",v->name);
}
上面SECTION的意思是告訴編譯器這個變數我會使用,讓編譯器不要優化,同時把該變數放置在Chip段內,而Chip$$Base是該記憶體的首地址,Chip$$Limit是尾地址,通過遍歷該段地址可實作查找指定函式入口的功能,
而在業務邏輯上,不需要關心link的底層實作,專注于實作邏輯后,使用下面的宏傳遞函式入口即可,
SC_ADD_CHIP(xxx,12);
本文來自博客園,作者:Air-Liu,轉載請注明原文鏈接:https://www.cnblogs.com/ghost-98210/p/15777666.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/412788.html
標籤:嵌入式
