PX4 IO [15] mixer

2023-05-16

PX4 IO [15] mixer

PX4 IO [15] mixer
                                                                             -------- 转载请注明出处 
                                                                             -------- 更多笔记请访问我的博客:merafour.blog.163.com 

                                                                             -------- 2015-1-5.冷月追风

                                                                             -------- email:merafour@163.com 



    看过了 IO的输入,我们现在来看看 IO中是怎么把信号输出的。 
    这个我们当然得先知道在 fmu中是怎么往 IO发这些输出数据的。 
    回过头去看第十一篇笔记,我们会看到 " AP_MotorsMatrix::output_test"函数的源码如下: 

// output_test - spin a motor at the pwm value specified
//  motor_seq is the motor's sequence number from 1 to the number of motors on the frame
//  pwm value is an actual pwm value that will be output, normally in the range of 1000 ~ 2000
void AP_MotorsMatrix::output_test(uint8_t motor_seq, int16_t pwm)
{
    // exit immediately if not armed
    if (!_flags.armed) {
        return;
    }

    // loop through all the possible orders spinning any motors that match that description
    for (uint8_t i=0; i<AP_MOTORS_MAX_NUM_MOTORS; i++) {
        if (motor_enabled[i] && _test_order[i] == motor_seq) {
            // turn on this motor
            hal.rcout->write(pgm_read_byte(&_motor_to_channel_map[i]), pwm);
        }
    }
}


也就是说通过 " hal.rcout->write"接口下发数据。" rcout"类型为 "PX4RCOutput"。从前面的分析中我们知道 "PX4RCOutput"其实是通过设备文件对 px4io进行调用,最终调用的是 "PX4IO::write"函数,源码如下: 

ssize_t PX4IO::write(file * /*filp*/, const char *buffer, size_t len)
/* Make it obvious that file * isn't used here */
{
    unsigned count = len / 2;

    if (count > _max_actuators)
        count = _max_actuators;

    if (count > 0) {

        perf_begin(_perf_write);
        int ret = io_reg_set(PX4IO_PAGE_DIRECT_PWM, 0, (uint16_t *)buffer, count);
        perf_end(_perf_write);

        if (ret != OK)
            return ret;
    }

    return count * 2;
}


px4io在我们的 V2版本中通过串口跟 io板通信。所以两者通信的关键在于 "PX4IO_PAGE_DIRECT_PWM"这个宏, 

radiolink@ubuntu:~/apm$ grep -nr PX4IO_PAGE_DIRECT_PWM ./PX4Firmware/src/
./PX4Firmware/src/modules/px4iofirmware/protocol.h:258:#definePX4IO_PAGE_DIRECT_PWM                    54              /**< 0..CONFIG_ACTUATOR_COUNT-1 */
./PX4Firmware/src/modules/px4iofirmware/registers.c:284:        casePX4IO_PAGE_DIRECT_PWM:
./PX4Firmware/src/modules/px4iofirmware/registers.c:883:        casePX4IO_PAGE_DIRECT_PWM:
./PX4Firmware/src/drivers/px4io/px4io.cpp:2366:                         ret = io_reg_set(PX4IO_PAGE_DIRECT_PWM, channel, arg);
./PX4Firmware/src/drivers/px4io/px4io.cpp:2649:         int ret = io_reg_set(PX4IO_PAGE_DIRECT_PWM, 0, (uint16_t *)buffer, count);
radiolink@ubuntu:~/apm$

因为我们现在关注的是 io固件,所以我们现在要找的源码在 "registers.c"源文件中。可能我们觉得这里值应该出现一个 "case"语句,但这里却出现了两个,为什么?如果你去看源码你会看到实际上有一个 "registers_set"和一个 "registers_get"函数。当然 get函数我们没有使用,就不去关心。下面我们就来看看 set函数。

int registers_set(uint8_t page, uint8_t offset, const uint16_t *values, unsignednum_values)
{
    switch (page) {
  /* ... */
        /* handle raw PWM input */
    case PX4IO_PAGE_DIRECT_PWM:
        /* copy channel data */
        while ((offset < PX4IO_CONTROL_CHANNELS) && (num_values > 0)) {
            /* XXX range-check value? */
            r_page_servos[offset] = *values;
            offset++;
            num_values--;
            values++;
        }
        system_state.fmu_data_received_time = hrt_absolute_time();
        r_status_flags |= PX4IO_P_STATUS_FLAGS_FMU_OK | PX4IO_P_STATUS_FLAGS_RAW_PWM;
        break;

所以我们看到,在这里 set主要是数据拷贝动作。而我们现在要解决的是在把数据放到 "r_page_servos"数组中之后数据是怎样到大寄存器的。

radiolink@ubuntu:~/apm$ grep -nr r_page_servos ./PX4Firmware/src/modules/px4iofirmware/
./PX4Firmware/src/modules/px4iofirmware/px4io.h:76:externuint16_t                      r_page_servos[];        /* PX4IO_PAGE_SERVOS */
./PX4Firmware/src/modules/px4iofirmware/mixer.cpp:217:                  r_page_servos[i] = r_page_servo_failsafe[i];
./PX4Firmware/src/modules/px4iofirmware/mixer.cpp:220:                  r_page_actuators[i] = FLOAT_TO_REG((r_page_servos[i] - 1500) / 600.0f);
./PX4Firmware/src/modules/px4iofirmware/mixer.cpp:237:          pwm_limit_calc(should_arm, mixed, r_page_servo_disarmed, r_page_servo_control_min, r_page_servo_control_max, outputs, r_page_servos, &pwm_limit);
./PX4Firmware/src/modules/px4iofirmware/mixer.cpp:240:                  r_page_servos[i] = 0;
./PX4Firmware/src/modules/px4iofirmware/mixer.cpp:276:                  up_pwm_servo_set(i, r_page_servos[i]);
./PX4Firmware/src/modules/px4iofirmware/registers.c:107:uint16_t                r_page_servos[PX4IO_SERVO_COUNT];
./PX4Firmware/src/modules/px4iofirmware/registers.c:221: * PAGE 104 uses r_page_servos.
./PX4Firmware/src/modules/px4iofirmware/registers.c:291:                                r_page_servos[offset] = *values;
./PX4Firmware/src/modules/px4iofirmware/registers.c:864:                SELECT_PAGE(r_page_servos);
./PX4Firmware/src/modules/px4iofirmware/registers.c:884:                SELECT_PAGE(r_page_servos);
radiolink@ubuntu:~/apm$

去阅读源码我们就会发现, mixer.cpp中的结果均来自同一个函数: mixer_tick。该函数同样是在 Px4io.c中由 user_start调用。代码如下:

int user_start(int argc, char *argv[])
{
    /* ... */
    for (;;) {
        /* track the rate at which the loop is running */
        perf_count(loop_perf);
        /* kick the mixer */
        perf_begin(mixer_perf);
        mixer_tick();
        perf_end(mixer_perf);
        /* kick the control inputs */
        perf_begin(controls_perf);
        controls_tick();
        perf_end(controls_perf);

这样我们就只需要关心 mixer_tick函数即可。而该函数从头到尾超过 150行代码,我们在看源码的时候要将它拆成几段。

void mixer_tick(void)
{
    /* check that we are receiving fresh data from the FMU */
    if (hrt_elapsed_time(&system_state.fmu_data_received_time) > FMU_INPUT_DROP_LIMIT_US) {
        /* too long without FMU input, time to go to failsafe */
        if (r_status_flags & PX4IO_P_STATUS_FLAGS_FMU_OK) {
            isr_debug(1, "AP RX timeout");
        }
        r_status_flags &= ~(PX4IO_P_STATUS_FLAGS_FMU_OK);
        r_status_alarms |= PX4IO_P_STATUS_ALARMS_FMU_LOST;
    } else {
        r_status_flags |= PX4IO_P_STATUS_FLAGS_FMU_OK;
    }
#define FMU_INPUT_DROP_LIMIT_US        200000

这段代码并不难理解,是用来检测超时的。超时时间为 200ms。可能我们都会奇怪, user_start中的主循环执行一次会消耗 200ms吗?关于这点,我只能说目前我还没有去研究它是怎么控制循环的,暂时不予讨论。

    /* default to failsafe mixing */
    source = MIX_FAILSAFE;
    /*
     * Decide which set of controls we're using.
     */
    /* do not mix if RAW_PWM mode is on and FMU is good */
    if ((r_status_flags & PX4IO_P_STATUS_FLAGS_RAW_PWM) &&
            (r_status_flags & PX4IO_P_STATUS_FLAGS_FMU_OK)) {
        /* don't actually mix anything - we already have raw PWM values */
        source = MIX_NONE;
    } else {
        if (!(r_status_flags & PX4IO_P_STATUS_FLAGS_OVERRIDE) &&
             (r_status_flags & PX4IO_P_STATUS_FLAGS_FMU_OK) &&
             (r_status_flags & PX4IO_P_STATUS_FLAGS_MIXER_OK)) {
            /* mix from FMU controls */
            source = MIX_FMU;
        }
        if ( (r_status_flags & PX4IO_P_STATUS_FLAGS_OVERRIDE) &&
             (r_status_flags & PX4IO_P_STATUS_FLAGS_RC_OK) &&
             (r_status_flags & PX4IO_P_STATUS_FLAGS_MIXER_OK) &&
             !(r_setup_arming & PX4IO_P_SETUP_ARMING_RC_HANDLING_DISABLED) &&
             !(r_status_flags & PX4IO_P_STATUS_FLAGS_FMU_OK)) {
             /* if allowed, mix from RC inputs directly */
            source = MIX_OVERRIDE;
        } else     if ( (r_status_flags & PX4IO_P_STATUS_FLAGS_OVERRIDE) &&
             (r_status_flags & PX4IO_P_STATUS_FLAGS_RC_OK) &&
             (r_status_flags & PX4IO_P_STATUS_FLAGS_MIXER_OK) &&
             !(r_setup_arming & PX4IO_P_SETUP_ARMING_RC_HANDLING_DISABLED) &&
             (r_status_flags & PX4IO_P_STATUS_FLAGS_FMU_OK)) {
            /* if allowed, mix from RC inputs directly up to available rc channels */
            source = MIX_OVERRIDE_FMU_OK;
        }
    }
    /*
     * Set failsafe status flag depending on mixing source
     */
    if (source == MIX_FAILSAFE) {
        r_status_flags |= PX4IO_P_STATUS_FLAGS_FAILSAFE;
    } else {
        r_status_flags &= ~(PX4IO_P_STATUS_FLAGS_FAILSAFE);
    }

r_status_flags就是前面我们在 set函数中设置的标志,如果set函数被正常调用,那么到这里 source的值为 MIX_NONE。关于失控保护,正常情况下是可以忽略的。

    /*
     * Decide whether the servos should be armed right now.
     *
     * We must be armed, and we must have a PWM source; either raw from
     * FMU or from the mixer.
     *
     * XXX correct behaviour for failsafe may require an additional case
     * here.
     */
    should_arm = (
        /* IO initialised without error */   (r_status_flags & PX4IO_P_STATUS_FLAGS_INIT_OK)
        /* and IO is armed */           && (r_status_flags & PX4IO_P_STATUS_FLAGS_SAFETY_OFF)
        /* and FMU is armed */           && (
                                ((r_setup_arming & PX4IO_P_SETUP_ARMING_FMU_ARMED)
        /* and there is valid input via or mixer */         &&   (r_status_flags & PX4IO_P_STATUS_FLAGS_MIXER_OK) )
        /* or direct PWM is set */               || (r_status_flags & PX4IO_P_STATUS_FLAGS_RAW_PWM)
        /* or failsafe was set manually */     || ((r_setup_arming & PX4IO_P_SETUP_ARMING_FAILSAFE_CUSTOM) && !(r_status_flags & PX4IO_P_STATUS_FLAGS_FMU_OK))
                             )
    );
    should_always_enable_pwm = (r_setup_arming & PX4IO_P_SETUP_ARMING_ALWAYS_PWM_ENABLE)
                        && (r_status_flags & PX4IO_P_STATUS_FLAGS_INIT_OK)
                        && (r_status_flags & PX4IO_P_STATUS_FLAGS_FMU_OK);

这段代码注释说的比较清楚,是进行解锁检查的。说到解锁,我们都还没看 fmu是怎么解锁的,待会还真得看看。飞控通常都是要解锁之后才能飞的,这是出于安全考虑。我想 fmu解锁了应该也会通过串口发送一个信息给 io并最终调用 set函。

    /*
     * Run the mixers.
     */
    if (source == MIX_FAILSAFE) {
        /* copy failsafe values to the servo outputs */
        for (unsigned i = 0; i < PX4IO_SERVO_COUNT; i++) {
            r_page_servos[i] = r_page_servo_failsafe[i];
            /* safe actuators for FMU feedback */
            r_page_actuators[i] = FLOAT_TO_REG((r_page_servos[i] - 1500) / 600.0f);
        }
    } else if (source != MIX_NONE && (r_status_flags & PX4IO_P_STATUS_FLAGS_MIXER_OK)) {
        float    outputs[PX4IO_SERVO_COUNT];
        unsigned mixed;
        /* mix */
        /* poor mans mutex */
        in_mixer = true;
        mixed = mixer_group.mix(&outputs[0], PX4IO_SERVO_COUNT);
        in_mixer = false;
        pwm_limit_calc(should_arm, mixed, r_page_servo_disarmed, r_page_servo_control_min, r_page_servo_control_max, outputs, r_page_servos, &pwm_limit);
        for (unsigned i = mixed; i < PX4IO_SERVO_COUNT; i++)
            r_page_servos[i] = 0;
        for (unsigned i = 0; i < PX4IO_SERVO_COUNT; i++) {
            r_page_actuators[i] = FLOAT_TO_REG(outputs[i]);
        }
    }

从前面的代码中我们知道 source的值为 MIX_NONE,所以这一段不会执行。这段代码只是给 r_page_servos一个特定的值,前面是失控保护,而后面应该是关闭电机。其实如果 fmu发过来的数据是 1ms的脉宽,电机也是关闭的。

    /* set arming */
    bool needs_to_arm = (should_arm || should_always_enable_pwm);
    /* check any conditions that prevent arming */
    if (r_setup_arming & PX4IO_P_SETUP_ARMING_LOCKDOWN) {
        needs_to_arm = false;
    }
    if (!should_arm && !should_always_enable_pwm) {
        needs_to_arm = false;
    }
    if (needs_to_arm && !mixer_servos_armed) {
        /* need to arm, but not armed */
        up_pwm_servo_arm(true);
        mixer_servos_armed = true;
        r_status_flags |= PX4IO_P_STATUS_FLAGS_OUTPUTS_ARMED;
        isr_debug(5, "> PWM enabled");
    } else if (!needs_to_arm && mixer_servos_armed) {
        /* armed but need to disarm */
        up_pwm_servo_arm(false);
        mixer_servos_armed = false;
        r_status_flags &= ~(PX4IO_P_STATUS_FLAGS_OUTPUTS_ARMED);
        isr_debug(5, "> PWM disabled");
    }
    if (mixer_servos_armed && should_arm) {
        /* update the servo outputs. */
        for (unsigned i = 0; i < PX4IO_SERVO_COUNT; i++)
            up_pwm_servo_set(i, r_page_servos[i]);
    } else if (mixer_servos_armed && should_always_enable_pwm) {
        /* set the disarmed servo outputs. */
        for (unsigned i = 0; i < PX4IO_SERVO_COUNT; i++)
            up_pwm_servo_set(i, r_page_servo_disarmed[i]);
    }
int up_pwm_servo_set(unsigned channel, servo_position_t value)
{
    if (channel >= PWM_SERVO_MAX_CHANNELS)
        return -1;

    unsigned timer = pwm_channels[channel].timer_index;

    /* test timer for validity */
    if ((pwm_timers[timer].base == 0) ||
        (pwm_channels[channel].gpio == 0))
        return -1;

    /* configure the channel */
    if (value > 0)
        value--;

    switch (pwm_channels[channel].timer_channel) {
    case 1:
        rCCR1(timer) = value;
        break;

    case 2:
        rCCR2(timer) = value;
        break;

    case 3:
        rCCR3(timer) = value;
        break;

    case 4:
        rCCR4(timer) = value;
        break;

    default:
        return -1;
    }

    return 0;
}

所以最终是通过 up_pwm_servo_set函数最终将 PWM信号输出的。其中 r_page_servos这组数据是 fmu发送过来的,而 r_page_servo_disarmed这组数据是前面 pwm_limit_calc函数计算得到的。

    而其中具体每一个参数是做什么的,这个就要搞懂了流程以后详细去分析了。

转载于:https://www.cnblogs.com/eastgeneral/p/10879608.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PX4 IO [15] mixer 的相关文章

  • PX4与TX2通信

    PX4与TX2通信以及相关数据的获取 目录 1 PX4硬件接口 2 TELEM1 2接口线序 3 PX4与TX2通信 PX4 IO口定义 xff1a PX4硬件 xff1a 4 通信测试 5 RTPS 43 ROS Jetson TX2终端
  • PX4通过I2C方式添加自定义传感器(2)

    PX4 I2C通信方式传感器驱动分析 xff08 以ets airspeed为例 xff09 1 说明 这篇文章我们就来看看I2C传感器的驱动过程 xff0c 当然里面也有很多东西我不是很理解 xff0c 所以仅谈我领悟的一些东西 我就以e
  • px4: v2的主板刷写v2的固件

    v2的主板刷写v2的固件 fengxuewei 64 fengxuewei Legion Y7000 2019 PG0 src Firmware changwei rc span class token function make span
  • PX4无人机 - 键盘控制飞行代码

    PX4无人机 键盘控制飞行代码 仿真效果 实机效果 由于图片限制5M以内 xff0c 只能上传一小段了 xff0c 整段视频请点击链接 Pixhawk 6c 无人机 键盘控制无人机 Offboard模式 核心 xff1a 发布 mavros
  • px4源码编译指南

    px4源码编译指南 强烈推荐大家去看官网的英文文档 xff0c 国内的博客杂七杂八 xff0c 官网的中文也很久没有更新 xff0c 这几天自己踩了很多坑 xff0c 写个教程希望能帮助到大家 xff08 本文选用平台是pixhawk1 1
  • PX4 -- EKF2

    文章目录 EKF2参数高度估计Range Finder滤波 单变量更新单变量更新对多变量的影响 EKF2 参数 EKF2 中有一类 GATE 参数 当测量值在 VAR GATE 范围内才会更新值 高度估计 四种高度控制方法 xff1a 气压
  • PX4模块设计之三:自定义uORB消息

    PX4模块设计之三 xff1a 自定义uORB消息 1 新增自定义uORB消息步骤2 应用ext hello world消息示例3 编译执行结果4 参考资料 基于PX4开源软件框架简明简介和PX4模块设计之二 xff1a uORB消息代理
  • PX4模块设计之九:PX4飞行模式简介

    PX4模块设计之九 xff1a PX4飞行模式简介 关于模式的探讨1 需求角度1 1 多旋翼 MC multi copter 1 1 1 RC控制模式1 1 1 1 Position Mode1 1 1 2 Altitude Mode1 1
  • PX4模块设计之二十一:uORB消息管理模块

    PX4模块设计之二十一 xff1a uORB消息管理模块 1 uORB模块构建模式2 uORB消息管理函数2 1 状态查询2 2 资源利用2 3 模块启动2 4 模块停止3 uORB消息接口3 1 消息主题注册3 2 消息主题去注册3 3
  • PX4模块设计之三十一:ManualControl模块

    PX4模块设计之三十一 xff1a ManualControl模块 1 ManualControl模块简介2 模块入口函数2 1 主入口manual control main2 2 自定义子命令custom command 3 Manual
  • PX4模块设计之四十五:param模块

    PX4模块设计之四十五 xff1a param模块 1 param模块简介2 模块入口函数param main3 重要函数列表4 总结5 参考资料 1 param模块简介 Description Command to access and
  • PX4模块设计之四十六:dataman模块

    PX4模块设计之四十六 xff1a dataman模块 1 dataman模块简介2 模块入口函数dataman main3 dataman模块重要函数3 1 start3 2 stop3 3 status3 4 task main 4 A
  • PX4-4-任务调度

    PX4所有的功能都封装在独立的模块中 xff0c uORB是任务间数据交互和同步的工具 xff0c 而管理和调度每个任务 xff0c PX4也提供了一套很好的机制 xff0c 这一篇我们分享PX4的任务调度机制 我们以PX4 1 11 3版
  • PX4 OffBoard Control

    终于还是走上了这一步 xff0c 对飞控下手 xff0c 可以说是一张白纸了 记录一下学习的过程方便以后的查阅 目录 一 ubuntu18 04配置px4编译环境及mavros环境 二 PX4的OffBoard控制 1 搭建功能包 2 编写
  • 步骤八:PX4使用cartographer与move_base进行自主建图导航

    首先老样子硬件如下 飞控 HOLYBRO PIXHAWK V4 PX4 机载电脑 jetson nano b01 激光雷达 思岚a2 前提 你已经完成了cartographer建图部分 能够正常输出map话题 前言 由于要参加中国机器人大赛
  • PX4之常用函数解读

    PX4Firmware 经常有人将Pixhawk PX4 APM还有ArduPilot弄混 这里首先还是简要说明一下 xff1a Pixhawk是飞控硬件平台 xff0c PX4和ArduPilot都是开源的可以烧写到Pixhawk飞控中的
  • 无人机PX4使用动捕系统mocap的位置实现控制+MAVROS

    动捕系统Optitrack xff0c 有很高的定位精度 xff0c 能够给无人机提供比较精确的位置信息 xff0c 因此如果实验室有条件 xff0c 都可以买一套动捕系统 动捕系统的原理 xff1a 光学式动作捕捉依靠一整套精密而复杂的光
  • 在 Java 中,如何录制扬声器的声音输出? [复制]

    这个问题在这里已经有答案了 我有一个 Java 应用程序 它从多个来源接收声音 用户的能力之一是将应用程序中发生的情况记录到 AVI 文件中 我想将声音包含在该视频捕获中 如何录制用户会听到的声音 例如所有声音输入混合在一起的结果 我可以弄
  • 如何在 Unity 中将混音器的音量设置为滑块的音量?

    我正在尝试进行一些音频设置 这是我的脚本 public AudioMixer masterMixer public float masterLvl public float musicLvl public float sfxLvl publ
  • Android:如何配置“tinymix”以使用“tinycap”录制系统音频

    在 Android 中 目前无法使用 Android SDK 录制系统音频 因此 我尝试了一下 TinyALSA 自 Android 4 起 希望可以重新路由音频输出 以便可以录制它 当我在设备上调用 tinymix 时 我得到以下配置 c

随机推荐

  • xlight ftp linux,Xlight FTP Server

    Xlight FTP Server的功能按钮都是中文的 xff0c 国内用户可以轻易地创建新的服务器 xff0c 并且能够为同一台计算机的多个端口创建各自的虚拟服务器 此外 xff0c 它还具有用户虚拟目录 xff0c 每个用户的虚拟目录都
  • 参数控制c语言代码走向,C语言可变参数完全解读

    本文转自 xff1a http www cnblogs com wangyonghui archive 2010 07 12 1776068 html 一 是什么 我们学习C语言时最经常使用printf 函数 xff0c 但我们很少了解其原
  • VHDL计算机硬件能直接执行吗,第5章 VHDL程序结构.ppt

    第5章 VHDL程序结构 VHDL 数字系统设计 第5章 VHDL程序结构 VHDL语言的特点 xff1a VHDL语言具有很强的电路描述和建模能力 xff0c 能从多个层次对数字系统进行建模和描述 xff0c 从而大大简化了硬件设计任务
  • opencv双目标定原理_双目视觉原理及流程概述

    击上方 新机器视觉 xff0c 选择加 34 星标 34 或 置顶 重磅干货 xff0c 第一时间送达 双目原理 双目视觉是利用视差原理的一种视觉方法 如图所示为空间中一点P在左右相机中的成像点Pleft 61 Xleft Yleft xf
  • java怎么写算法_用Java写算法之一:冒泡排序

    从这篇文章开始 xff0c 我会陆陆续续将我所能用Java实现的算法在这里简单做个梳理 xff0c 也算温故而知新吧 受个人水平和时间限制 xff0c 可能会有错漏 xff0c 欢迎各位批评指正 那么 xff0c 就从冒泡排序开始 显然 x
  • docker显示linux桌面,怎样在桌面上安装 Docker CE?

    按照这些简单的步骤在你的 Linux Mac 或 Windows 桌面上安装 Docker CE 在上一篇文章中 xff0c 我们学习了容器世界的一些基本术语 当我们运行命令并在后续文章中使用其中一些术语时 xff0c 这些背景信息将会派上
  • 信号量-邮箱-消息队列的区别

    为什么要用 xff1a 任务间的通信可以通过全局变量或者信号量来完成 全局变量虽然可以承载通信的内容 xff0c 但是接收方无法意识到信息的到达 xff0c 除非发送方向接收方发送一个信号量 xff0c 或者接收方不断该全局变量 xff1b
  • 乱码大全(二) (转)

    乱码大全 二 转 64 more 64 2 XxencodeXML namespace prefix 61 o ns 61 34 urn schemas microsoft com Office office 34 gt 提到Uuencod
  • 成都麻将胡牌算法

    四川麻将胡牌算法 xff08 不支持风 花牌 xff09 支持缺一门 七小对 xff0c 正常胡牌 xff0c 带杠 感谢 华仔 对我的代码提出了宝贵的意见 xff0c 华仔很适合做测试啊 xff01 xff01 include lt st
  • linux lvm 扩容磁盘,Linux LVM磁盘空间扩容的新方法

    导读 传统LVM扩容方法需要增加PV磁盘 xff0c 扩容多次后 xff0c 服务器的磁盘数量会越来越多 xff0c 容易增加日后维护存储和磁盘布局的难度 当服务器是虚拟机 xff0c 或者使用SAN NAS存储的物理机时 xff0c 由于
  • keil中的串口调试:

    keil中串口的虚拟调试信息在通过View serial windows usart1 2 3 4 debug printf 可以看到 当然也可以通过虚拟串口VSPD 43 串口调试助手在外部实现 xff0c 方法如下 xff1a 虚拟 串
  • Eclipse的Ctrl+s不能保存问题的解决!

    原因1 xff1a eclipse快捷键设置有问题 xff0c 解决方式 xff1a 检查windows gt perferences gt Keys中的Save项 xff0c 是否绑定了Ctrl 43 S xff0c 以及相关设置是否正确
  • linux 查看磁盘空间大小

    1 Ubuntu 查看磁盘空间大小命令 df h Df命令是linux系统以磁盘分区为单位查看文件系统 xff0c 可以加上参数查看磁盘剩余空间信息 xff0c 命令格式 xff1a df hl 显示格式为 xff1a 文件系统 容量 已用
  • 开源三轴云台EVVGC(simple BGC)分析

    一 xff0e 主程序分析 主程序结构清晰 xff0c 流程如图所示 xff0c 下面将对每个部分做详细分析 二 系统初始化 系统初始化部分的流程如上图所示 xff0c 下面对每部分做具体分析 1 时钟初始化 该部分主要是使能DWT xff
  • 使用docker中mysql镜像

    1 拉取mysql镜像 docker pull mysql 5 6 2 运行mysql的镜像生成一个正在运行的容器 xff0c 可以通过docker contain ls得到容器的id信息 docker run dit p 3306 330
  • WARNING: CPU: 0 PID: 1 at ./arch/x86/include/asm/fpu/internal.h:373

    cut here WARNING CPU 0 PID 1 at arch x86 include asm fpu internal h 373 0xffffffffb3022ed7 Modules linked in CPU 0 PID 1
  • PMP考试概念汇总(下)

    管理沟通 xff1a 是根据沟通管理计划 xff0c 生成 收集 分发 储存 检索及最终处置项目信息的过程 本过程的主要作用是 xff0c 促进项目干系人之间实现有效率且有效果的沟通 控制沟通 xff1a 是在整个项目生命周期中对沟通进行监
  • 发现cmake使用CMakeLists.txt生成工程时的一个问题

    使用CMakeLists txt生成DLL 定义的exort字段会将全部大写变成大小写混合 xff0c 例如 NECONFIG EXPORT 在生成的工程中会变为 NeConfig EXPORT 转载于 https www cnblogs
  • .NET Core 跨平台 串口通讯 ,Windows/Linux 串口通讯,flyfire.CustomSerialPort 的使用

    目录 1 xff0c 前言 2 xff0c 安装虚拟串口软件 3 xff0c 新建项目 xff0c 加入 flyfire CustomSerialPort 4 xff0c flyfire CustomSerialPort 说明 5 xff0
  • PX4 IO [15] mixer

    PX4 IO 15 mixer PX4 IO 15 mixer 转载请注明出处 更多笔记请访问我的博客 xff1a merafour blog 163 com 2015 1