Mavlink_main.cpp源码学习
- int mavlink_main(int argc, char *argv[])
- {
- if (argc < 2) {
- usage(); //使用说明
- return 1;
- }
- if (!strcmp(argv[1], "start")) { //在这里启动了mavlink
- return Mavlink::start(argc, argv);
- } else if (!strcmp(argv[1], "stop")) { //命令是stop-all
- PX4_WARN("mavlink stop is deprecated, use stop-all instead");
- usage();
- return 1;
- } else if (!strcmp(argv[1], "stop-all")) {
- return Mavlink::destroy_all_instances(); //关闭start里创建的任务
- } else if (!strcmp(argv[1], "status")) {
- return Mavlink::get_status_all_instances(); //打印start中创建的任务信息
- } else if (!strcmp(argv[1], "stream")) {
- return Mavlink::stream_command(argc, argv);
- } else if (!strcmp(argv[1], "boot_complete")) {
- Mavlink::set_boot_complete();
- return 0;
- } else {
- usage();
- return 1;
- }
- return 0;
- }
- int
- Mavlink::start(int argc, char *argv[])
- {
- MavlinkULog::initialize();
- MavlinkCommandSender::initialize();
- // Wait for the instance count to go up one
- // before returning to the shell
- int ic = Mavlink::instance_count(); //确认不超过最大个数
- if (ic == Mavlink::MAVLINK_MAX_INSTANCES) {
- warnx("Maximum MAVLink instance count of %d reached.",
- (int)Mavlink::MAVLINK_MAX_INSTANCES);
- return 1;
- }
- // Instantiate thread
- char buf[24];
- sprintf(buf, "mavlink_if%d", ic);
- // This is where the control flow splits
- // between the starting task and the spawned
- // task - start_helper() only returns
- // when the started task exits. //这里创建了start_helper的守护进程
- px4_task_spawn_cmd(buf,
- SCHED_DEFAULT,
- SCHED_PRIORITY_DEFAULT,
- 2500,
- (px4_main_t)&Mavlink::start_helper,
- (char *const *)argv);
- // Ensure that this shell command
- // does not return before the instance
- // is fully initialized. As this is also
- // the only path to create a new instance,
- // this is effectively a lock on concurrent
- // instance starting. XXX do a real lock.
- // Sleep 500 us between each attempt
- const unsigned sleeptime = 500;
- // Wait 100 ms max for the startup.
- const unsigned limit = 100 * 1000 / sleeptime;
- unsigned count = 0;
- while (ic == Mavlink::instance_count() && count < limit) { //轮询等待
- ::usleep(sleeptime);
- count++;
- }
- return OK;
- }
- int
- Mavlink::task_main(int argc, char *argv[])
- {
- int ch;
- _baudrate = 57600;
- _datarate = 0;
- _mode = MAVLINK_MODE_NORMAL;
- #ifdef __PX4_NUTTX
- /* the NuttX optarg handler does not
- * ignore argv[0] like the POSIX handler
- * does, nor does it deal with non-flag
- * verbs well. So we remove the application
- * name and the verb.
- */
- argc -= 2;
- argv += 2;
- #endif
- /* don't exit from getopt loop to leave getopt global variables in consistent state,
- * set error flag instead */
- bool err_flag = false;
- int myoptind = 1;
- const char *myoptarg = nullptr;
- #ifdef __PX4_POSIX
- char *eptr;
- int temp_int_arg;
- #endif
- while ((ch = px4_getopt(argc, argv, "b:r:d:u:o:m:t:fvwx", &myoptind, &myoptarg)) != EOF) { //这里把argv[0]后面的都反了一下
- switch (ch) {
- case 'b':
- _baudrate = strtoul(myoptarg, nullptr, 10); //设置波特率
- if (_baudrate < 9600 || _baudrate > 3000000) {
- warnx("invalid baud rate '%s'", myoptarg);
- err_flag = true;
- }
- break;
- case 'r':
- _datarate = strtoul(myoptarg, nullptr, 10); //设置传输速率
- if (_datarate < 10 || _datarate > MAX_DATA_RATE) {
- warnx("invalid data rate '%s'", myoptarg);
- err_flag = true;
- }
- break;
- case 'd':
- _device_name = myoptarg; //选择串口设备
- set_protocol(SERIAL);
- break;
- #ifdef __PX4_POSIX
- case 'u': //选择UDP网络本地
- temp_int_arg = strtoul(myoptarg, &eptr, 10);
- if (*eptr == '\0') {
- _network_port = temp_int_arg;
- set_protocol(UDP);
- } else {
- warnx("invalid data udp_port '%s'", myoptarg);
- err_flag = true;
- }
- break;
- case 'o': //选择UDP网络远程
- temp_int_arg = strtoul(myoptarg, &eptr, 10);
- if (*eptr == '\0') {
- _remote_port = temp_int_arg;
- set_protocol(UDP);
- } else {
- warnx("invalid remote udp_port '%s'", myoptarg);
- err_flag = true;
- }
- break;
- case 't': //伙伴IP,通过MAV_BROADCAST参数广播
- _src_addr.sin_family = AF_INET;
- if (inet_aton(myoptarg, &_src_addr.sin_addr)) {
- _src_addr_initialized = true;
- } else {
- warnx("invalid partner ip '%s'", myoptarg);
- err_flag = true;
- }
- break;
- #else
- case 'u':
- case 'o':
- case 't':
- warnx("UDP options not supported on this platform");
- err_flag = true;
- break;
- #endif
- // case 'e':
- // mavlink_link_termination_allowed = true;
- // break;
- case 'm': //设置默认的stream和rates
- if (strcmp(myoptarg, "custom") == 0) {
- _mode = MAVLINK_MODE_CUSTOM;
- } else if (strcmp(myoptarg, "camera") == 0) {
- // left in here for compatibility
- _mode = MAVLINK_MODE_ONBOARD;
- } else if (strcmp(myoptarg, "onboard") == 0) {
- _mode = MAVLINK_MODE_ONBOARD;
- } else if (strcmp(myoptarg, "osd") == 0) {
- _mode = MAVLINK_MODE_OSD;
- } else if (strcmp(myoptarg, "magic") == 0) {
- _mode = MAVLINK_MODE_MAGIC;
- } else if (strcmp(myoptarg, "config") == 0) {
- _mode = MAVLINK_MODE_CONFIG;
- } else if (strcmp(myoptarg, "iridium") == 0) {
- _mode = MAVLINK_MODE_IRIDIUM;
- _rstatus.type = telemetry_status_s::TELEMETRY_STATUS_RADIO_TYPE_IRIDIUM;
- }
- break;
- case 'f': //消息可发给其他mavlink接口
- _forwarding_on = true;
- break;
- case 'v': //verbos output
- _verbose = true;
- break;
- case 'w': //等待发送直到接收到第一个消息
- _wait_to_transmit = true;
- break;
- case 'x': //开启ftp
- _ftp_on = true;
- break;
- default: //其他应该是错误的
- err_flag = true;
- break;
- }
- }
- if (err_flag) {
- usage();
- return PX4_ERROR;
- }
- if (_datarate == 0) {
- /* convert bits to bytes and use 1/2 of bandwidth by default */
- _datarate = _baudrate / 20;
- }
- if (_datarate > MAX_DATA_RATE) {
- _datarate = MAX_DATA_RATE;
- }
- if (get_protocol() == SERIAL) {
- if (Mavlink::instance_exists(_device_name, this)) {
- warnx("%s already running", _device_name);
- return PX4_ERROR;
- }
- PX4_INFO("mode: %s, data rate: %d B/s on %s @ %dB",
- mavlink_mode_str(_mode), _datarate, _device_name, _baudrate);
- /* flush stdout in case MAVLink is about to take it over */ //清空输出缓冲区,并把缓冲区内容输出
- fflush(stdout);
- /* default values for arguments */ //默认的串口值
- _uart_fd = mavlink_open_uart(_baudrate, _device_name);
- if (_uart_fd < 0 && _mode != MAVLINK_MODE_CONFIG) {
- warn("could not open %s", _device_name);
- return PX4_ERROR;
- } else if (_uart_fd < 0 && _mode == MAVLINK_MODE_CONFIG) {
- /* the config link is optional */
- return OK;
- }
- } else if (get_protocol() == UDP) {
- if (Mavlink::get_instance_for_network_port(_network_port) != nullptr) {
- warnx("port %d already occupied", _network_port);
- return PX4_ERROR;
- }
- PX4_INFO("mode: %s, data rate: %d B/s on udp port %hu remote port %hu",
- mavlink_mode_str(_mode), _datarate, _network_port, _remote_port);
- }
- /* initialize send mutex */ //初始化发送mutex
- pthread_mutex_init(&_send_mutex, nullptr);
- /* if we are passing on mavlink messages, we need to prepare a buffer for this instance */ //如果我们在传送mavlink消息,我们需要准备一个buffer作为接口
- if (_forwarding_on || _ftp_on) {
- /* initialize message buffer if multiplexing is on or its needed for FTP. //如果multiplexing打开了或者需要FTP,初始化消息buffer。
- * make space for two messages plus off-by-one space as we use the empty element //为两个消息提供足够的空间,并加上off-by-one空间,作为我们使用的空元素
- * marker ring buffer approach. //标记ring buffer方法
- */
- if (OK != message_buffer_init(2 * sizeof(mavlink_message_t) + 1)) { //起始申请了3个message空间,第三个应该是空的。防止off-by-one
- warnx("msg buf:");
- return 1;
- }
- /* initialize message buffer mutex */ //初始化message buffer mutex
- pthread_mutex_init(&_message_buffer_mutex, nullptr);
- }
- /* Initialize system properties */ //初始化系统内容
- mavlink_update_system();
- /* start the MAVLink receiver */ //开始接收mavlink
- MavlinkReceiver::receive_start(&_receive_thread, this);
- MavlinkOrbSubscription *param_sub = add_orb_subscription(ORB_ID(parameter_update));
- uint64_t param_time = 0;
- MavlinkOrbSubscription *status_sub = add_orb_subscription(ORB_ID(vehicle_status));
- uint64_t status_time = 0;
- MavlinkOrbSubscription *ack_sub = add_orb_subscription(ORB_ID(vehicle_command_ack));
- /* We don't want to miss the first advertise of an ACK, so we subscribe from the //我们不想要丢失最开始ACK的advertise,所以我们topic退出后,还会发送一段时间
- * beginning and not just when the topic exists. */
- ack_sub->subscribe_from_beginning(true);
- uint64_t ack_time = 0;
- MavlinkOrbSubscription *mavlink_log_sub = add_orb_subscription(ORB_ID(mavlink_log));
- struct vehicle_status_s status;
- status_sub->update(&status_time, &status);
- struct vehicle_command_ack_s command_ack;
- ack_sub->update(&ack_time, &command_ack);
- /* add default streams depending on mode */ //根据mode,增加默认的streams
- if (_mode != MAVLINK_MODE_IRIDIUM) {
- /* HEARTBEAT is constant rate stream, rate never adjusted */
- configure_stream("HEARTBEAT", 1.0f);
- /* STATUSTEXT stream is like normal stream but gets messages from logbuffer instead of uORB */
- configure_stream("STATUSTEXT", 20.0f);
- /* COMMAND_LONG stream: use high rate to avoid commands skipping */
- configure_stream("COMMAND_LONG", 100.0f);
- }
- switch (_mode) {
- case MAVLINK_MODE_NORMAL:
- configure_stream("SYS_STATUS", 1.0f);
- configure_stream("EXTENDED_SYS_STATE", 1.0f);
- configure_stream("HIGHRES_IMU", 1.5f);
- configure_stream("ATTITUDE", 20.0f);
- configure_stream("RC_CHANNELS", 5.0f);
- configure_stream("SERVO_OUTPUT_RAW_0", 1.0f);
- configure_stream("ALTITUDE", 1.0f);
- configure_stream("GPS_RAW_INT", 1.0f);
- configure_stream("ADSB_VEHICLE", 2.0f);
- configure_stream("COLLISION", 2.0f);
- configure_stream("DISTANCE_SENSOR", 0.5f);
- configure_stream("OPTICAL_FLOW_RAD", 1.0f);
- configure_stream("VISION_POSITION_ESTIMATE", 1.0f);
- configure_stream("ESTIMATOR_STATUS", 0.5f);
- configure_stream("NAV_CONTROLLER_OUTPUT", 1.5f);
- configure_stream("GLOBAL_POSITION_INT", 5.0f);
- configure_stream("LOCAL_POSITION_NED", 1.0f);
- configure_stream("POSITION_TARGET_LOCAL_NED", 1.5f);
- configure_stream("POSITION_TARGET_GLOBAL_INT", 1.5f);
- configure_stream("ATTITUDE_TARGET", 2.0f);
- configure_stream("HOME_POSITION", 0.5f);
- configure_stream("NAMED_VALUE_FLOAT", 1.0f);
- configure_stream("VFR_HUD", 4.0f);
- configure_stream("WIND_COV", 1.0f);
- break;
- case MAVLINK_MODE_ONBOARD:
- configure_stream("SYS_STATUS", 5.0f);
- configure_stream("EXTENDED_SYS_STATE", 5.0f);
- configure_stream("HIGHRES_IMU", 50.0f);
- configure_stream("ATTITUDE", 250.0f);
- configure_stream("ATTITUDE_QUATERNION", 50.0f);
- configure_stream("RC_CHANNELS", 20.0f);
- configure_stream("SERVO_OUTPUT_RAW_0", 10.0f);
- configure_stream("ALTITUDE", 10.0f);
- configure_stream("GPS_RAW_INT", 5.0f);
- configure_stream("ADSB_VEHICLE", 10.0f);
- configure_stream("COLLISION", 10.0f);
- configure_stream("DISTANCE_SENSOR", 10.0f);
- configure_stream("OPTICAL_FLOW_RAD", 10.0f);
- configure_stream("VISION_POSITION_ESTIMATE", 10.0f);
- configure_stream("ESTIMATOR_STATUS", 1.0f);
- configure_stream("NAV_CONTROLLER_OUTPUT", 10.0f);
- configure_stream("GLOBAL_POSITION_INT", 50.0f);
- configure_stream("LOCAL_POSITION_NED", 30.0f);
- configure_stream("POSITION_TARGET_GLOBAL_INT", 10.0f);
- configure_stream("ATTITUDE_TARGET", 10.0f);
- configure_stream("HOME_POSITION", 0.5f);
- configure_stream("NAMED_VALUE_FLOAT", 10.0f);
- configure_stream("VFR_HUD", 10.0f);
- configure_stream("WIND_COV", 10.0f);
- configure_stream("POSITION_TARGET_LOCAL_NED", 10.0f);
- configure_stream("SYSTEM_TIME", 1.0f);
- configure_stream("TIMESYNC", 10.0f);
- configure_stream("CAMERA_CAPTURE", 2.0f);
- //camera trigger is rate limited at the source, do not limit here
- configure_stream("CAMERA_TRIGGER", 500.0f);
- configure_stream("CAMERA_IMAGE_CAPTURED", 5.0f);
- configure_stream("ACTUATOR_CONTROL_TARGET0", 10.0f);
- break;
- case MAVLINK_MODE_OSD:
- configure_stream("SYS_STATUS", 5.0f);
- configure_stream("EXTENDED_SYS_STATE", 1.0f);
- configure_stream("ATTITUDE", 25.0f);
- configure_stream("RC_CHANNELS", 5.0f);
- configure_stream("SERVO_OUTPUT_RAW_0", 1.0f);
- configure_stream("ALTITUDE", 1.0f);
- configure_stream("GPS_RAW_INT", 1.0f);
- configure_stream("ESTIMATOR_STATUS", 1.0f);
- configure_stream("GLOBAL_POSITION_INT", 10.0f);
- configure_stream("ATTITUDE_TARGET", 10.0f);
- configure_stream("HOME_POSITION", 0.5f);
- configure_stream("VFR_HUD", 25.0f);
- configure_stream("WIND_COV", 2.0f);
- configure_stream("SYSTEM_TIME", 1.0f);
- break;
- case MAVLINK_MODE_MAGIC:
- //stream nothing
- break;
- case MAVLINK_MODE_CONFIG:
- // Enable a number of interesting streams we want via USB
- configure_stream("SYS_STATUS", 1.0f);
- configure_stream("EXTENDED_SYS_STATE", 2.0f);
- configure_stream("HIGHRES_IMU", 50.0f);
- configure_stream("ATTITUDE", 50.0f);
- configure_stream("ATTITUDE_QUATERNION", 50.0f);
- configure_stream("RC_CHANNELS", 10.0f);
- configure_stream("SERVO_OUTPUT_RAW_0", 20.0f);
- configure_stream("SERVO_OUTPUT_RAW_1", 20.0f);
- configure_stream("ALTITUDE", 10.0f);
- configure_stream("GPS_RAW_INT", 10.0f);
- configure_stream("ADSB_VEHICLE", 20.0f);
- configure_stream("COLLISION", 20.0f);
- configure_stream("DISTANCE_SENSOR", 10.0f);
- configure_stream("OPTICAL_FLOW_RAD", 10.0f);
- configure_stream("VISION_POSITION_ESTIMATE", 10.0f);
- configure_stream("ESTIMATOR_STATUS", 5.0f);
- configure_stream("NAV_CONTROLLER_OUTPUT", 10.0f);
- configure_stream("GLOBAL_POSITION_INT", 10.0f);
- configure_stream("LOCAL_POSITION_NED", 30.0f);
- configure_stream("POSITION_TARGET_GLOBAL_INT", 10.0f);
- configure_stream("ATTITUDE_TARGET", 8.0f);
- configure_stream("HOME_POSITION", 0.5f);
- configure_stream("NAMED_VALUE_FLOAT", 50.0f);
- configure_stream("VFR_HUD", 20.0f);
- configure_stream("WIND_COV", 10.0f);
- configure_stream("CAMERA_TRIGGER", 500.0f);
- configure_stream("CAMERA_IMAGE_CAPTURED", 5.0f);
- configure_stream("ACTUATOR_CONTROL_TARGET0", 30.0f);
- configure_stream("MANUAL_CONTROL", 5.0f);
- break;
- case MAVLINK_MODE_IRIDIUM:
- configure_stream("HIGH_LATENCY", 0.1f);
- break;
- default:
- break;
- }
- /* set main loop delay depending on data rate to minimize CPU overhead */ //根据data reate减少CPU开销,设置主要loop延迟
- _main_loop_delay = (MAIN_LOOP_DELAY * 1000) / _datarate;
- /* hard limit to 500 Hz at max */ //硬界限到500Hz最大
- if (_main_loop_delay < 2000) {
- _main_loop_delay = 2000;
- }
- /* hard limit to 100 Hz at least */ //最小100Hz
- if (_main_loop_delay > 10000) {
- _main_loop_delay = 10000;
- }
- /* now the instance is fully initialized and we can bump the instance count */ //现在实例完全初始化,并且我们能bump实例计数
- LL_APPEND(_mavlink_instances, this);
- /* init socket if necessary */ //如果需要初始化socket
- if (get_protocol() == UDP) {
- init_udp();
- }
- /* if the protocol is serial, we send the system version blindly */ //如果协议是攒口,发送系统版本blindy(盲目的)
- if (get_protocol() == SERIAL) {
- send_autopilot_capabilites();
- }
- while (!_task_should_exit) {
- /* main loop */ //主循环
- usleep(_main_loop_delay);
- perf_begin(_loop_perf);
- hrt_abstime t = hrt_absolute_time();
- update_rate_mult();
- if (param_sub->update(¶m_time, nullptr)) {
- /* parameters updated */ //参数更新
- mavlink_update_system();
- }
- /* radio config check */ //比例设置确认
- if (_uart_fd >= 0 && _radio_id != 0 && _rstatus.type == telemetry_status_s::TELEMETRY_STATUS_RADIO_TYPE_3DR_RADIO) {
- /* request to configure radio and radio is present */
- FILE *fs = fdopen(_uart_fd, "w");
- if (fs) {
- /* switch to AT command mode */ //转换到AT命令模式
- usleep(1200000);
- fprintf(fs, "+++\n");
- usleep(1200000);
- if (_radio_id > 0) {
- /* set channel */
- fprintf(fs, "ATS3=%u\n", _radio_id);
- usleep(200000);
- } else {
- /* reset to factory defaults */ //重置factory defaults
- fprintf(fs, "AT&F\n");
- usleep(200000);
- }
- /* write config */ //写配置
- fprintf(fs, "AT&W");
- usleep(200000);
- /* reboot */ //重启
- fprintf(fs, "ATZ");
- usleep(200000);
- // XXX NuttX suffers from a bug where
- // fclose() also closes the fd, not just
- // the file stream. Since this is a one-time
- // config thing, we leave the file struct
- // allocated.
- #ifndef __PX4_NUTTX
- fclose(fs);
- #endif
- } else {
- PX4_WARN("open fd %d failed", _uart_fd);
- }
- /* reset param and save */ //重设param并且保存
- _radio_id = 0;
- param_set(_param_radio_id, &_radio_id);
- }
- if (status_sub->update(&status_time, &status)) {
- /* switch HIL mode if required */ //转换HIL模式如果需要
- set_hil_enabled(status.hil_state == vehicle_status_s::HIL_STATE_ON);
- set_manual_input_mode_generation(status.rc_input_mode == vehicle_status_s::RC_IN_MODE_GENERATED);
- }
- /* send command ACK */ //发送ACK命令
- uint16_t current_command_ack = 0;
- if (ack_sub->update(&ack_time, &command_ack)) {
- mavlink_command_ack_t msg;
- msg.result = command_ack.result;
- msg.command = command_ack.command;
- current_command_ack = command_ack.command;
- mavlink_msg_command_ack_send_struct(get_channel(), &msg);
- }
- struct mavlink_log_s mavlink_log;
- if (mavlink_log_sub->update_if_changed(&mavlink_log)) {
- _logbuffer.put(&mavlink_log);
- }
- /* check for shell output */ //确认作为shell输出
- if (_mavlink_shell && _mavlink_shell->available() > 0) {
- if (get_free_tx_buf() >= MAVLINK_MSG_ID_SERIAL_CONTROL_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES) {
- mavlink_serial_control_t msg;
- msg.baudrate = 0;
- msg.flags = SERIAL_CONTROL_FLAG_REPLY;
- msg.timeout = 0;
- msg.device = SERIAL_CONTROL_DEV_SHELL;
- msg.count = _mavlink_shell->read(msg.data, sizeof(msg.data));
- mavlink_msg_serial_control_send_struct(get_channel(), &msg);
- }
- }
- /* check for ulog streaming messages */ //确认作为ulog streaming消息
- if (_mavlink_ulog) {
- if (_mavlink_ulog_stop_requested) {
- _mavlink_ulog->stop();
- _mavlink_ulog = nullptr;
- _mavlink_ulog_stop_requested = false;
- } else {
- if (current_command_ack == vehicle_command_s::VEHICLE_CMD_LOGGING_START) {
- _mavlink_ulog->start_ack_received();
- }
- int ret = _mavlink_ulog->handle_update(get_channel());
- if (ret < 0) { //abort the streaming on error
- if (ret != -1) {
- PX4_WARN("mavlink ulog stream update failed, stopping (%i)", ret);
- }
- _mavlink_ulog->stop();
- _mavlink_ulog = nullptr;
- }
- }
- }
- /* check for requested subscriptions */ //确认requested subscriptions
- if (_subscribe_to_stream != nullptr) {
- if (OK == configure_stream(_subscribe_to_stream, _subscribe_to_stream_rate)) {
- if (_subscribe_to_stream_rate > 0.0f) {
- if (get_protocol() == SERIAL) {
- PX4_DEBUG("stream %s on device %s enabled with rate %.1f Hz", _subscribe_to_stream, _device_name,
- (double)_subscribe_to_stream_rate);
- } else if (get_protocol() == UDP) {
- PX4_DEBUG("stream %s on UDP port %d enabled with rate %.1f Hz", _subscribe_to_stream, _network_port,
- (double)_subscribe_to_stream_rate);
- }
- } else {
- if (get_protocol() == SERIAL) {
- PX4_INFO("stream %s on device %s disabled", _subscribe_to_stream, _device_name);
- } else if (get_protocol() == UDP) {
- PX4_INFO("stream %s on UDP port %d disabled", _subscribe_to_stream, _network_port);
- }
- }
- } else {
- if (get_protocol() == SERIAL) {
- PX4_WARN("stream %s on device %s not found", _subscribe_to_stream, _device_name);
- } else if (get_protocol() == UDP) {
- PX4_WARN("stream %s on UDP port %d not found", _subscribe_to_stream, _network_port);
- }
- }
- _subscribe_to_stream = nullptr;
- }
- /* update streams */ //更新流
- MavlinkStream *stream;
- LL_FOREACH(_streams, stream) {
- stream->update(t);
- }
- /* pass messages from other UARTs or FTP worker */ //传递消息从其他UARTs或FTP 队列
- if (_forwarding_on || _ftp_on) {
- bool is_part;
- uint8_t *read_ptr;
- uint8_t *write_ptr;
- pthread_mutex_lock(&_message_buffer_mutex);
- int available = message_buffer_get_ptr((void **)&read_ptr, &is_part);
- pthread_mutex_unlock(&_message_buffer_mutex);
- if (available > 0) {
- // Reconstruct message from buffer
- mavlink_message_t msg;
- write_ptr = (uint8_t *)&msg;
- // Pull a single message from the buffer
- size_t read_count = available;
- if (read_count > sizeof(mavlink_message_t)) {
- read_count = sizeof(mavlink_message_t);
- }
- memcpy(write_ptr, read_ptr, read_count);
- // We hold the mutex until after we complete the second part of the buffer. If we don
Mavlink_main.cpp源码学习的更多相关文章
- caffe源码学习之Proto数据格式【1】
前言: 由于业务需要,接触caffe已经有接近半年,一直忙着阅读各种论文,重现大大小小的模型. 期间也总结过一些caffe源码学习笔记,断断续续,这次打算系统的记录一下caffe源码学习笔记,巩固一下 ...
- mongo源码学习(四)服务入口点ServiceEntryPoint
在上一篇博客mongo源码学习(三)请求接收传输层中,稍微分析了一下TransportLayer的作用,这篇来看下ServiceEntryPoint是怎么做的. 首先ServiceEntryPoint ...
- mongo源码学习(三)请求接收传输层
在上一篇博客中(mongo源码学习(二)db.cpp之mongoDbMain方法分析),我们把db.cpp中的mongoDbMain的执行过程分析了一下,最后会调用initAndListen(serv ...
- stl源码学习(版本2.91)--list
stl源码学习(版本2.91)--list 一,阅读list()构造函数的收获 1,默认构造函数的作用和被调用的时机 struct no{ no(int i){} //no(){ // std::co ...
- Qt Creator 源码学习笔记03,大型项目如何管理工程
阅读本文大概需要 6 分钟 一个项目随着功能开发越来越多,项目必然越来越大,工程管理成本也越来越高,后期维护成本更高.如何更好的组织管理工程,是非常重要的 今天我们来学习下 Qt Creator 是如 ...
- Qt Creator 源码学习笔记04,多插件实现原理分析
阅读本文大概需要 8 分钟 插件听上去很高大上,实际上就是一个个动态库,动态库在不同平台下后缀名不一样,比如在 Windows下以.dll结尾,Linux 下以.so结尾 开发插件其实就是开发一个动态 ...
- [算法2-数组与字符串的查找与匹配] (.NET源码学习)
[算法2-数组与字符串的查找与匹配] (.NET源码学习) 关键词:1. 数组查找(算法) 2. 字符串查找(算法) 3. C#中的String(源码) 4. 特性Attribute 与内 ...
- Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结
2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...
- jQuery源码学习感想
还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...
随机推荐
- Servlet 第一天
package com.servlet; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet. ...
- WORM Worm worm 毛毛虫爬树爬树~
对于动态规划,我也就不多说了.因为还不会, 每个题都不一样,但大致原则是一样的.抓住题意, 本题:n棵树,毛毛虫在m分钟内从p到t的路线种数,毛毛虫只可以向左右相邻位置走. 中心代码: for(i = ...
- php面试专题---2、常量及数据类型考点
php面试专题---2.常量及数据类型考点 一.总结 一句话总结: 变量为null和变量判断为false的情况需要仔细注意下 1.PHP中字符串可以使用哪三种定义方法以及各自的区别是什么? 单引号:不 ...
- ANTLR4在windows10下的安装
1.下载ANTLR ①.从官网下载到最新版本的antlr-4.7.1-complete.jar.我下载的时候最新版本是4.7.1. ②.选择路径保存,为方便之后修改环境变量.我的下载目录为E:\Ant ...
- Xcode 10如何打包ipa包?
参考: https://www.jianshu.com/p/0421b3fd2470 前置条件 首先导入证书和配置文件 具体操作步骤: product>>Archive 如图所示,选择Di ...
- Linux对用户态的动态内存管理
Linux对内核态内存分配请求与用户态内存分配请求处理上分别对待 Linux本身信任自己,因此Linux内核请求分配多少内存,就会马上分配相同数量的内存出来. 但内核本身不相信应用程序,而且通常应用程 ...
- 学习php的步骤是什么?
PHP应该学什么,如何学好PHP (注:原文来自传智播客) 一些共性问题,大致是: 1. 应该怎样学习PHP,学习的顺序是怎样的? 2. PHP学好后,可以做什么事情? 3. 听得懂课,但是一旦自己独 ...
- php Connection timed out after 30000 milliseconds
function HttpRequest($url, $params, $method = 'GET', $header = array(), $bEncode = true){ $opts = ar ...
- springCloud的使用09-----高可用的注册中心
思路:创建多个注册中心,在他们的配置文件中配置相互之间的注册 1 在eureka-server项目的resources目录下创建两个配置文件application-peer1.yml和applicat ...
- Libgdx中TextButton的一些思考
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/caihongshijie6/article/details/37566183 由于有 ...