南宁3及分销网站制作,网站空间代理站,给别人做网站怎么赚钱,公众号文章模板素材背景 
问题 
前段时间开发一个tty驱动#xff0c;用途是实现仪器对GPIB消息的接收、处理和上报。对于上报场景#xff0c;下位机应用将上报内容写入一个驱动创建的tty设备#xff0c;tty子系统将应用的输入转发给tty驱动#xff0c;tty驱动将其转换成对SPI从设备#xff0…背景 
问题 
前段时间开发一个tty驱动用途是实现仪器对GPIB消息的接收、处理和上报。对于上报场景下位机应用将上报内容写入一个驱动创建的tty设备tty子系统将应用的输入转发给tty驱动tty驱动将其转换成对SPI从设备即GPIB扩展板的写入SPI从设备再将收到的SPI消息转换成GPIB消息发送给上位机。  
实现tty_operations的write接口时我是这么获取驱动上下文的 
struct gpib_tty_ctx {struct tty_port port;struct tty_struct mgr;  // 其实是无效的成员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指针访问上下文结构体gpib_tty_ctx的驱动私有字段完成write功能return count;
}但是实际执行的时候触发了空指针异常且空指针的值并不是0x0这种典型值而是带一点偏移。 
问题定位 
经定位是我对tty子系统的理解有问题write方法的第一个入参tty并不是gpib_tty_ctx的struct tty_struct mgr成员的地址而是tty子系统在运行时自动创建的一个匿名tty_struct对象的地址因此我用container_of宏获取到的gpib_tty_ctx对象地址也是一个无效地址 
解决 
注意到tty_struct结构体包含一个类型为struct tty_port的指针port 
struct tty_struct {struct kref kref;int index;struct device *dev;struct tty_driver *driver;struct tty_port *port;   // 指向用户驱动创建并初始化的tty_port对象const struct tty_operations *ops;struct tty_ldisc *ldisc;struct ld_semaphore ldisc_sem;// ...
};它应该就是指向驱动之前创建并初始化的gpib_tty_ctx.port对象这个对象本身是没有被复制的因此我可以将这个指针传递给container_of宏 
struct gpib_tty_ctx *ctx  container_of(tty-port, struct gpib_tty_ctx, port);经测试新的container_of宏返回了正确的驱动上下文地址。 
总结 
tty_struct指针类似于file_operations接口的open方法的输出参数file指针都对应内核自动分配的一个对象其地址是不可以用于container_of宏的但是它的成员private_data可以用于container_of宏因为后者的值是驱动填写的。container_of宏的第一个参数是结构体成员的地址这个结构体成员一般是个对象不建议选地址类成员因为如果是地址则该成员很可能是复制过的那么你通过给container_of宏提供二级指针指针成员的地址就是二级指针获取的ctx对象很可能是错的。