在第二章 第七节mavlink_log实现原理中讲解的内容有误,深表歉意,我们会持续改进!!谢谢关注!
-
设备节点的名字
#define MAVLINK_LOG_DEVICE "/dev/mavlink"
-
驱动的fops中的ioctl重映射
#ifdef __PX4_NUTTX
fops.ioctl = (int (*)(file *, int, long unsigned int))&mavlink_dev_ioctl;
#endif
-
注册设备节点
#ifdef __PX4_NUTTX
register_driver(MAVLINK_LOG_DEVICE, &fops, 0666, NULL);
#else
-
mavlink中mavlink_dev_ioctl的方法
#ifdef __PX4_NUTTX
Mavlink::mavlink_dev_ioctl(struct file *filp, int cmd, unsigned long arg)
#else
Mavlink::ioctl(device::file_t *filp, int cmd, unsigned long arg)
#endif
{
}
1. 打开设备节点:我们从这里会想到一个问题,这个设备节点被多次打开,会不会导致,数据输出出现竞争的现象
_mavlink_fd = px4_open(MAVLINK_LOG_DEVICE, 0)
px4_ioctl(_fd, severity, (unsigned long)&text[0]);
->调用ioctl,会调用到Mavlink::mavlink_dev_ioctl(struct file *filp, int cmd, unsigned long arg),
“而我讲的是会调用Mavlink::ioctl(device::file_t *filp, int cmd, unsigned long arg), 这个是错误,由于在之前fops.ioctl又做了新的重映射,所以会调用到mavlink_dev_ioctl这个方法”
2. 一个驱动fops,可以被挂载到不同的设备节点中,但是1个设备节点,不能挂载多个fops, 这个是怎么回事呢??
这样我们就想到,这个mavlink_dev_ioctl(struct file *filp, int cmd, unsigned long arg)必须是静态函数,然后我们查找
class Mavlink {
static int mavlink_dev_ioctl(struct file *filep, int cmd, unsigned long arg);
}
和我们想的一样的,MAVLINK_LOG_DEVICE设备节点注册了mavlink的静态函数,这样就保证了,mavlink这个类,只会注册一个MAVLINK_LOG的设备节点,通过mavlink_dev_ioctl这个函数,传入this指针,在类中的静态函数mavlink_dev_ioctl,访问类的实例化对象的成员
- 应用实例
commander中打开设备节点MAVLINK_LOG_DEVICE
static int mavlink_fd = 0; //静态变量
mavlink_fd = px4_open(MAVLINK_LOG_DEVICE, 0);
calib_ret = do_gyro_calibration(mavlink_fd, false);
calib_ret = do_accel_calibration(mavlink_fd);
3. MavlinkStream的实现
在mavlink发送中,每一个功能是1个mavlink流。
class MavlinkStreamAgriBigdata : public MavlinkStream
-> static MavlinkStream *new_instance(Mavlink *mavlink)
{
return new MavlinkStreamAgriBigdata(mavlink);
}
public MavlinkStream {
protected:
Mavlink *_mavlink; //父类中,指定了每一个mavlink的对象
}
3. 1 流的list
class StreamListItem {
public:
MavlinkStream* (*new_instance)(Mavlink *mavlink);
const char* (*get_name)();
StreamListItem(MavlinkStream* (*inst)(Mavlink *mavlink), const char* (*name)()) :
new_instance(inst),
get_name(name) {};
~StreamListItem() {};
};
3.2 创建好了,就可以直接使用数组,进行访问了
new StreamListItem(&MavlinkStreamHeartbeat::new_instance, &MavlinkStreamHeartbeat::get_name_static),
3.3 通过名字进行,和发送的间隔进行决定是否,创建这个流,同时设置这个时间间隔
if (strcmp(stream_name, streams_list[i]->get_name()) == 0) {
/* create new instance */
stream = streams_list[i]->new_instance(this);
stream->set_interval(interval);
3.4 mavlink多通道原理
每个mavlink都会有一份stream。那么,获取同一个orb,同时发出。
每个stream中,也不需要判断是否,由于没有分出来一个具体的函数,所以功能都是一样