2018年4月26日 星期四

[轉] Strong Symbol and Weak Symbol(強型別和弱型別)

http://swaywang.blogspot.tw/2011/10/strong-symbol-and-weak-symbol.html


Strong Symbol and Weak Symbol(強型別和弱型別)

Compiler會把已經初始化的Global varible當作Strong Symbol
未初始化的Global varible為Weak Symbol
我們可以使用GCC提供的 "__attribute__((weak))"
來定義任意一個Strong Symbol為Weak Symbol
以下是一個例子:
extern int ext;

int weak;
int strong = 1;
__attribute__((weak)) weak2 = 2;

int main(){
    return 0;
}

在這個例子中weak和weak2都是Weak Symbol
strong和main是Strong Symbol
ext不是Strong也不是Weak,因為他是一個外部變數

Compiler會按照下列規則處理Strong以及Weak Symbol

Rule1: Strong Symbol不能在不同的Obj檔被多次定義
       這就是我們常常看到的重複定義錯誤

Rule2: 如果一個Symbol在某個檔案是Strong,在其他檔案都是Weak
       Compiler會選擇Strong Symbol

Rule3: 如果一個Symbol在每個檔案都是Weak,會選擇最大的Type
       比如說一個同樣名稱的int和double global varible
       Compiler在Link的時候會選擇double

外部符號的Reference也有分兩種

Strong Reference:  在Link時找不到符號定義會回報錯誤
Weak Reference:   在Link時找不到符號定義不會回報錯誤,通常會預設為0

下面是GCC把foo()宣告成weak reference的擴充keyword
__attribute__((weakref)) void foo();

int main()
{
    foo();
}
上面這段code可以編譯成執行檔且不會產生錯誤

但是我們執行程式的話,因為沒有定義foo(),foo的位置為0
因此會發生不合法的位置存取錯誤

Weak Symbol和 Weak Reference對函式庫的設計非常有用
函式庫可以定義一些Weak Symbol的函式
使用者可以自己定義一些Strong Symbol達到擴充功能
因為Strong Symbol會蓋掉Weak Symobl

我們也可以透過Weak Reference使用一些擴充功能
以後就算我們把擴充功能去掉,程式還是可以正常Link

2018年2月25日 星期日

[轉] tera term的ttl常用指令


a.通過Tera Term連接PFC所在的機器以及斷開連接
通過TTLconnect/disconnect命令實現
Connect
connect '192.168.137.27 /ssh /auth=password /user=username /passwd= passwd'
注:其中username是用戶名,passwd是密碼
Disconnect
disconnect   
注:disconnect後面指定參數,這樣就不彈出確認框了。

connect '/c=3 /baud=115200'
; C=3 是com port3 ,baud rate =115200

b.通過log記錄全程操作過程,最終通過比對log確認測試結果。
通過logopen/logclose命令來寫log
logopen
logopen filename 0 1 1
注:filename最好設成命令名,不通ttl腳本不要重複。也可以帶執行的時間,
例如:Show_candidate_config_  20110426-130939.log
    方法如下:
gettime timestr "%Y%m%d-%H%M%S"
getdir mdir
sprintf2 filename '%s\ Show_candidate_config _%s.log' mdir  timestr
logclose 
           logclose

    

c.測試項作成時可能用到的命令
Pause:(暫停)
 pause <time> Remarks Pauses for <time> seconds. 


Sendln:(發送命令並換行)
sendln <data1> <data2>....
Remarks Causes Tera Term to send characters followed by a new-line character to the host.     
        

Send :(發送命令)
send <data1> <data2>....
Remarks Causes Tera Term to send characters to the host.
If <data> is a string, the string is sent to the host. 
If <data> is an integer, its lowest-order byte (0-255) is regarded as an ASCII code of the character, and the character is sent to the host.         例如:按Tab 鍵的命令是send  #9           


wait等待匹配的字符串出現)  
wait <string1> [<string2> ...]
Remarks Pauses until one of the character strings is received from the host, or until the timeout occurs. Maximum number of the strings is 10. 
     注:使用這個命令是需要設置timeout 時間,命令的返回結果保存在resault 變量中,resault 時,則為超時。Timeout 設置命令如下:
          timeout=1   /* 等號後面的值為整數,設為負則是無限等待*


waitln等待整行匹配的字符串出現)         
waitln <string1> [<string2> ...]
Remarks Pauses until a line which contains one of the character strings is received from the host, or until the timeout occurs. Maximum number of the strings is 10.     
注意點同上     其他命令例如if,then,elseif,else,endif,goto 等請參考help 文件。 



腳本製作注意
a.    不同的ttl 腳本內指定的Log 文件名​​不能重複。
b.    腳本的最後部分請清空測試環境,以便下一個ttl 腳本執行。
c.    在執行比較緩慢的地方,例如連接機器時,請追加pause 命令
d.    腳本盡量寫得簡潔短小,以便式樣發生變更時易於更改。
e.    必要的時候可以追加註釋


例子:
1,window 下創建bat文件
"C:\Program Files\teraterm\ttpmacro.exe" "D:\My Kownhow\TTL\test.ttl"
exit
2,生產ttl腳本文件test.ttl
;###connect host
connect '172.28.92.23 /ssh /auth=password /user=root /passwd=password'
pause 1
;###create log
gettime logstr "log-%Y%m%d-%H%M%S.txt"
getdir curdir
sprintf '%s\%s' curdir logstr
filename = inputstr
logopen filename 0 1 1
logwrite 'Log start'#13#10
looptimes = 1 ;
while looptimes < 11
 ;###run cmd 
 sendln "ls -l"
 wait "#"
looptimes = looptimes + 1
endwhile
;###closelog
Logclose
;###disconnect
disconnect
closett
執行bat文件就可以運行ttl腳本.

2018年1月23日 星期二

 如果沒有build server root 權限且缺少執行檔, 可以直接用下面方法產生執行檔

export PKG_CONFIG_PATH=<your local installation path>/lib/pkgconfig
autoreconf -f -i
./configure –prefix=<your local installation path>
make
make install
     export PATH=[execution file path]:$PATH

2017年12月22日 星期五

GCC: the --start-group and --end-group command line options

https://stackoverflow.com/questions/5651869/gcc-what-are-the-start-group-and-end-group-command-line-options

https://linux.die.net/man/1/ld

-( archives -) or --start-group archives --end-group
The archives should be a list of archive files. They may be either explicit file names, or -l options.
The specified archives are searched repeatedly until no new undefined references are created. Normally, an archive is searched only once in the order that it is specified on the command line. If a symbol in that archive is needed to resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference. By grouping the archives, they all be searched repeatedly until all possible references are resolved.
Using this option has a significant performance cost. It is best to use it only when there are unavoidable circular references between two or more archives.

2017年12月11日 星期一

[轉] [C/C++] 靜態函式 (static function) 2011

static function is a function whose scope is limited to the current source file.  Scope refers to the visibility of a function or variable. If the function or variable is visible outside of the current source file, it is said to have global, or externalscope. If the function or variable is not visible outside of the current source file, it is said to have local, or static scope.
意思是說靜態函式只能被該檔案所看見,其它檔案無法得知該檔案是否有其靜態函式。
有一些 C 的語法,在 C++ 的程序員相對少用。但就是因為這個原因,有時就會忽略了。
假設我們有一個Header檔 Foo.h
static void f1(){
cout << “f1()" << endl;
}
void f2(){
cout << “f2()" << endl;
}
f1 和 f2 的差別在於 static 這個 keyword 。在這裡的 f1 被宣告和定義為 static ,是指它只在這個 Compilation Unit 中生效。而 f2 沒有被定義為 static ,亦即是它可以被其他 Compilation Unit 訪問。
但到底什麼是 Compilation Unit 呢?首先,一個程式編譯過程如下:
compliation_process這裡的 a.cpp , b.cpp 和 c.cpp 也 引入了 Foo.h 這個檔案,經過前處理器後,Foo.h 的內容會被加入到 a.cpp, b.cpp 和 c.cpp 中,再經過編譯器,變成為 a.o , b.o 和 c.o 這些目的碼,最後經過連結器,變成執行檔
要留意的地方是,每個經過前處理器處理後的.cpp 檔,和它的目的檔是一一對應的,而Compilation Unit,就是這些被處理後的.cpp 檔了。
若以Foo.h 的 f1 為例子,雖然在每個 .cpp 檔也被定義了,但經過編譯後,所有的f1 也會被隱藏在自己的目的檔中,連結器在找尋symbol的過程中,是會忽略的。
但f2 就不同了,所有的f2 在目的檔中,也是不會被隱藏,所以在連結器找尋symbol,會找到多份的f2,那連結就會有錯誤了。
所以在大部份的情況下,在Header檔中定義函數,也是需要 static 這個 keyword 的。就算加上了 inline,情況也是一樣的。
static inline void f3(){
cout << “f3()" << endl;
}