第二章 第七节mavlink_log实现原理 补充说明 闫刚

在第二章 第七节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中,也不需要判断是否,由于没有分出来一个具体的函数,所以功能都是一样

猜你喜欢

转载自blog.csdn.net/yangang185/article/details/81296121