旅游網(wǎng)站的制作友情鏈接獲取的途徑有哪些
背景
問題
前段時(shí)間開發(fā)一個(gè)tty驅(qū)動(dòng),用途是實(shí)現(xiàn)儀器對(duì)GPIB消息的接收、處理和上報(bào)。對(duì)于上報(bào)場(chǎng)景,下位機(jī)應(yīng)用將上報(bào)內(nèi)容寫入一個(gè)驅(qū)動(dòng)創(chuàng)建的tty設(shè)備,tty子系統(tǒng)將應(yīng)用的輸入轉(zhuǎn)發(fā)給tty驅(qū)動(dòng),tty驅(qū)動(dòng)將其轉(zhuǎn)換成對(duì)SPI從設(shè)備
(即GPIB擴(kuò)展板)的寫入,SPI從設(shè)備
再將收到的SPI消息轉(zhuǎn)換成GPIB消息
發(fā)送給上位機(jī)
。
struct gpib_tty_ctx {struct tty_port port;struct tty_struct mgr; // 其實(shí)是無效的成員struct tty_driver *tty_drv;struct spi_device *spi_dev;struct gpib_spi_ctx *spi_ctx;struct mutex tty_lock;u32 activated:1;const u8 *pend_tx_buf;u32 pend_tx_len;
};static int gpib_tty_write(struct tty_struct * tty, const unsigned char *buf, int count)
{struct gpib_tty_ctx *ctx = container_of(tty, struct gpib_tty_ctx, mgr);// 通過ctx指針訪問上下文結(jié)構(gòu)體gpib_tty_ctx的驅(qū)動(dòng)私有字段,完成write功能return count;
}
但是實(shí)際執(zhí)行的時(shí)候,觸發(fā)了空指針異常
,且空指針的值并不是0x0這種典型值,而是帶一點(diǎn)偏移。
問題定位
經(jīng)定位,是我對(duì)tty子系統(tǒng)的理解有問題,write
方法的第一個(gè)入?yún)?code>tty,并不是gpib_tty_ctx
的struct tty_struct mgr
成員的地址,而是tty子系統(tǒng)在運(yùn)行時(shí)自動(dòng)創(chuàng)建的一個(gè)匿名tty_struct
對(duì)象的地址!因此我用container_of
宏獲取到的gpib_tty_ctx
對(duì)象地址也是一個(gè)無效地址!
解決
注意到tty_struct
結(jié)構(gòu)體包含一個(gè)類型為struct tty_port
的指針port
:
struct tty_struct {struct kref kref;int index;struct device *dev;struct tty_driver *driver;struct tty_port *port; // 指向用戶驅(qū)動(dòng)創(chuàng)建并初始化的tty_port對(duì)象const struct tty_operations *ops;struct tty_ldisc *ldisc;struct ld_semaphore ldisc_sem;// ...
};
它應(yīng)該就是指向驅(qū)動(dòng)之前創(chuàng)建并初始化的gpib_tty_ctx.port
對(duì)象,這個(gè)對(duì)象本身是沒有被復(fù)制的,因此我可以將這個(gè)指針傳遞給container_of
宏:
struct gpib_tty_ctx *ctx = container_of(tty->port, struct gpib_tty_ctx, port);
經(jīng)測(cè)試,新的container_of
宏返回了正確的驅(qū)動(dòng)上下文地址。
總結(jié)
tty_struct
指針類似于file_operations
接口的open
方法的輸出參數(shù)file
指針,都對(duì)應(yīng)內(nèi)核自動(dòng)分配的一個(gè)對(duì)象,其地址是不可以用于container_of
宏的,但是它的成員private_data
可以用于container_of
宏,因?yàn)楹笳叩闹凳球?qū)動(dòng)填寫的。container_of
宏的第一個(gè)參數(shù)是結(jié)構(gòu)體成員
的地址
,這個(gè)結(jié)構(gòu)體成員
一般是個(gè)對(duì)象,不建議選地址類成員,因?yàn)槿绻堑刂?#xff0c;則該成員很可能是復(fù)制過的,那么你通過給container_of
宏提供二級(jí)指針(指針成員的地址就是二級(jí)指針)獲取的ctx對(duì)象,很可能是錯(cuò)的。