在Linux下使用gcc編譯,
有幾個內建的變數可以非常好用,
在Debug的時候,
占非常重要的角色。
1. __BASE_FILE__
完整的原始檔案路徑
2. __cplusplus
表示該檔案由 g++ 所編譯,當成 C++ 的檔案
3. __DATE__
編譯的日期
4. __TIME__
編譯的時間
5. __FILE__
原始檔名
6. __LINE__
所在行數
7. __VERSION__
gcc 版本
8. __func__
替代 __FUNCTION__,__FUNCTION__ 已被 GNU 不推薦使用
參考資料:
LinuxC – gcc 預先定義的巨集
2014年5月21日 星期三
2014年5月9日 星期五
如何開啟windows 7的telnet與tftp
為了把image燒到測試的板子上面,
必需要用到tftp這一個指令。
而在windows 7預設是把telnet與tftp關掉。
如何把這兩個功能打開呢?
開啟控制台→程式集→開啟或關閉Windows功能
選擇「Telnet用戶端」與「TFTP用戶端」的選擇,
再按確定。
這樣就可以使用telnet與tftp了。
參考資料:
Win7 開啟 telnet and tftp
必需要用到tftp這一個指令。
而在windows 7預設是把telnet與tftp關掉。
如何把這兩個功能打開呢?
開啟控制台→程式集→開啟或關閉Windows功能
選擇「Telnet用戶端」與「TFTP用戶端」的選擇,
再按確定。
這樣就可以使用telnet與tftp了。
參考資料:
Win7 開啟 telnet and tftp
2014年5月5日 星期一
union
因為IPv6的address一共有128bit,
若要處理的話,
目前long int也只有4 bytes(32bit),
double只有8bytes(64bit)
沒有一個變數可以儲存到128bit,
這個時候就要用到union
直接寫下
這個宣告方式,可以讓128bit,
各別的使用8bit在運算。
下面是我寫的一個sub function,
也因為有了這個,
要運算IPv6才會變的比較簡單。
若要處理的話,
目前long int也只有4 bytes(32bit),
double只有8bytes(64bit)
沒有一個變數可以儲存到128bit,
這個時候就要用到union
直接寫下
/* IPv6 address */
struct in6_addr {
union {
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};
這個宣告方式,可以讓128bit,
各別的使用8bit在運算。
下面是我寫的一個sub function,
也因為有了這個,
要運算IPv6才會變的比較簡單。
/*
* Filter the IPv6 by prefix to Network ID or Interface ID
*
* @param IPv6_Addr_Src the source for filtering
* @param IPv6_Addr_Dst the result of the filtering process
* @param PrefixLen the prefix of the network
* @param MaskType if the value is NetworkPrefix, network prefix would be reserved
* if the value is InterfaceIdentifier, the interface identifier would be reserved
*/
static void
MaskIPv6 (
struct in6_addr IPv6_Addr_Src,
struct in6_addr *IPv6_Addr_Dst,
int PrefixLen,
enum MaskType Direction
)
{
char *AddrPtr, *IndexAddrPtr;
int FullByteNumber, BitNumber;
char Mask;
int Index;
int CurrentPosition;
//
// The bytes of network id part
//
FullByteNumber = PrefixLen / 8;
//
// The bits of network id part
//
BitNumber = PrefixLen % 8;
//
// filter the bytes of Network ID part
//
for (CurrentPosition = 0; CurrentPosition < FullByteNumber; CurrentPosition++) {
if (Direction == NetworkPrefix) {
IPv6_Addr_Src.s6_addr[CurrentPosition] = IPv6_Addr_Src.s6_addr[CurrentPosition] & 0xFF;
} else {
IPv6_Addr_Src.s6_addr[CurrentPosition] = IPv6_Addr_Src.s6_addr[CurrentPosition] & 0x00;
}
}
//
// filter the bits of Network ID part and the bits of Interface ID part
//
Mask = 0;
if (BitNumber != 0) {
for (Index = 0; Index < BitNumber; Index++) {
Mask = (Mask << 1) | 1;
}
for (Index = 0; Index < 8 - BitNumber; Index++) {
Mask = Mask << 1;
}
if (Direction == InterfaceIdentifier) {
Mask = ~Mask;
}
IPv6_Addr_Src.s6_addr[CurrentPosition] = IPv6_Addr_Src.s6_addr[CurrentPosition] & Mask;
CurrentPosition++;
}
//
// filter the bytes of Interface ID part
//
for (; CurrentPosition < 16; CurrentPosition++) {
if (Direction == NetworkPrefix) {
IPv6_Addr_Src.s6_addr[CurrentPosition] = IPv6_Addr_Src.s6_addr[CurrentPosition] & 0x00;
} else {
IPv6_Addr_Src.s6_addr[CurrentPosition] = IPv6_Addr_Src.s6_addr[CurrentPosition] & 0xFF;
}
}
//
// Copy the modified IPv6_Addr_Src context for return
//
memcpy (IPv6_Addr_Dst, &IPv6_Addr_Src, sizeof (IPv6_Addr_Src));
}