在Linux中,基于SMD的數(shù)據(jù)通信是以信道的形式作為一個(gè)設(shè)備存在的,作為一種雙向信道,其接口的實(shí)現(xiàn)遵循Linux設(shè)備驅(qū)動(dòng)規(guī)范。在Qucalcomm平臺(tái)上,SMD的緩沖大小為8192bit,大信道數(shù)為64,SMD的頭大小為20bit。
SMD的相關(guān)代碼實(shí)現(xiàn)主要位于aurora\msm\msm\arch\arm\mach-msm目錄下。主要文件包括:smd.c、smd_nmea.c、smd_qmi.c、smd_rpcrouter.c、smd_rpcrouter_clients.c、smd_ rpcrouter_device.c、smd_rpcrouter_servers.c、smd_tty.c等。
SMD信道需要同時(shí)維護(hù)接收信道、發(fā)送信道的狀態(tài)和數(shù)據(jù)信息,SMD的信道定義如下:
struct smd_channel {
volatile struct smd_half_channel *send; //發(fā)送握手信道
volatile struct smd_half_channel *recv; //接收握手信道
unsigned char *send_buf; //發(fā)送信道數(shù)據(jù)
unsigned char *recv_buf; //接收信道數(shù)據(jù)
unsigned buf_size;
struct list_head ch_list; //信道列表
unsigned current_packet;
unsigned n;
void *priv;
void (*notify)(void *priv, unsigned flags);
int (*read)(smd_channel_t *ch, void *data, int len); //讀數(shù)據(jù)
int (*write)(smd_channel_t *ch, const void *data, int len); //寫(xiě)數(shù)據(jù)
int (*read_avail)(smd_channel_t *ch); //是否可讀
int (*write_avail)(smd_channel_t *ch); //是否可寫(xiě)
int (*read_from_cb)(smd_channel_t *ch, void *data, int len);
void (*update_state)(smd_channel_t *ch);
unsigned last_state;
char name[20];
struct platform_device pdev;
unsigned type;
};
共享信道的信道狀態(tài)在其握手信道中記錄,握手信道的定義如下:
struct smd_half_channel {
unsigned state;
unsigned char fDSR;
unsigned char fCTS;
unsigned char fCD;
unsigned char fRI;
unsigned char fHEAD; //頭部
unsigned char fTAIL; //尾部
unsigned char fSTATE; //狀態(tài)
unsigned char fUNUSED;
unsigned tail;
unsigned head;
};
在實(shí)際實(shí)現(xiàn)中,SMD信道分配被封裝在SMEM(Shared Memory Manager)模塊中,系統(tǒng)提供了smem_init()、smem_alloc()、smem_get_entry()等內(nèi)存操作函數(shù)供SMD和SMSM操作。
SMD的狀態(tài)共有SMD_SS_CLOSED、SMD_SS_OPENING、SMD_SS_OPENED、SMD_SS_FLUSHING、SMD_SS_CLOSING、SMD_SS_RESET、SMD_SS_RESET_OPENING等。其變化過(guò)程如圖1-1所示。

圖1-1 SMD的狀態(tài)機(jī)