rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

一点儿想法,设备struct rt_device定义中的 void *user_data 是不是应该只留给用户使用

Open winfenggao opened this issue 2 years ago • 4 comments

按照字面意思,void *user_data; 应该留给用户使用,目前在组件和软件包中都有占用;

有几次在写代码时,用到了这个指针,直到程序异常排查采发现组件占用了这个指针,被我修改了导致异常; 是不是应该对这个指针的使用明确一下。 或者组件和软件包避免使用这个指针; 或者使用者特别声明一下; 或者专门在device里给组件门专门留一个指针; ` /**

  • Device structure */ struct rt_device { struct rt_object parent; /**< inherit from rt_object */

    enum rt_device_class_type type; /< device type */ rt_uint16_t flag; /< device flag */ rt_uint16_t open_flag; /**< device open flag */

    rt_uint8_t ref_count; /< reference count */ rt_uint8_t device_id; /< 0 - 255 */

    /* device call back */ rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size); rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);

#ifdef RT_USING_DEVICE_OPS const struct rt_device_ops ops; #else / common device interface */ rt_err_t (*init) (rt_device_t dev); rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag); rt_err_t (*close) (rt_device_t dev); rt_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); rt_size_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size); rt_err_t (*control)(rt_device_t dev, int cmd, void args); #endif / RT_USING_DEVICE_OPS */

#ifdef RT_USING_POSIX_DEVIO const struct dfs_file_ops fops; struct rt_wqueue wait_queue; #endif / RT_USING_POSIX_DEVIO */

void                     *user_data;                /**< device private data */

}; `

winfenggao avatar Aug 21 '22 01:08 winfenggao

没错 我们也发现这个问题了,这个非常误导用户,将在v5.0版本当中修改。

mysterywolf avatar Aug 21 '22 05:08 mysterywolf

好的

winfenggao avatar Aug 22 '22 02:08 winfenggao

按照字面意思,void *user_data; 应该留给用户使用,目前在组件和软件包中都有占用;

个人认为不应该, device 的结构体中的所有成员变量都是供驱动逻辑使用的,其他组件/模块调用设备时应该只使用 rt_device_open / read/ write 等 api 完成对设备的操作,不应该直接使用设备结构体的任何成员变量。

a1012112796 avatar Nov 10 '22 09:11 a1012112796

不是的 这个是设计的问题,user_data这个词给用户造成了极大地误解,或者说早期阶段,rt-thread在没有过多上层建筑是 user_data确实是给user用的,但是上层建筑开始逐渐丰富起来之后,rt-thread的这些上层建筑也开始偷偷摸摸自己去用这个字段了。所以这里要重新规范一下。

mysterywolf avatar Nov 10 '22 15:11 mysterywolf

不是的 这个是设计的问题,user_data这个词给用户造成了极大地误解,或者说早期阶段,rt-thread在没有过多上层建筑是 user_data确实是给user用的,但是上层建筑开始逐渐丰富起来之后,rt-thread的这些上层建筑也开始偷偷摸摸自己去用这个字段了。所以这里要重新规范一下。

  • 文档注释还是比较明确的。。。 image

  • 个人感觉可能考虑添加如下接口:

void rt_device_set_param(rt_device_t dev, void *param);
void *rt_device_get_param(rt_device_t dev);
  • 更希望可以给hook 加参数,但这样对旧的代码破坏就太大了。。。
diff --git a/rt-thread/include/rtthread.h b/rt-thread/include/rtthread.h
index c55720b..85d9016 100644
--- a/rt-thread/include/rtthread.h
+++ b/rt-thread/include/rtthread.h
@@ -502,10 +502,10 @@ void rt_device_destroy(rt_device_t device);
 
 rt_err_t
 rt_device_set_rx_indicate(rt_device_t dev,
-                          rt_err_t (*rx_ind)(rt_device_t dev, rt_size_t size));
+                          rt_err_t (*rx_ind)(rt_device_t dev, rt_size_t size, void *param), void *param);
 rt_err_t
 rt_device_set_tx_complete(rt_device_t dev,
-                          rt_err_t (*tx_done)(rt_device_t dev, void *buffer));
+                          rt_err_t (*tx_done)(rt_device_t dev, void *buffer, void *param), void *param);
 
 rt_err_t  rt_device_init (rt_device_t dev);
 rt_err_t  rt_device_open (rt_device_t dev, rt_uint16_t oflag);


a1012112796 avatar Jan 06 '23 08:01 a1012112796

文档注释还是比较明确的。。。

外国人看不懂中文文档呢?

这块肯定是有问题的,中文文档把user_data写成了私有数据,私有数据应该叫private_data。这是两个高冲突的信息,文档里说这个是私有数据,源码命名上说这个不是系统私有的,是留给用户的。主要是因为,早期rt-thread仅仅是一个kernel的时候,tcb里的user_data真的是给user留着用的。但是随着rt-thread上层建筑不断增多。很多其他结构体写模仿者tcb的写法写成了user_data。但是user_data却总被系统内部自己偷偷使用掉,根本不是留给user的。

mysterywolf avatar Jan 08 '23 04:01 mysterywolf