PH47代码框架全局函数及功能类

PH47代码框架全局函数及功能类

概述

全局函数及功能类体系是PH47框架当中除了4个逻辑层之外最重要的组成部分之一,它们可以在 整个PH7 代码框架及用户代码中使用。常用全局函数及功能类为 PH7 代码框架提供了最常用和最基础的功能实现。

全局函数主要包含了对时间相关功能操作、调试功能函数及类、全局状态变量操作、运行频率控制等最常用的功能。

读者可粗略了解本章内容,在实际开发过程中涉及到具体内容时作为手册性质内容进行查询了解即可。

时间相关全局函数简明指南

获取自飞控板启动至当前时刻的 ms 计数

函数

uint32_t gGetMills() 

功能

获取自飞控板启动至当前时刻的 ms 计数。

数据范围为 4294967296ms,1193 hour

返回值

当前时刻的 ms 计数

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.h

// Demo:
uint32_t uCurr_ms = gGetMills()   

获取自飞控板启动至当前时刻的 ms 计数(float)

函数

float gGetMills_f()

功能

获取自飞控板启动至当前时刻的 ms 时间,小数点精确到后3位即 us。

飞控板运行约 4800s 后溢出重置,从 0 开始重新计数

返回值 

当前时刻的 ms 时间并精确到小数点后3位

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.h

// Demo:
float fCurr_ms = gGetMills();  

获取自飞控板启动至当前时刻的 us 计数

函数

uint32_t gGetMicros()

功能

获取自飞控板启动至当前时刻的 us 计数。

计数开始 600s 后溢出重置,从0开始重新计数

返回值

当前时刻的 us 计数

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.h

// Demo:
uint32_t uCurr_us = gGetMicros(); 

获取距离前一时刻的时间间隔(ms)

函数

uint32_t gGetTmUsage_ms(uint32_t uPrevMs)

功能

获取距离前一时刻 uPrevMs 的时间间隔(ms)

参数

uPrevMs:上一时刻的ms时间计数

返回值 

距离上一时刻的时间间隔(ms)

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.h

// Demo:
uint32_t uPrevMs = gGetMills();// Do something...
uint32_t uDt_ms = gGetTmUsage_ms(uPrevMs);

获取距离前一时刻的时间间隔(us)

函数

uint32_t gGetTmUsage_us(uint32_t uPrevUs)

功能

获取距离前一时刻 uPrevUs 的时间间隔(us)。

注意该时间间隔最长不能超过 600s

参数

uPrevUs:上一时刻us时间计数

返回值 

距离上一时刻的时间间隔(us)

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.h

// Demo:
uint32_t uPrevUs = gGetMicros();// Do something...
uint32_t uDt_us = gGetTmUsage_ms(uPrevUs);

us级时间延时

函数

uint32_t gDelay_us(uint16_t uDelay)

功能

以阻塞方式延时 uDelay 微秒(us),同时返回实际延时时间(us)。

注意尽量不要使用本函数进行 ms 级别的延时,如确实需要则以 HAL_Delay(uint32_t Delay) 或 osDelay (uint32_t millisec) 函数实现

参数

uDelay:待延时的微秒时间

返回值

实际延时时间(us)

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.h

// Demo:
gDelay_us(10);

调试功能函数简明指南

表达式真值确认宏ASSERT()

函数

ASSERT(f) 宏

功能

对表达式 f 进行真值确认。

若 f 为 false, 则程序执行在 ASSERT 语句处中断,并通过串口输出中断位置所在的文件名和行号,同时令状态指示LED快速闪烁。

参数

f:表达式

注意

  1. 若需要 ASSERT 正常输出中断位置字符信息,则 ASSERT 语句的执行顺序须在 CThreadCtrl_BBP.InitAfterThreadStart() 函数之后。可供判断的标志变量为 core.blSysInitCompleted变量,true 表示初始化工作已完成,ASSERT 宏可正常使用。
  2. 一般情况下,驱动层代码中若使用 ASSERT 语句,在表达式为 false 情况下 led 能够正常闪烁指示, 但不能输出错误信息位置信息字符串。
  3. 对于二次开发用户而言,应用层 CAppBBP_xxx 的代码中均可正常使用 ASSERT 语句的所有功能

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.

// Demo:
_pSensor_IMU = new CSensor_IMU(IMU_GYR_ACC_MPU6500, FREQ_THREAD_FAST);
ASSERT(_pSensor_IMU);

调试字符串输出宏TRACE(fmt, args ...)宏      

函数

TRACE(fmt, args ...)

功能

TRACE 宏以邮件队列方式向调试串口输出调试字符串信息

参数

格式化字符串

注意

  1. 连续使用 TRACE 时具有严格的顺序性, 此外 TRACE 具有跨线程安全性。
  2. 使用 %f 输出单精度浮点变量时,小数部分最长长度为 6 位, 此外,在同一 TRACE 语句中,%f 输出的浮点变量不要超过3个
  3. 与 ASSERT 宏类似, TRACE 的运行依赖于线程的启动运行(可供判断的标志变量为 core.blSysInitCompleted)
  4. TRACE实际显示信息时刻会晚于函数调用时刻(间隔在 10ms 级别)

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.

// Demo:
TRACE("\r\n> press calibrated: %.1f.", _ground_pressure);

调试字符串输出函数gPrintf(const char *fmt, ...) 函数

函数

void gPrintf(const char *fmt, ...)

功能

以中断方式向调试串口输出格式化字符串

参数

格式化字符串

注意

  1. gPrintf 在跨线程使用时应注意数据安全性,同时多个 gPrintf 密集执行时其输出顺序可能会存在不确定性.。
  2. gPrintf 可用于线程启动前的字符串输出。

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.

// Demo:
gPrintf("\r\n> Init Gyro %d...", _uImuID);

状态LED设置函数gSetLed()

函数

void gSetLed(bool blLight)

功能

点亮和或熄灭调试 LED, 此函数可用于驱动层代码的信息指示工作

参数

true 点亮状态指示led,false熄灭

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.h

// Demo:
gSetLed(true)

生成格式化字符串函数gFormat()

函数

void gFormat(char *pBuffOut, const char *fmt, ...)

功能

生成格式化字符串

参数

格式化字符串

注意

使用 %f 输出单精度浮点变量时,小数部分最长长度为 6 位。

此外,在同一 TRACE 语句中,%f 输出的浮点变量不要超过3个

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.h

// Demo:
char szTmp[32];
gFormat(szTmp, "log %d readonly:%d", 5, true);
TRACE("\r\n> %s", szTmp);

调试信息显示函数gShowInfo()

函数

void gShowInfo(bool blTrace, bool blMavlinkMsg,

MAV_SEVERITY eSeverity, const char *fmt, ...)

功能

以格式化字符串的形式,在调试串口,或CSS状态信息显示窗口中显示字符串信息

参数

blTrace

true 表示在调试串口输出字符串;

blMavlinkMsg

true 表示通过向 CSS 发送 message 方式在 CSS 信息窗口中显示信息。

eSeverity

使用字符颜色表示信息等级(CSS 中对来自于控制板的状态信息使用蓝色背景进行显示):

MAV_SEVERITY_ERROR    红色字符

MAV_SEVERITY_WARNING  黄色字符

MAV_SEVERITY_NOTICE      绿色字符

MAV_SEVERITY_INFO     白色字符

fmt

格式化字符串

包含文件

\DevStudio\Frame\Core\GlobalFun_Sys.h

// Demo:
gShowInfo(true, true, MAV_SEVERITY_ERROR, "IMU%d Cali failed!", _uImuID);

调试类CTestSuit功能使用说明

PH47框架中预置了一个专用于框架功能调试以及代码单元测试的测试类CTestSuit。在该类中设置了两个功能函数以及对应成员变量用于功能测试。

用户测试命令响应函数

函数

void TrigleTest()

功能

测试功能触发函数,当用户在调试串口中输入”debug;”命令后触发执行。并在调试窗口以及CSS状态信息窗口显示相关信息。

同时,CTestSuite._uTestCnt16变量自动加1。用户可根据此变量数值执行不同的功能代码。

函数

TrigleTest_MavCmd(float fPara_1, float fPara_2)

功能

测试功能触发函数,当用户在GCS端发出MAVLINK_MSG_ID_COMMAND_LONG_SA命令,且该命令的packet.commandMAV_CMD_DEBUG时函数触发运行。

同时,MAVLINK_MSG_ID_COMMAND_LONG_SA命令附带的两个参数packet.param1, packet.param2作为函数参数进行传递。

函数

GetParaInfo()

功能

在调试串口中输出当前参数系统所有参数的信息。

但在用户在调试串口中输入”getpara;”命令后函数触发运行。

硬件外设自测函数

函数

void SelfTest(),void SetTest()

功能

PH47代码框架硬件驱动自测功能函数。用于对BBP控制板的硬件外设进行测试。

用户在调试串口输入”test;”命令后开始测试并显示相关信息。输入一次test;命令切换一项测试内容,直至测试完毕。

代码模块单元测试函数

代码模块单元测试函数主要对PH47框架中重要和常用的模块单元进行测试,一般集中于硬件驱动代码上。用户在进行硬件移植的过程中可直接使用或稍许修改这些单元测试代码。

函数

UsartRead()

功能

中断方式读取USART1, USART2, USART6接收数据,并以中断方式输出到调试串口USART6进行显示。

函数

UsartWrite()

功能

以中断方式,或DMA方式向当前控制板窗口写入测试数据。

用户可根据需要对函数中的代码进行部分屏蔽以选择相应功能。

函数

void AT24C128_Test(uint8_t uWrite)

功能

对EEProm芯片AT24C128执行读写操作测试。

用户可根据需要对函数中的代码进行部分屏蔽以选择相应功能。

函数

void W25Q128_Test()

功能

对Flash芯片W25Q128执行读写操作测试。

用户可根据需要对函数中的代码进行部分屏蔽以选择相应功能。

函数

W25Q128_PrintPage_256byte(uint8_t *pBuff)

功能

以16进制,格式化显示当前内存缓冲区内数据以选择相应功能。

函数

void ReadLog()

功能

读取记载飞行记录数据的头信息,或者飞行记录数据。

用户可根据需要对函数中的代码进行部分屏蔽以选择相应功能。

函数

GetAdc()

功能

获取BBP控制板ADC通道测量得到的电压数值。

函数

void PwmOut()

功能

在当前控制板Pwm输出通道输出指定的Pwm波形,可使用示波器在输出端进行测量。

循环控制功能类简明指南

循环间隔时间设置函数SetRunInv_ms ()

函数

void SetRunInv_ms(uint16_t uInteval_ms)

功能

在循环体 loop 之外的初始化阶段设置运行时间间隔(ms), 设置后在 loop 中调用 IsSetRunInv_ms() 进行运行频率控制

参数

uInteval_ms 为设定运行间隔时间, 即以 (1000ms / uInteval_ms) 的频率(hz)运行

包含文件

\DevStudio\Frame\Core\FreqDiv.h

示例

见IsSetRunInv_ms()函数示例

循环间隔控制函数IsSetRunInv_ms ()

函数

bool IsSetRunInv_ms()

功能

在循环体 loop 内判断是否达到了前述 SetRunInv_ms() 设置的时间间隔。

使用前必须调用 SetRunInv_ms() 设定间隔值。

注意在每个循环中,相同时间设定的IsSetRunInv_ms()函数只能调用一次

返回值

true 表示已经达到之前通过SetRunInv_ms ()函数设定的循环间隔时间

包含文件

\DevStudio\Frame\Core\FreqDiv.h

// Step 1. 首先在 .h 文件中进行FreqDiv.h文件包含
// 然后声明 CFreqDiv 类对象 _FreqDiv_50hzCFreqDiv _FreqDiv_50hz;              // Step 2.在.cpp文件的初始化函数中设置循环间隔时间(ms) 1000ms/20ms= 50hz
_FreqDiv_50hz.SetRunInv_ms(20);      // Step 3. 在.cpp文件的loop循环中进行循环间隔判断
if(_FreqDiv_50hz.IsSetRunInv_ms()) {// do something...
}

us级循环间隔时间设定与控制函数()

函数

void SetRunInv_us(uint16_t uInteval_us)

bool IsSetRunInv_us()

功能

功能同 SetRunInv_ms()及IsSetRunInv_ms()函数,只是时间单位为us

设定循环间隔时间倍率函数SetFreqMuti ()

函数

void SetFreqMuti(FREQ_MUTIPLES eFreqMuti)

功能

在以 SetRunInv_ms() 或 SetRunInv_us() 设定运行频率的基准,进行倍频设置,改变当前循环控制频率。

参数

eFreqMuti为倍率系数

倍率系数枚举为 FREQ_MUTIPLES, 其中定义了从 0.1 到 25 的倍频系数,以及停止分频或倍频控制系数。

注意

包含文件

\DevStudio\Frame\Core\FreqDiv.h

// 将当前运行频率从 50hz 重新设定为 100hz
_FreqDiv_50hz.SetFreqMuti(FREQ_MUTI_2); 

获取实际运行频率函数GetActFreq ()

函数

float GetActFreq(uint32_t uCurr_us)

功能

获取最近一次循环过程的实际工作频率(hz)

参数

uCurr_us 为本函数调用时刻的 us 时间

注意

受 mcu 及 rtos 性能限制, 或者程序执行时间过长可能会造成 loop 实际运行频率不等于 SetRunInv_ms() 或 SetRunInv_us() 设定的运行频率, 此时就可以通过本函数获取 loop 的实际运行频率

包含文件

\DevStudio\Frame\Core\FreqDiv.h

// Demo:
float fFreq_hz = _FreqCtrl_5hz.GetActFreq( gGetMicros() );  

LED专用控制类使用说明

CLedOutput类可控制BBP控制板上的状态LED以“长点亮”、“短点亮”方式输出编码组合。通常在硬件移植的初期阶段,串口USART驱动尚未实现的时,获取调试信息手段极其有限的情况下,就可以使用CLedOutput类控制LED显示一定的调试信息。

CLedOutput类控制Led方式为非阻塞,不会对调用其的代码执行产生影响。

函数

void Led_ShowStatus(LED_OUTPUT_INFO eInfoCode)

功能

使用状态LED显示带编码的ASSERT信息,或者编码信息

以2组爆闪, 每组内5次快速闪烁为提示符进行信息显示

显示信息长度为3 bit, dot(短时闪烁) 表示 0, dash(长闪烁)表示1,

显示顺序为从左到右

参数

eInfoCode 为LED_INFO_ASSERT时作为ASSERT信息显示,以10组爆闪,每组闪烁 10 次作为提示符,之后显示 3 bit 数据。

eInfoCode 为LED_OUTPUT_INFO枚举的其他数值时作为多飞控协作模式,或其他信息显示。以2 组爆闪作为提示符, 每组闪烁 5 次,之后 显示 3 bit 数据。

包含文件

\DevStudio\Frame\LedOutput.h

// Demo:
frm.led.Led_ShowStatus(LED_INFO_PILOT_MASTER);

多飞控协作控制类使用说明

PH47框架以及BBP系列控制板均支持双飞控协作模式。在双飞控组合状态下,可以组合为双飞控冗余热备模式、集群主从机模式、资源扩展模式等多种工作模式。

  1. 双飞控冗余热备模式:此模式下双飞控系统由主飞控及副飞控构成,且主副飞控各自连接必要的传感器,并拥有各自的遥测通讯通道,对应各自的GCS,以并行方式各自运行。正常状态下,飞行器由主飞控进行控制。副飞控通过监测主飞控的心跳包对主飞控状态进行监视,若主飞控心跳包消失达到一定时间(2500ms),则副飞控接管飞行器控制权。此外,操作者也能通过GCS实施主副飞控控制权切换。
  2. 集群主从机模式:集群中的飞控主机通过空对空通讯链路对飞控从机实施指令控制。此时飞控从机通常脱离GCS控制,完全受控于飞控主机。
  3. 双飞控资源扩展模式:此模式下仅有主飞控运行飞控软件,作为副飞控的控制板不参与飞行控制,仅作为控制板硬件资源(串口、SPI接口、I2C接口、PWM输入输出)扩展使用。

双飞控冗余热备模式硬件连接

  • 主副飞控的USART6调试串口相互连接,并令主副飞控分别工作于MUSART_DUAL_PILOT_MASTER或MUSART_DUAL_PILOT_SLAVER模式。
  • 主飞控控制权切换跳线(BBP飞控板背面)从单飞控板运行时的PB3切换到PoEn,在此情况下,飞控板Pwm输出由副飞控板进行控制。

  • 副飞控GPIO_EXT_1_Pin输出连接到主飞控EN_PWM_OUT_Pin输入引脚。

多飞控协作功能函数

函数

void ChangeConsoleMode(MUTI_USAGE_USART eMode);

功能

改变当前调试串口工作模式。

默认状态下调试串口Usart6工作于调试命令行控制台模式。但需要处于多飞控协作模式下时,BBP v2,BBP Mini控制板需要将Usart6切换到对应的模式。

参数

参数定义MUTI_USAGE_USART枚举,取值如下:

    MUSART_DEBUG_CONSOLE:调试串口模式

    MUSART_DUAL_PILOT_MASTER双飞控, 主机

    MUSART_DUAL_PILOT_SLAVER双飞控,从机

    MUSART_AIRLINK_MASTER集群编队, 主机

    MUSART_AIRLINK_SLAVER集群编队, 从机

    MUSART_AIRLINK_P2P集群编队, 点对点

    MUSART_DUAL_TELE单飞控,资源扩展模式

    MUSART_TOF单飞控,Usart6连接tof或光流

包含文件

\DevStudio\CommonDef.h

// 调试串口工作模式切换
MUTI_USAGE_USART eMode = (MUTI_USAGE_USART) core.para.Get(P_CONSOLE_MODE);
frm.mutipilot.ChangeConsoleMode(eMode);  

函数

bool ChangeFlightCtrlRights(FLIGHT_CTRL_RIGHTS eCtrlRight)

功能

在双飞控冗余热备模式,切换当前飞控(主飞控或副飞控)的控制权。

主副飞控均可使用该函数,将控制权交给另外一个飞控。

此外,副飞控还可主动收回主飞控的控制权

参数

参数定义位于枚举FLIGHT_CTRL_RIGHTS中,取值如下:

CTRL_BY_DP_SLAVER由主飞控,或副飞控发起,将控制权转移到副飞控。

CTRL_BY_DP_MASTER由副飞控发起,将控制权交回主飞控

包含文件

\DevStudio\Frame\MutiPilot.h

// 双飞控模式下,从机切换控制权至主飞控,允许主飞控输出控制 
frm.mutipilot.ChangeFlightCtrlRights(CTRL_BY_DP_MASTER);

消息操作功能使用说明

PH47代码框架设置了简单的消息循环以及SendMessage()以及PostMsg()函数功能。上述函数可跨线程使用。区别在于:

SendMessage()在发出message后立即执行消息响应函数。

PostMsg()在发出消息后通过CheckPostMsg()函数判断是否收到指定message,若收到则执行相关代码。

SendMessage()函数使用方法

  • Step1:定义message ID:在\DevStudio\BoardConfig\Firmware_BBDB\StateVarDef_BBDB.h文件中定义Message ID。如有必要,还可以定义消息的参数。例如:
// 参数批量下载消息. LParam 参数决定参数下载状态
#define MSG_SET_MSGRATE_FOR_PARA_WP_DOWN  203   #define PARAM_DOWN_START 1     // 下载开始#define PARAM_DOWN_COMPLETED 2 // 下载结束
  • Step2:在代码中需要发出message的位置调用SendMessage()函数:
msg.SendMessage(MSG_SET_MSGRATE_FOR_PARA_WP_DOWN,(uint32_t) PARAM_DOWN_START,(uint16_t) 0);
  • Step3:在框架类实现文件\DevStudio\Frame\Frame.cpp的HandleMessage()函数中加入对消息MSG_SET_MSGRATE_FOR_PARA_WP_DOWN的处理代码。注意,所有 对于SendMessage的响应功能代码都必须在CFrame.HandleMessage()函数中实现。
if(pPopMsg ->uMsgId == MSG_SET_MSGRATE_FOR_PARA_WP_DOWN)Msg_SetMsgRate4ParaWp(pPopMsg);

PostMsg()函数使用方法

  • Step1:定义message ID:在STATUS_BOOL枚举的自定义区域内定义用于PostMsg的ID(此处不同于SendMessage的id定义,因为PostMsg使用的Message实质上是一种bool类型的全局状态状态变量)。STATUS_BOOL枚举位于\DevStudio\BoardConfig\Firmware_BBDB\StateVarDef_BBDB.h文件中。
  • Step2:在代码中Post特定Message
// Post message P_MSG_LOG_DOWN_COMPLETE
frm.PostMsg(P_MSG_LOG_DOWN_COMPLETE);
  • Step3:在代码中适当位置检测P_MSG_LOG_DOWN_COMPLETE是否已经发出,若发出,则执行相关响应代码。
if(frm.CheckPostMsg(P_MSG_LOG_DOWN_COMPLETE))LogDownComplete();

SendMessage()与PostMsg()的小结

消息机制

SendMessage 机制

PostMsg 机制

执行时刻

消息发出后立刻执行

检测消息是否发出以决定是否执行

功能响应

代码位置

必须在CFrame.HandleMessage()函数中实现。

可以在框架中任意位置对消息是否发出进行检测,并实现功能响应代码。

消息ID定义

在\Firmware_BBDB\

StateVarDef_BBDB.h中定义

在\Firmware_BBDB\

StateVarDef_BBDB.h的STATUS_BOOL枚举中定义

消息参数

消息id可带参数

不可携带参数

引用对象

通过独立引用对象msg使用

作为frm引用对象下的一个功能函数使用

其他全局性性质功能函数使用说明

传感器真实数据模式判断

PH47框架具有初步的HIL(Hardware In Loop)仿真运行功能,通过数据总线系统,整个框架运行数据流的源头数据,既可以来自各传感器实际测量的原始真实数据,也可来自于之前实际飞行(运行)过程中记录下的记录数据。后者的意义在于,通过使用记录数据驱动整个框架运行,可以建立起一个开环,可以在室内反复重现运行过程。从而对某些逻辑控制过程,或者控制算法进行仿真开发或调试。降低实际飞行(运行)的实验成本。

PH47框架为HIL数据回放运行涉及了一套完整的机制,只需要GCS发出上行控制命令MAVLINK_MSG_ID_COMMAND_LONG_SA的command id为MAV_CMD_START_HILSIM即可以当前索引的飞行记录数据为驱动,开始HIL回放运行过程。

在程序运行过程中可通过IsSensorMode()函数判断当前驱动数据是来自于传感器真实测量数据,还是来自于飞行记录数据回放。

函数

bool IsSensorMode()

功能

判断当前是否属于传感器数据真实输入模式,

返回true表示当前驱动框架运行的数据来自于传感器真实测量;

false表示当前驱动数据来自于记录数据回放

if( frm.IsSensorMode() ) {// Some code }

向GCS发送自定义数据(短数据帧)

在遥测通讯系统当中,当通讯协议确定的情况下, 如果出现了新的数据需要传送,而遥测协议又尚未包含该数据时,一般有两种方法:一种是增加通讯协议内容,设计一个新的数据帧将新数据加入其中;另外一种是利用已有的数据帧来传输新数据。

通常情况下,使用一个通用数据帧来传输新出现或新增加的数据是一种不错的解决方法。同时,配合CSS的逻辑控制语句功能,能够对通用数据帧携带不同数据进行不同分类处理(关联到不同总线)。

PH47框架中可用的通用数据帧(message)有USER_DEF_DATA以及COMMAND_LONG_SA后者因为可以携带7个flaot类型的参数,message长度较长,通常用于一次性需要传输多个数据的场合。而对于一次只需要传输少量数据的场合,使用USER_DEF_DATA就比较合适。

// Demo_10.下行发送自定义短控制命令发送
Vector3f vTmp = bus.sImu.MagRaw.Get();
mavlink_user_def_data_t packet;packet.ID = 0xA5;
packet.Para_16 = (int16_t) vTmp.x;
packet.Para_32 = gGetMills();core.mavlink.AddMsg_UserDefData(&packet);


更多内容见CSDN博客专栏:无人机飞控icon-default.png?t=O83Ahttps://blog.csdn.net/ss15/category_9690939.html?spm=1001.2014.3001.5482相关资源:PH47: PH47运动控制代码框架.icon-default.png?t=O83Ahttps://gitee.com/ss15/ph47

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/60469.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣 LeetCode 203. 移除链表元素(Day2:链表)

解题思路: 方法一:头节点和非头节点分开处理 方法二:定义一个dummy虚拟节点,后面的节点就可以采用相同的处理方式 注意: cur需要指向要删除的节点的上一个节点,因为要越过这一个被删除的节点 class Sol…

IEC60870-5-104 协议源码架构详细分析

IEC60870-5-104 协议源码架构 前言一、资源三、目录层级一二、目录层级二config/lib60870_config.hdependencies/READMEexamplesCMakeLists.txtcs101_master_balancedcs104_client_asyncmulti_client_servertls_clienttls_server说明 make这些文件的作用是否需要导入这些文件&a…

turbo c 2.0 画螺栓

代码; #include<graphics.h> void bolt(x0,y0,d,l) int x0,y0,d,l; {int x1,x2,x3,x4,x5,x6,x7,x8;int y1,y2,y3,y4,y5,r1,r2,b,c;if(l>2*d) b2*d;else b1;r11.5*d;r20.38*d;c0.1*d;x1x0-0.7*d;x2x0-0.61*d;x3x0-0.32*d;x4x00.8*d;x5x0l-b;x6x0l-c;x7x0l-0.05*d;x8x0…

网络服务综合项目-博客

一、运行环境&#xff1a; 主机主机名系统服务192.168.31.128Server-WebLinuxWeb192.168.31.129Server-NFS-DNSLinuxNFS 二、基础配置&#xff1a; 配置主机名开启防火墙并配置部分开启selinux并配置服务器之间使用ntp.aliyun.com进行时间同步服务器之间实现ssh免密登录 三…

leetcode86:分隔链表

给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x 3 输出&am…

Android Mobile Network Settings | APN 菜单加载异常

问题 从log看是有创建APN对应的Controller&#xff08;功能逻辑是ok的&#xff09;&#xff0c;但是Mobile Network Settings无法显示&#xff08;UI异常&#xff09;。 日志分析 看似APN 菜单已经创建了&#xff0c;实际上并没有显示。 11-12 07:01:28.150 8773 8773 D Pr…

上海市计算机学会竞赛平台2020年4月月赛丙组永恒的生命游戏

题目背景 2020年4月11日&#xff0c;英国数学家 约翰霍顿康威&#xff08;John Horton Conway&#xff09;因为新型冠状病毒肺炎不幸逝世。他在群论、数论、代数、几何拓扑、理论物理、组合博弈论和几何等领域&#xff0c;都做出了重大贡献。他的离去是人类文明的损失。他最著…

FS8x 功能安全

fail-safe是电独立的和物理隔离的。fail-safe由自己的参考电压和电流提供,有自己的振荡器,有重复的模拟路径以最小化常见的故障,并有LBIST/ABIST来覆盖潜在故障。fail-safe根据设备部件号提供ASIL B或ASIL D遵从性。除非另有规定,fail-safe定时来自故障安全振荡器,其精度为…

项目模块十七:HttpServer模块

一、项目模块设计思路 目的&#xff1a;实现HTTP服务器搭建 思想&#xff1a;设计请求路由表&#xff0c;记录请求方法与对应业务的处理函数映射关系。用户实现请求方法和处理函数添加到路由表&#xff0c;服务器只接受请求并调用用户的处理函数即可。 处理流程&#xff1a; …

内网域环境、工作组、局域网等探针方案

1. 信息收集 1.1 网络收集 了解当前服务器的计算机基本信息&#xff0c;为后续判断服务器角色&#xff0c;网络环境做准备 systeminfo 详细信息 net start 启动服务 tasklist 进程列表 schtasks 计划任务&#xff08;受权限影响&#xff09; 了解当前服务器的网络接口信息…

什么是量化交易

课程大纲 内容初级初识量化&#xff0c;理解量化 初识量化 传统量化和AI量化的区别 量化思想挖掘 量化思想的挖掘及积累技巧 量化代码基础&#xff1a; python、pandas、SQL基础语法 金融数据分析 常用金融分析方式 常用因子分析方式 数据分析实战练习 回测及交易引擎 交易引擎…

OpenHarmony-1.启动流程

OpenHarmony启动流程 1.kernel的启动 流程图如下所示&#xff1a;   OpenHarmony(简称OH)的标准系统的底层系统是linux&#xff0c;所以调用如下代码&#xff1a; linux-5.10/init/main.c: noinline void __ref rest_init(void) {struct task_struct *tsk;int pid;rcu_sch…

【LeetCode】【算法】64. 最小路径和

LeetCode 64. 最小路径和 题目描述 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 思路 思路&#xff1a;这种题太典了&#xff0c;典…

1.7 JS性能优化

从输入url到页面加载完成都做了些什么 输入 URL - 资源定位符 http://www.zhaowa.com - http 协议 追问&#xff1a;http 与 TCP 1. http - 应用层 < > TCP - 传输层 2. 关联 - http基于TCP实现连接 < > UDP > 握手 & 挥手 &#xff08;传输速率上较…

Spring Task详细讲解

✨Spring Task简介 Spring Task 是 Spring 提供的轻量级定时任务工具&#xff0c;也就意味着不需要再添加第三方依赖了&#xff0c;相比其他第三方类库更加方便易用。可以按照约定的时间自动执行某个代码逻辑。 使用场景&#xff1a; 信用卡每月还款提醒银行贷款每月还款提醒…

Qt/C++ 海康SDK开发示例Demo

*** 工业相机在机器视觉中起到关键作用&#xff0c;本文基于海康 SDK 详细解读了设备连接与控制的各个步骤。内容涵盖设备枚举、句柄创建、图像采集回调以及设备异常处理&#xff0c;帮助开发者快速理解如何通过代码控制相机&#xff0c;实时采集并处理图像数据。*** 1. 搜索并…

HDLBIts习题(5):移位寄存器

&#xff08;1&#xff09;易错习题1&#xff1a;109题&#xff08;shift18&#xff09; 对算数左移和算数右移概念不清&#xff0c;不知道该如何计算。 逻辑左移和算术左移之间没有区别。&#xff08;无论是有符号位数据还是无符号位数据&#xff0c;右侧补0&#xff09; 逻辑…

想要成为独立游戏作者 :通关!游戏设计之道 2-2 关卡设计

本文通过ai辅助总结加个人微调,不喜勿喷 前篇如下&#xff1a; 想要成为独立游戏作者 &#xff1a;通关&#xff01;游戏设计之道 2-1 HUD-CSDN博客 1.关卡的多重定义 在电子游戏行业里 “关卡” 有多种含义&#xff0c;如游戏行为发生的环境、分割的游戏体验单元、量…

【深圳大学】数据结构A+攻略(计软版)

1. 考试 1.1 形式 分为平时&#xff0c;笔试&#xff0c;机试三部分。其中&#xff1a; 平时占30%&#xff0c;包含平时OJ测验和课堂练习&#xff0c;注意这个可能会因老师的不同和课题组的新策略而改变。笔试占60%&#xff0c;是分值占比的主要部分。机试占10%。 1.2 题型…

Springboot 启动端口占用如何解决

Springboot 启动端口占用如何解决 1、报错信息如下 *************************** APPLICATION FAILED TO START ***************************Description:Web server failed to start. Port 9010 was already in use.Action:Identify and stop the process thats listening o…