2018年8月5日 星期日

[轉] Makefile中的wildcard用法

在Makefile規則中,通配符會被自動展開。但在變量的定義和函數引用時,通配符將失效這種情況下如果需要通配符有效,就需要使用函數“wildcard,它的用法是:$(wildcard PATTERN...) 。在Makefile中,它被展開為已經存在的使用空格分開的匹配此模式的所有文件列表。如果不存在任何符合此模式的文件,函數會忽略模式字符並返回空。需要注意的是:這種情況下規則中通配符的展開和上一小節匹配通配符的區別。
一般我們可以使用$(wildcard *.c)”來獲取工作目錄下的所有的.c文件列表。複雜一些用法;可以使用“$(patsubst %.c,%.o,$(wildcard *.c))”,首先使用“wildcard”函數獲取工作目錄下的.c文件列表;之後將列表中所有文件名的後綴.c替換為.o。這樣我們就可以得到在當前目錄可生成的.o文件列表。因此在一個目錄下可以使用如下內容的Makefile來將工作目錄下的所有的.c文件進行編譯並最後連接成為一個可執行文件:

#sample Makefile
objects := $(patsubst %.c,%.o,$(wildcard *.c))

foo : $(objects)
cc -o foo $(objects)

這裡我們使用了make的隱含規則來編譯.c的源文件。對變量的賦值也用到了一個特殊的符號(:=)。

1、wildcard : 擴展通配符
2、notdir : 去除路徑
3、patsubst :替換通配符
例子:
建立一個測試目錄,在測試目錄下建立一個名為sub的子目錄
$ mkdir test
$ cd test
$ mkdir sub
在test下,建立a.c和b.c2個文件,在sub目錄下,建立sa.c和sb.c2 個文件
建立一個簡單的Makefile
src=$(wildcard *.c ./sub/*.c)
dir=$(notdir $(src))
obj=$(patsubst %.c,%.o,$(dir) )
all:
 @echo $(src)
 @echo $(dir)
 @echo $(obj)
 @echo "end"
 
執行結果分析:
第一行輸出:
a.c b.c ./sub/sa.c ./sub/sb.c
wildcard把 指定目錄 ./ 和 ./sub/ 下的所有後綴是c的文件全部展開。
第二行輸出:
a.c b.c sa.c sb.c
notdir把展開的文件去除掉路徑信息
第三行輸出:
a.o b.o sa.o sb.o
在$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的變量符合後綴是.c的全部替換成.o,任何輸出。
或者可以使用
obj=$(dir:%.c=%.o)
效果也是一樣的。
這裡用到makefile裡的替換引用規則,即用您指定的變量替換另一個變量。
它的標準格式是
$(var:a=b) 或 ${var:a=b}
它的含義是把變量var中的每一個值結尾用b替換掉a


今天在研究makefile時在網上看到一篇文章,介紹了使用函數wildcard得到指定目錄下所有的C語言源程序文件名的方法,這下好了,不用手工一個一個指定需要編譯的.c文件了,方法如下:
SRC = $(wildcard *.c)
等於指定編譯當前目錄下所有.c文件,如果還有子目錄,比如子目錄為inc,則再增加一個wildcard函數,像這樣:
SRC = $(wildcard *.c) $(wildcard inc/*.c)
也可以指定彙編源程序: 
ASRC = $(wildcard *.S)

2018年7月30日 星期一

[5j03] Passing Arrays as Function Arguments in C

https://www.tutorialspoint.com/cprogramming/c_passing_arrays_to_functions.htm

If you want to pass a single-dimension array as an argument in a function, you would have to declare a formal parameter in one of following three ways and all three declaration methods produce similar results because each tells the compiler that an integer pointer is going to be received. Similarly, you can pass multi-dimensional arrays as formal parameters.

Way-1

Formal parameters as a pointer −
void myFunction(int *param) {
   .
   .
   .
}

Way-2

Formal parameters as a sized array −
void myFunction(int param[10]) {
   .
   .
   .
}

Way-3

Formal parameters as an unsized array −
void myFunction(int param[]) {
   .
   .
   .
}

Example

Now, consider the following function, which takes an array as an argument along with another argument and based on the passed arguments, it returns the average of the numbers passed through the array as follows −
double getAverage(int arr[], int size) {

   int i;
   double avg;
   double sum = 0;

   for (i = 0; i < size; ++i) {
      sum += arr[i];
   }

   avg = sum / size;

   return avg;
}
Now, let us call the above function as follows −
#include <stdio.h>
 
/* function declaration */
double getAverage(int arr[], int size);

int main () {

   /* an int array with 5 elements */
   int balance[5] = {1000, 2, 3, 17, 50};
   double avg;

   /* pass pointer to the array as an argument */
   avg = getAverage( balance, 5 ) ;
 
   /* output the returned value */
   printf( "Average value is: %f ", avg );
    
   return 0;
}
When the above code is compiled together and executed, it produces the following result −
Average value is: 214.400000
As you can see, the length of the array doesn't matter as far as the function is concerned because C performs no bounds checking for formal parameters.

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