APM代码中MAVLINK的初步分析。

来源:互联网 发布:麒麟linux 编辑:程序博客网 时间:2024/04/29 23:31

                最近在看APM代码中的MAVLINK部分。这里记录下一些分析结果,有同样看这部分的同志请一起把这部分知识补全。

 

                首先在MAVLink 的主要功能是通过在ArduCopter.cpp中的三个“任务”完成的。

                SCHED_TASK(gcs_send_heartbeat,     1,   110),
                SCHED_TASK(gcs_send_deferred,    50,    550),
                SCHED_TASK(gcs_data_stream_send, 50,    550),

                这3个任务,第一个心跳任务是1hz,第二个和第三个是50hz。

                除了这三个任务在初始化部分还有一个MAVlink通讯任务。

如图所示在初始化中定义了一个mavlink_delay_cb_static()。这个部分具体什么用途没仔细分析,大体就是初始化部分与地面站沟通用的。

 

                在初始化Copter::init_ardupilot()中,还有一部分是初始化MAVLINK与硬件串口之间联系的函数。

  // init the GCS connected to the console
    gcs[0].setup_uart(serial_manager,AP_SerialManager::SerialProtocol_Console, 0);

    // init telemetry port
    gcs[1].setup_uart(serial_manager,AP_SerialManager::SerialProtocol_MAVLink, 0);
    // setup serial port for telem2
    gcs[2].setup_uart(serial_manager, AP_SerialManager::SerialProtocol_MAVLink,1);
    // setup serial port for fourthtelemetry port (not used by default)
    gcs[3].setup_uart(serial_manager,AP_SerialManager::SerialProtocol_MAVLink, 2);

第一个gcs通道表示初始化串口为控制台接口

第二gcs通道到第四gcs通道用来初始化MAVLINK通道。在具体内容,还没有去分析暂时放这里。

  再回到gcs_send_heartbeat,gcs_send_deferred,gcs_data_stream_send这三个任务。第一个任务和第二个任务先不管。看的第三个任务

voidCopter::gcs_data_stream_send(void)
{

    for (uint8_t i=0; i<num_gcs; i++){
        if (gcs[i].initialised){
           gcs[i].data_stream_send();
        }
    }
}

这个函数是主要负责和地面站的通讯。

num_gcs看到定义是static const uint8_t num_gcs = MAVLINK_COMM_NUM_BUFFERS;

在追本溯源可以看到#defineMAVLINK_COMM_NUM_BUFFERS 2

这里可以看出主要和地面站通讯的gcs通道是通道gcs[0]和通道gcs[1].

在GCS_MAVLINK::data_stream_send(void)中可以看到是通过函数bool GCS_MAVLINK::stream_trigger(enum streams stream_num)

来确定当前应该发送那个消息的,没仔细分析,估计是将发送周期平均分配下,每个通道每个消息的间隔都是500ms。

消息组在enum ap_message  {………….}这个里面分配的。

通过data_stream_send 里面调用了try_send_message发送消息。

在try_send_message函数中,通过switch(id) 选择要发送的消息组(就是enum ap_message )。

继续看其中一个消息组例如

case MSG_EXTENDED_STATUS1:

        // send extended status only oncevehicle has been initialised

        // to avoid unnecessary errors beingreported to user

        if (copter.ap.initialised) {

            CHECK_PAYLOAD_SIZE(SYS_STATUS);

            copter.send_extended_status1(chan);

            CHECK_PAYLOAD_SIZE(POWER_STATUS);

           copter.gcs[chan-MAVLINK_COMM_0].send_power_status();

        }

        break;

这个里面的NOINLINE void Copter::send_extended_status1(mavlink_channel_t chan))函数中,

可以看到最终是通过_mav_finalize_message_chan_send(…..)这个函数对消息打包成帧,

而在_mav_finalize_message_chan_send(…..)中是有函数_mavlink_send_uart//最终发送。

暂时分析到这里告一段落了。大体结构如此,再具体的内容,以后详细分析后在补充,希望哪位大侠可以分享下经验,把这部分细节补充更完善。


1 0
原创粉丝点击