2012年10月18日 星期四

[轉][Linux] - Linux IPC到底是什麼東西?


看Linux的資料,覺得很不爽的就是各個概念很多,什麼東西都取一個名字,然後抽象的又取個名字,特別是加上中文翻譯作者經常又翻譯出不同的意思、不同的版本來,看的實在是有點暈,其實最後弄明白了也就是那些東西。
 
IPC Inter-Process Communication 進程間通信。
一開始我還以為有個專門的進程間通信的機制呢,原來這只是一個統一稱呼而已,真實的通信用的機制是:semaphore,message queue,pipe,mutex,share memory等。
 
下面轉一個別人寫的IPC方面的資料連接,不熟悉的可以看看:
原帖發表在IBM的developerworks網站上,是一個系列的文章,作者鄭彥興,通過講解和例子演示了Linux中幾種IPC的使用方式,我覺得很好,在這裡做一個保留,能看完的話Linux IPC的基礎是沒有問題的了。

一)Linux環境進程間通信(一)管道及有名管道

二)Linux環境進程間通信(二):信號

三)Linux環境進程間通信(三)消息隊列

四)Linux環境進程間通信(四)信號燈

五)Linux環境進程間通信(五):共享內存

------------------------------
各種通信方式的優缺點
1)unix下面系統本身就是用管道(pipe)進行通信的,事實上就是比較簡單,而且比較簡單   
  2)socket會帶來一些額外的開銷,如網絡開銷,系統安全等等,不建議用,除非不是同一台機器   
  3)共享內存,控制起來麻煩,但是速度是會,帶來的麻煩就是程序要添加一些瑣或者是信號量,程序寫的不好容易出現死瑣現象   
  4)通過文件進行通信,不過這個速度是最慢的  
  5)消息隊列是消息的鏈接表,包括Posix消息隊列systemV消息隊列。有足夠權限的進程可以向隊列中添加消息,被賦予讀權限的進程則可以讀走隊列中的消息。消息隊列克服了信號承載信​​息量少,管道只能承載無格式字節流以及緩衝區大小受限等缺點。但開銷比較大。


2012年8月16日 星期四

[轉] PIC32 庫函數學習筆記3——定時器



根據PIC32MX中文說明介紹,PIC32MX 系列器件共5個定時器,TEMER1~5。

其中,TIMER1採用一個同步/ 異步16 位定時器,它可作為自由運行的時段定時器使用,用於各種計時應用和計數外部事件。此定時器也可與低功耗輔助振盪器(SOSC)結合使用,為應用提供實時時鐘。支持下列模式:
‧ 同步內部定時器
‧ 同步內部門控定時器
‧ 同步外部定時器
‧ 異步外部定時器

其他支持的特性有
‧ 可選的時鐘預分頻比
‧ 定時器可在CPU 空閒和休眠模式下工作
‧ 可使用CLR、SET 和INV寄存器進行快速位操作
‧ 異步模式下,可與SOSC 結合使用以提供實時時鐘(Real-Time Clock, RTC)。

TIMER2~5採用了4 個同步16 位定時器(默認),它可作為自由運行的時段定時器使用,用於各種計時應用和計數外部事件。支持下列模式:
‧ 同步內部 16位定時器
‧ 同步內部 16位門控定時器
‧ 同步外部 16位定時器

Timer2 與Timer3組合以及Timer4與Timer5 組合可提供2個32位同步定時器。這2個32位定時器可工作在3 種模式下:
‧ 同步內部 32位定時器
‧ 同步內部 32位門控定時器
‧ 同步外部 32位定時器

其他支持的特性有:
‧ 可選的時鐘預分頻比
‧ 定時器可工作在CPU 空閒模式下
‧ 為輸入捕捉模塊和輸出比較模塊提供了時基(僅Timer2 和Timer3)
‧ ADC事件觸發信號(僅 Timer3)
‧ 可使用CLR、SET 和INV寄存器進行快速位操作



定時器的庫函數更加的豐富,主要內容如下:

‧ CPU Core Timer Operations //CPU核心定時器
OpenCoreTimer
UpdateCoreTimer
mConfigIntCoreTimer
mEnableIntCoreTimer
mDisableIntCoreTimer
mSetPriorityIntCoreTimer
ReadCoreTimer
WriteCoreTimer
‧ General Purpose Timer Common Operations
OpenTImerx
CloseTimerx
ConfigIntTimerx
SetPriorityIntTx
DisableIntTx
EnableIntTx
‧ General Purpose Timer and Period Read/Write Operations
ReadTimerx
WriteTimerx
ReadPeriodx
WritePeriodx


  • void OpenCoreTimer(unsigned int compare);


This function clears the CPU Core Count register, then loads the CPUCore Compare register with period.

例:OpenCoreTimer(0x00004000);


  • void UpdateCoreTimer(unsigned int period);


This function adds period to the current value in the CPU Core Compare register, effectively creating the next period match.
Note: A simple method for creating periodic interrupts can be achieved by using the CPU Core Timer and an ISR (Interrupt Service Routine) that calls “UpdateCoreTimer() to update the Core Compare value.See Core Timer code example at the end of this chapter

例:void _CoreTimerHandler(void)
{
    mCTClearIntFlag();
    UpdateCoreTimer(CORE_TIMER_PERIOD);
   
    // .. things to do .. add code here
}


  • void mConfigIntCoreTimer(config);


his argument contains one or more bit masks bitwise OR'd
together. Select one or more from the following bit masks.
Note: An absent mask symbol in an argument assumes the
corresponding bit(s) are disabled, or default value, and are
set = 0.
Core Timer On/Off
CT_INT_ON
CT_INT_OFF
Core Timer Priority Interrupt Level
CT_INT_PRIOR_7
CT_INT_PRIOR_6
CT_INT_PRIOR_5
CT_INT_PRIOR_4
CT_INT_PRIOR_3
CT_INT_PRIOR_2
CT_INT_PRIOR_1
CT_INT_PRIOR_0
Core Timer Sub-Priority Interrupt Level
CT_INT_SUB_PRIOR_3
CT_INT_SUB_PRIOR_2
CT_INT_SUB_PRIOR_1
CT_INT_SUB_PRIOR_0

例:mConfigIntCoreTimer(CT_INT_ON | CT_INT_PRIOR_4);


  • mEnableIntCoreTimer();


This macro enables the 32-bit CPU Core Timer interrupt.//應該是打開主定時器一類的


  • void mDisableIntCoreTimer(void);


//關閉主定時器


  • void mCTSetIntPriority(unsigned int priority);//設置定時器優先級


Core Timer Priority Interrupt Levels
CT_INT_PRIOR_7
CT_INT_PRIOR_6
CT_INT_PRIOR_5
CT_INT_PRIOR_4
CT_INT_PRIOR_3
CT_INT_PRIOR_2
CT_INT_PRIOR_1
CT_INT_PRIOR_0

例:mCTSetIntPriority(CT_INT_PRIOR_2);


  • unsigned int ReadCoreTimer(void);


//返回內部定時器值

例:unsigned int t0;
t0 = ReadCoreTimer();


  • void WriteCoreTimer(unsigned int timer);//寫主定時器


例:WriteCoreTimer(0x12345678);



//下面部分是通用定時器設置


  • void OpenTimer1(unsigned int config, unsigned int period);

void OpenTimer2(unsigned int config, unsigned int period);
void OpenTimer3(unsigned int config, unsigned int period);
void OpenTimer4(unsigned int config, unsigned int period);
void OpenTimer5(unsigned int config, unsigned int period);

Timer Module On/Off
Tx_ON
Tx_OFF
(These bit fields are mutually exclusive)
Asynchronous Timer Write Disable
T1_TMWDIS_ON
T1_TMWDIS_OFF
(These bit fields are mutually exclusive)
Timer Module Idle mode On/Off
Tx_IDLE_CON
Tx_IDLE_STOP
(These bit fields are mutually exclusive)
Timer Gate time accumulation enable
Tx_GATE_ON
Tx_GATE_OFF
(These bit fields are mutually exclusive)

Timer Prescaler(1)//只有TIMER1可以設置

T1_PS_1_1
T1_PS_1_8
T1_PS_1_64
T1_PS_1_256
Timer Prescaler//所有的定時器都可以設置
Tx_PS_1_1
Tx_PS_1_2
Tx_PS_1_4
Tx_PS_1_8
Tx_PS_1_16
Tx_PS_1_32
Tx_PS_1_64
Tx_PS_1_256
(These bit fields are mutually exclusive)

Timer Synchronous clock enable(1)
Tx_SYNC_EXT_ON
(These bit fields are mutually exclusive)
Timer Clock source
Tx_SOURCE_EXT
(These bit fields are mutually exclusive)

例:OpenTimer1(T1_ON | T1_SOURCE_EXT | T1_SYNC_EXT_ON |T1_PS_1_8, 0xFFFF);


  • void OpenTimer32(unsigned int config, unsigned long period);


void OpenTimer45(unsigned int config, unsigned long period);//將兩個定時器合併作為一個32位定時器使用

Timer module On/Off
Tx_ON
Tx_OFF
(These bit fields are mutually exclusive)
Timer Module Idle mode On/Off
Tx_IDLE_CON
Tx_IDLE_STOP
(These bit fields are mutually exclusive)
Timer Gate time accumulation enable
Tx_GATE_ON
Tx_GATE_OFF
(These bit fields are mutually exclusive)
Timer prescaler
Tx_PS_1_1
Tx_PS_1_2
Tx_PS_1_4
Tx_PS_1_8
Tx_PS_1_16
Tx_PS_1_32
Tx_PS_1_64
Tx_PS_1_256
(These bit fields are mutually exclusive)
32-bit Timer Mode enable
Tx_32BIT_MODE_ON
Tx_32BIT_MODE_OFF
(These bit fields are mutually exclusive)
Timer clock source
Tx_SOURCE_EXT
Tx_SOURCE_INT
(These bit fields are mutually exclusive)

例:OpenTimer23(T2_ON | T2_PS_1_256 | T2_32BIT_MODE_ON,
0x00A00000);


  • void CloseTimer1(void);

void CloseTimer2(void);
void CloseTimer3(void);
void CloseTimer4(void);
void CloseTimer5(void);//關閉相應的定時器


  • void CloseTimer23 (void)

void CloseTimer45 (void)//停止32位定時器


  • void ConfigIntTimer1(unsigned int config);

void ConfigIntTimer2(unsigned int config);
void ConfigIntTimer3(unsigned int config);
void ConfigIntTimer4(unsigned int config);
void ConfigIntTimer5(unsigned int config);//配置定時器中斷

Timer interrupt enable/disable//中斷開關位
Tx_INT_ON
Tx_INT_OFF
(These bit fields are mutually exclusive)
Timer interrupt priorities//定時中斷優先級
Tx_INT_PRIOR_7
Tx_INT_PRIOR_6
Tx_INT_PRIOR_5
Tx_INT_PRIOR_4
Tx_INT_PRIOR_3
Tx_INT_PRIOR_2
Tx_INT_PRIOR_1
Tx_INT_PRIOR_0
(These bit fields are mutually exclusive)
Timer interrupt sub- priorities
Tx_INT_SUB_PRIOR_3
Tx_INT_SUB_PRIOR_2
Tx_INT_SUB_PRIOR_1
Tx_INT_SUB_PRIOR_0
(These bit fields are mutually exclusive)

例:ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_2);


  • void ConfigIntTimer23(unsigned int config);

void ConfigIntTimer45(unsigned int config);//32位定時器中斷配置

Timer interrupt enable/disable
Tx_INT_ON
Tx_INT_OFF
(These bit fields are mutually exclusive)
Timer interrupt priorities
Tx_INT_PRIOR_7
Tx_INT_PRIOR_6
Tx_INT_PRIOR_5
Tx_INT_PRIOR_4
Tx_INT_PRIOR_3
Tx_INT_PRIOR_2
Tx_INT_PRIOR_1
Tx_INT_PRIOR_0
(These bit fields are mutually exclusive)
Timer interrupt sub- priorities
Tx_INT_SUB_PRIOR_3
Tx_INT_SUB_PRIOR_2
Tx_INT_SUB_PRIOR_1
Tx_INT_SUB_PRIOR_0

例:/* Set Timer45 interrupt priority = 3, sub = 2 */
ConfigIntTimer45(T45_INT_ON | T45_INT_PRIOR_3 | T45_INT_SUB_PRIOR_2);


  • void SetPriorityIntT1(unsigned int config);

void SetPriorityIntT2(unsigned int config);
void SetPriorityIntT3(unsigned int config);
void SetPriorityIntT4(unsigned int config);
void SetPriorityIntT5(unsigned int config);//改變中斷優先級

Timer interrupt priorities
Tx_INT_PRIOR_7
Tx_INT_PRIOR_6
Tx_INT_PRIOR_5
Tx_INT_PRIOR_4
Tx_INT_PRIOR_3
Tx_INT_PRIOR_2
Tx_INT_PRIOR_1
Tx_INT_PRIOR_0

例:/* Set Timer3 interrupt priority = 2*/
SetPriorityIntT3(T3_INT_PRIOR_2)


  • void SetPriorityIntT23(unsigned int config);

void SetPriorityIntT45(unsigned int config);

Timer interrupt priorities
Tx_INT_PRIOR_7
Tx_INT_PRIOR_6
Tx_INT_PRIOR_5
Tx_INT_PRIOR_4
Tx_INT_PRIOR_3
Tx_INT_PRIOR_2
Tx_INT_PRIOR_1
Tx_INT_PRIOR_0

例:/* Set Timer23 interrupt priority = 2*/
SetPriorityIntT23(T23_INT_PRIOR_2);

16.void DisableIntT1(void);//禁止相應的定時中斷
void DisableIntT2(void);
void DisableIntT3(void);
void DisableIntT4(void);
void DisableIntT5(void);

例:/* Disable Timer4 interrupt */
DisableIntT4();


  • void DisableIntT23(void);

void DisableIntT45(void);

/* Disable Timer45 interrupt */
DisableIntT45();

18.void EnableIntT1(void);
void EnableIntT2(void);
void EnableIntT3(void);
void EnableIntT4(void);
void EnableIntT5(void);//使能中斷

/* Enable Timer4 interrupt */
EnableIntT4();


  • void EnableIntT23(void);

void EnableIntT45(void);

/* Enable Timer45 interrupt */
EnableIntT45();


  • unsigned int ReadTimer1(void);

unsigned int ReadTimer2(void);
unsigned int ReadTimer3(void);
unsigned int ReadTimer4(void);
unsigned int ReadTimer5(void);//返回16為定時計數器的值

例:/* Read timer 4 */
currentValue = ReadTimer4();


  • unsigned int ReadTimer23(void);

unsigned int ReadTimer45(void);

例:currentValue = ReadTimer45();


  • void WriteTimer1(unsigned int);

void WriteTimer2(unsigned int);
void WriteTimer3(unsigned int);
void WriteTimer4(unsigned int);
void WriteTimer5(unsigned int);//寫16位定時寄存器值

例:WriteTimer1(0x0400);


  • void WriteTimer23(unsigned int);

void WriteTimer45(unsigned int);

WriteTimer45(0x00000000);


  • unsigned int ReadPeriod1(void);

unsigned int ReadPeriod2(void);
unsigned int ReadPeriod3(void);
unsigned int ReadPeriod4(void);
unsigned int ReadPeriod5(void);//

例:currentValue = ReadPeriod4();


  • unsigned int ReadPeriod23(void);

unsigned int ReadPeriod45(void);

例:currentValue = ReadPeriod45();


  • void WritePeriod1(unsigned int);

void WritePeriod2(unsigned int);
void WritePeriod3(unsigned int);
void WritePeriod4(unsigned int);
void WritePeriod5(unsigned int);

例:WritePeriod1(0x0400);


  • void WritePeriod23(unsigned int);

void WritePeriod45(unsigned int);

例:WritePeriod45(0x00000000);

Source : http://hi.baidu.com/lykb/blog/item/803d54cb8d41b20bbf09e677.html

2012年8月9日 星期四

關於C/C++的指標


我想應該還有不少人在使用指標上有些地方觀念不大清楚,比如說下面二個函式,那個是正確的?為什麼?像這樣的問題如果弄不清楚,寫出來的程式一定非常危險。
// 為簡化忽略檢查
void alloc_mem(char* p) // 版本1
{
  p = new char[100];
}

void alloc_mem(char** p) // 版本2
{
  *p = new char[100];
}
如上,這個函式要配置大小是100個字元的記憶體並從傳入的參數p回傳,這二個版本除了輸入參數不一樣外大致上是一樣的;從第一個版本來看,參數是一個字元指標,記憶體配置出之後直接傳給p,如果觀念正確的人一定可以馬上指出這樣的寫法是錯誤的,第二個版本才是正確能work的。

現在就來說明為什麼,在這之前先要了解在C/C++中,函式的參數是如何傳遞的,在C/C++中函式的呼叫所傳入的參數是透過堆疊(Stack) 來傳入函式的,不懂什麼是堆疊也沒關係,就把它看成是另外一塊記憶體也行,當在程式中呼叫某個函式時,傳入的參數會先被複製到這塊記憶體中,當在函式中要使用這些參數時再從堆疊中去取出來。

以版本1的例子來說明,如下在程式中大概會這樣呼叫。
char* pp = NULL;
alloc_mem(pp);
pp一開始的初值是NULL,當呼叫alloc_mem時,pp的值會被複製到堆疊中(傳址),這種情況和以下的code事實上是對等的,只不過 p的值一開始被初始化成和pp的值一樣,p就好像一個區域變數一樣,一離開函式後這個變數就無效了,所以在外面的pp的值永遠都不會改變,同時在涵式中 new出來的記憶體也lost掉了。
void alloc_mem()
{
  char* p = new char[100];
}
再來看版本2,它的參數是一個指標的指標,這是什麼意思,我們先從實際使用上來看,如下。
char* pp = NULL;
alloc_mem(&pp);
這次我們把pp這個變數的位址傳入涵式,所以在涵式中所得到的是pp這個變數的位址,在函式中p所含的內容是pp的位址,pp是一個char*形態的變數,p是一個指標它的內容是char*的形態,現在p已經指向pp了,所以對p的內容作改變,相對的pp的值也會跟著改變。

現在來看另外一個類似例子,會比較清楚些。
void change_val(int* i)
{
  *i = 5;
}

int ii = 3;
change_val(&ii);
這個例子和上面是一樣的,只不過變數的形態從char*改成了int,仔細去對照比較一下,回頭再去看alloc_mem相信能更容易明白。

Reference :
1. 很讚的遊戲編輯器, http://good-ed.blogspot.tw/2009/12/cc.html

2012年5月30日 星期三

(BCB)使用指標傳值-1

程式裡面經常可以見到 &變數,尤其在Funtion宣告時裡面常出現
以往只了解是針對記憶體位置做讀寫,實際操作一次

程式功能:
Button1->Caption = Edit1 + Edit2 ;
使用函數 fastcul 計算。


  • 一般常見寫法:

//----------------------------------------------------------------

int TForm1::fastcul(int a, int b)
{
         return (a+b);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        int a ,b ;
        a = StrToInt(Edit1->Text);
        b = StrToInt(Edit2->Text);
        Button1->Caption = fastcul(a,b);
}

//----將值傳到fastcul,計算完成回傳


  • 使用指標寫法
//------------------------------------------------------------------
TForm1 *Form1;
int a ,b;
//------------------------------------------------------------------
bool TForm1::fastcul(AnsiString &TestData)
{
         TestData=a+b;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        AnsiString TestData;
        a = StrToInt(Edit1->Text);
        b = StrToInt(Edit2->Text);
        fastcul(TestData);
        Button1->Caption = TestData;
}


以上兩種寫法都可以達到相同要求!