feat:add servo erpc api

This commit is contained in:
lgv 2026-04-21 17:21:20 +08:00
parent 8063250f66
commit 4e64fb3438
55 changed files with 26275 additions and 1071 deletions

32
.config
View File

@ -10,9 +10,7 @@
#
# rt_vsnprintf options
#
# CONFIG_RT_KLIBC_USING_LIBC_VSNPRINTF is not set
# CONFIG_RT_KLIBC_USING_VSNPRINTF_LONGLONG is not set
# CONFIG_RT_KLIBC_USING_VSNPRINTF_STANDARD is not set
CONFIG_RT_KLIBC_USING_LIBC_VSNPRINTF=y
# end of rt_vsnprintf options
#
@ -243,12 +241,12 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
# CONFIG_RT_USING_I2C is not set
# CONFIG_RT_USING_PHY is not set
# CONFIG_RT_USING_PHY_V2 is not set
# CONFIG_RT_USING_ADC is not set
CONFIG_RT_USING_ADC=y
# CONFIG_RT_USING_DAC is not set
# CONFIG_RT_USING_NULL is not set
# CONFIG_RT_USING_ZERO is not set
# CONFIG_RT_USING_RANDOM is not set
# CONFIG_RT_USING_PWM is not set
CONFIG_RT_USING_PWM=y
# CONFIG_RT_USING_PULSE_ENCODER is not set
# CONFIG_RT_USING_INPUT_CAPTURE is not set
# CONFIG_RT_USING_MTD_NOR is not set
@ -613,6 +611,7 @@ CONFIG_RT_USING_CPP_EXCEPTIONS=y
# CONFIG_PKG_USING_U8G2 is not set
# end of u8g2: a monochrome graphic library
# CONFIG_PKG_USING_NES_SIMULATOR is not set
# CONFIG_PKG_USING_OPENMV is not set
# CONFIG_PKG_USING_MUPDF is not set
# CONFIG_PKG_USING_STEMWIN is not set
@ -951,6 +950,7 @@ CONFIG_PKG_STM32H7_CMSIS_DRIVER_VER="latest"
# CONFIG_PKG_USING_GD32_ARM_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_GD32_ARM_SERIES_DRIVER is not set
# CONFIG_PKG_USING_GD32_RISCV_SERIES_DRIVER is not set
# CONFIG_PKG_USING_GD32VW55X_WIFI is not set
# end of GD32 Drivers
#
@ -958,6 +958,15 @@ CONFIG_PKG_STM32H7_CMSIS_DRIVER_VER="latest"
#
# CONFIG_PKG_USING_HPM_SDK is not set
# end of HPMicro SDK
#
# FT32 HAL & SDK Drivers
#
# CONFIG_PKG_USING_FT32F0_STD_DRIVER is not set
# CONFIG_PKG_USING_FT32F0_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_FT32F4_STD_DRIVER is not set
# CONFIG_PKG_USING_FT32F4_CMSIS_DRIVER is not set
# end of FT32 HAL & SDK Drivers
# end of HAL & SDK Drivers
#
@ -1036,6 +1045,7 @@ CONFIG_PKG_STM32H7_CMSIS_DRIVER_VER="latest"
# CONFIG_PKG_USING_P3T1755 is not set
# CONFIG_PKG_USING_QMI8658 is not set
# CONFIG_PKG_USING_ICM20948 is not set
# CONFIG_PKG_USING_SCD4X is not set
# end of sensors drivers
#
@ -1053,6 +1063,7 @@ CONFIG_PKG_STM32H7_CMSIS_DRIVER_VER="latest"
# CONFIG_PKG_USING_CST812T is not set
# end of touch drivers
# CONFIG_PKG_USING_LCD_SPI_DRIVER is not set
# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_BUTTON is not set
# CONFIG_PKG_USING_PCF8574 is not set
@ -1132,8 +1143,13 @@ CONFIG_PKG_STM32H7_CMSIS_DRIVER_VER="latest"
# CONFIG_PKG_USING_IC74HC165 is not set
# CONFIG_PKG_USING_IST8310 is not set
# CONFIG_PKG_USING_ST7789_SPI is not set
# CONFIG_PKG_USING_CAN_UDS is not set
# CONFIG_PKG_USING_ISOTP_C is not set
# CONFIG_PKG_USING_IKUNLED is not set
# CONFIG_PKG_USING_INS5T8025 is not set
# CONFIG_PKG_USING_IRUART is not set
# CONFIG_PKG_USING_ST7305 is not set
# CONFIG_PKG_USING_TM1668 is not set
# CONFIG_PKG_USING_SPI_TOOLS is not set
# end of peripheral libraries and drivers
@ -1512,8 +1528,12 @@ CONFIG_BSP_UART3_RX_USING_DMA=y
# CONFIG_BSP_UART3_TX_USING_DMA is not set
CONFIG_BSP_UART3_RX_BUFSIZE=1024
CONFIG_BSP_UART3_TX_BUFSIZE=512
# CONFIG_BSP_USING_PWM is not set
CONFIG_BSP_USING_PWM=y
CONFIG_BSP_USING_PWM1=y
CONFIG_BSP_USING_PWM1_CH1=y
# CONFIG_BSP_USING_QSPI is not set
CONFIG_BSP_USING_ADC=y
CONFIG_BSP_USING_ADC1=y
# CONFIG_BSP_USING_SPI is not set
# CONFIG_BSP_USING_CRC is not set
# CONFIG_BSP_USING_RNG is not set

View File

@ -29,11 +29,13 @@ PROJECT(rtthread C CXX ASM)
INCLUDE_DIRECTORIES(
.
applications
applications/controller
applications/erpc
applications/erpc/service
applications/erpc/client
applications/erpc/common
applications/erpc/proto/generated
applications/servo_manager
board
board/CubeMX_Config/Inc
board/ports/usb
@ -101,26 +103,25 @@ ADD_DEFINITIONS(
# Library source files
SET(RT_APP_ERPC_SOURCES
applications/erpc/service/src/erpc_server_main.cpp
applications/erpc/proto/generated/head_service_interface.cpp
applications/erpc/common/src/erpc_error_handler.cpp
applications/erpc/proto/generated/face_servo_interface.cpp
applications/erpc/service/src/head_service_impl.cpp
applications/erpc/proto/generated/head_service_server.cpp
applications/erpc/proto/generated/face_servo_server.cpp
applications/erpc/service/src/erpc_server_main.cpp
)
SET(RT_APPLICATIONS_SOURCES
applications/main.c
applications/servo.c
)
SET(RT_CHERRYUSB_SOURCES
rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_msh.c
rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c
rt-thread/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c
rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c
rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c
rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c
rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_msh.c
rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c
rt-thread/components/drivers/usb/cherryusb/core/usbd_core.c
rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c
)
SET(RT_COMPILER_SOURCES
@ -133,9 +134,13 @@ SET(RT_COMPILER_SOURCES
rt-thread/components/libc/compilers/newlib/syscalls.c
)
SET(RT_CONTROLLER_SOURCES
applications/controller/src/pid_controller.cpp
)
SET(RT_CPP_SOURCES
rt-thread/components/libc/cplusplus/cxx_crt_init.c
rt-thread/components/libc/cplusplus/cxx_crt.cpp
rt-thread/components/libc/cplusplus/cxx_crt_init.c
)
SET(RT_DEVICEDRIVERS_SOURCES
@ -149,6 +154,8 @@ SET(RT_DEVICEDRIVERS_SOURCES
rt-thread/components/drivers/ipc/ringbuffer.c
rt-thread/components/drivers/ipc/waitqueue.c
rt-thread/components/drivers/ipc/workqueue.c
rt-thread/components/drivers/misc/adc.c
rt-thread/components/drivers/misc/rt_drv_pwm.c
rt-thread/components/drivers/pin/dev_pin.c
rt-thread/components/drivers/serial/dev_serial.c
rt-thread/components/drivers/spi/dev_spi.c
@ -161,37 +168,40 @@ SET(RT_DRIVERS_SOURCES
board/ports/usb/usb_cdc_char_device.c
board/ports/usb/usb_cdc_init.c
libraries/STM32H7xx_HAL/CMSIS/Device/ST/STM32H7xx/Source/Templates/gcc/startup_stm32h750xx.s
libraries/HAL_Drivers/drivers/drv_adc.c
libraries/HAL_Drivers/drivers/drv_gpio.c
libraries/HAL_Drivers/drivers/drv_pwm.c
libraries/HAL_Drivers/drivers/drv_spi.c
libraries/HAL_Drivers/drivers/drv_tim.c
libraries/HAL_Drivers/drivers/drv_usart.c
libraries/HAL_Drivers/drv_common.c
)
SET(RT_ERPC_SOURCES
packages/erpc-1.14.0/erpc_c/infra/erpc_server.cpp
packages/erpc-1.14.0/erpc_c/port/erpc_port_rtt.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_framed_transport.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_message_buffer.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_crc16.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_simple_server.cpp
packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_setup_mbf_dynamic.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_message_loggers.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_server_setup.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_transport_arbitrator.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_framed_transport.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_message_buffer.cpp
packages/erpc-1.14.0/erpc_c/transports/erpc_inter_thread_buffer_transport.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_basic_codec.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_setup_mbf_static.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_setup_usb_cdc.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_pre_post_action.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_setup_mbf_dynamic.cpp
packages/erpc-1.14.0/erpc_c/port/erpc_threading_pthreads.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_setup_mbf_static.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_simple_server.cpp
packages/erpc-1.14.0/erpc_c/port/erpc_port_rtt.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_server.cpp
packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_basic_codec.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_pre_post_action.cpp
packages/erpc-1.14.0/erpc_c/transports/erpc_inter_thread_buffer_transport.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_setup_usb_cdc.cpp
)
SET(RT_FINSH_SOURCES
rt-thread/components/finsh/msh.c
rt-thread/components/finsh/cmd.c
rt-thread/components/finsh/msh_parse.c
rt-thread/components/finsh/shell.c
rt-thread/components/finsh/msh_parse.c
rt-thread/components/finsh/cmd.c
rt-thread/components/finsh/msh.c
)
SET(RT_KERNEL_SOURCES
@ -213,17 +223,16 @@ SET(RT_KERNEL_SOURCES
)
SET(RT_KLIBC_SOURCES
rt-thread/src/klibc/rt_vsnprintf_tiny.c
rt-thread/src/klibc/rt_vsscanf.c
rt-thread/src/klibc/kstring.c
rt-thread/src/klibc/kstdio.c
rt-thread/src/klibc/kerrno.c
rt-thread/src/klibc/kstdio.c
rt-thread/src/klibc/kstring.c
rt-thread/src/klibc/rt_vsscanf.c
)
SET(RT_KTIME_SOURCES
rt-thread/components/drivers/ktime/src/cputimer.c
rt-thread/components/drivers/ktime/src/hrtimer.c
rt-thread/components/drivers/ktime/src/boottime.c
rt-thread/components/drivers/ktime/src/cputimer.c
)
SET(RT_LIBCPU_SOURCES
@ -237,29 +246,34 @@ SET(RT_LIBCPU_SOURCES
SET(RT_LIBRARIES_SOURCES
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_usart.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rng.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cryp.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cec.c
libraries/STM32H7xx_HAL/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sram.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_comp.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cryp_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_lptim.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sram.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cryp_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c
libraries/STM32H7xx_HAL/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_usart.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cec.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cryp.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rng.c
)
SET(RT_POSIX_SOURCES
@ -276,6 +290,10 @@ SET(RT_POSIX_SOURCES
rt-thread/components/libc/posix/tls/emutls.c
)
SET(RT_SERVO_MANAGER_SOURCES
applications/servo_manager/src/servo_manager.cpp
)
SET(RT_UTC_UTEST_SOURCES
)
@ -302,6 +320,7 @@ SET(RT_COMPILER_LIBS
ADD_LIBRARY(rtt_app_erpc OBJECT ${RT_APP_ERPC_SOURCES})
ADD_LIBRARY(rtt_CherryUSB OBJECT ${RT_CHERRYUSB_SOURCES})
ADD_LIBRARY(rtt_Compiler OBJECT ${RT_COMPILER_SOURCES})
ADD_LIBRARY(rtt_controller OBJECT ${RT_CONTROLLER_SOURCES})
ADD_LIBRARY(rtt_CPP OBJECT ${RT_CPP_SOURCES})
ADD_LIBRARY(rtt_DeviceDrivers OBJECT ${RT_DEVICEDRIVERS_SOURCES})
ADD_LIBRARY(rtt_Drivers OBJECT ${RT_DRIVERS_SOURCES})
@ -313,6 +332,7 @@ ADD_LIBRARY(rtt_ktime OBJECT ${RT_KTIME_SOURCES})
ADD_LIBRARY(rtt_libcpu OBJECT ${RT_LIBCPU_SOURCES})
ADD_LIBRARY(rtt_Libraries OBJECT ${RT_LIBRARIES_SOURCES})
ADD_LIBRARY(rtt_POSIX OBJECT ${RT_POSIX_SOURCES})
ADD_LIBRARY(rtt_servo_manager OBJECT ${RT_SERVO_MANAGER_SOURCES})
# Interface libraries
ADD_LIBRARY(rtt_utc_UTest INTERFACE)
@ -330,6 +350,7 @@ TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME}.elf
rtt_app_erpc
rtt_CherryUSB
rtt_Compiler
rtt_controller
rtt_CPP
rtt_DeviceDrivers
rtt_Drivers
@ -341,6 +362,7 @@ TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME}.elf
rtt_libcpu
rtt_Libraries
rtt_POSIX
rtt_servo_manager
rtt_utc_UTest
rtt_utestcases
)

View File

@ -0,0 +1,10 @@
from building import *
import os
cwd = GetCurrentDir()
src = Glob('src/*.cpp')
CPPPATH = [cwd]
group = DefineGroup('controller', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,68 @@
//
// Created by Administrator on 2026/1/16.
//
#ifndef RTTHREAD_PID_CONTROLLER_H
#define RTTHREAD_PID_CONTROLLER_H
class PidController
{
public:
PidController();
// 设置目标(通用 target
void setTarget(double target);
// PID 增益
void setGains(double kp, double ki, double kd);
/// 设置积分上下限: lower <= I <= upper
/// 若 upper <= lower则不启用积分限幅
void setIntegralLimits(double lower, double upper);
/// 设置误差死区: |error| < deadzone 时视为 0
void setDeadzone(double deadzone);
/// 设置 D 项滤波系数(简单一阶滤波)
/// coeff <= 0 表示不启用滤波
void setDerivativeFilterCoeff(double coeff);
/// 重置内部状态(积分/上一拍误差/滤波器)
void reset(double integral = 0.0, double prev_error = 0.0);
/// 核心:根据当前值计算控制量
double compute(double x, double dt);
private:
// gains
double kp_;
double ki_;
double kd_;
// target
double target_;
// state
double integralError_;
double prevError_;
// integral clamp
double iLower_;
double iUpper_;
// deadzone
double deadzone_;
// derivative filter
double dFilterCoeff_;
double dErrorFiltered_;
bool initialized_;
};
#endif //RTTHREAD_PID_CONTROLLER_H

View File

@ -0,0 +1,96 @@
//
// Created by Administrator on 2026/1/16.
//
#include "controller/include/pid_controller.h"
#include <algorithm>
#include <cmath>
PidController::PidController()
: kp_(0.0),
ki_(0.0),
kd_(0.0),
target_(0.0),
integralError_(0.0),
prevError_(0.0),
iLower_(0.0),
iUpper_(0.0),
deadzone_(0.0),
dFilterCoeff_(0.0),
dErrorFiltered_(0.0),
initialized_(false) {}
void PidController::setTarget(double target) {
target_ = target;
}
void PidController::setGains(double kp, double ki, double kd) {
kp_ = kp;
ki_ = ki;
kd_ = kd;
}
void PidController::setIntegralLimits(double lower, double upper) {
iLower_ = lower;
iUpper_ = upper;
}
void PidController::setDeadzone(double deadzone) {
deadzone_ = std::max(0.0, deadzone);
}
void PidController::setDerivativeFilterCoeff(double coeff) {
dFilterCoeff_ = coeff;
if (dFilterCoeff_ <= 0.0) {
dErrorFiltered_ = 0.0;
}
}
void PidController::reset(double integral, double prev_error) {
integralError_ = integral;
prevError_ = prev_error;
dErrorFiltered_ = 0.0;
initialized_ = false;
}
double PidController::compute(double x, double dt) {
if (dt <= 0.0) return 0.0;
// 误差target - current
double error = target_ - x;
if (std::abs(error) < deadzone_) error = 0.0;
// 第一次调用时初始化 prevError避免 dError 突刺
if (!initialized_) {
prevError_ = error;
initialized_ = true;
}
// 积分
integralError_ += error * dt;
// 积分限幅(若启用)
if (iUpper_ > iLower_) {
integralError_ = std::clamp(integralError_, iLower_, iUpper_);
}
// 微分:对误差微分
const double dError = (error - prevError_) / dt;
// 一阶滤波y = y + a*(x - y)a = coeff*dt (夹到[0,1])
if (dFilterCoeff_ > 0.0) {
const double a = std::clamp(dFilterCoeff_ * dt, 0.0, 1.0);
dErrorFiltered_ = dErrorFiltered_ + a * (dError - dErrorFiltered_);
} else {
dErrorFiltered_ = dError;
}
prevError_ = error;
const double p = kp_ * error;
const double i = ki_ * integralError_;
const double d = kd_ * dErrorFiltered_;
return p + i + d;
}

View File

@ -22,13 +22,13 @@ if GetDepend(['ERPC_MODE_CLIENT']):
gen_dir = p('proto', 'generated')
# interface 建议始终编译(两端都可能需要)
src += [p('proto', 'generated', 'head_service_interface.cpp')]
src += [p('proto', 'generated', 'face_servo_interface.cpp')]
src += [p('common', 'src', 'erpc_error_handler.cpp')]
if GetDepend(['ERPC_MODE_SERVER']):
src += [p('proto', 'generated', 'head_service_server.cpp')]
src += [p('proto', 'generated', 'face_servo_server.cpp')]
if GetDepend(['ERPC_MODE_CLIENT']):
src += [p('proto', 'generated', 'head_service_client.cpp')]
src += [p('proto', 'generated', 'face_servo_client.cpp')]
CPPPATH = [
cwd,

View File

@ -0,0 +1,30 @@
// face_servo.erpc
// 生成命令 .\erpcgen.exe -o .\generated\ -g c .\face_servo.erpc
// .\erpcgen.exe -g py .\face_servo.erpc
program face_servo
// 舵机ID字符串最大长度
const int32 kServoIdMaxLen = 32
// 最多支持的舵机数量
const int32 kMaxServoCount = 48
// 按 ID 设置角度的命令
struct ServoCmd {
string id @max_length(kServoIdMaxLen)
float angle_deg
}
interface FaceServo
{
// 接口1一次性设置所有舵机角度可变长度
// angles_deg 的顺序由固件映射表顺序定义
setAllAngles(list<float> angles_deg @max_length(kMaxServoCount)) -> int32
// 接口2按字符串ID批量设置角度可变长度
setAngles(list<ServoCmd> cmds @max_length(kMaxServoCount)) -> int32
// 单个按字符串ID设置角度
setAngle(string id @max_length(kServoIdMaxLen), float angle_deg) -> int32
}

View File

@ -0,0 +1,69 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "c_face_servo_client.h"
#include "face_servo_client.hpp"
#include "erpc_manually_constructed.hpp"
using namespace erpc;
using namespace std;
using namespace erpcShim;
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
FaceServo_client *s_FaceServo_client = nullptr;
#else
ERPC_MANUALLY_CONSTRUCTED_STATIC(FaceServo_client, s_FaceServo_client);
#endif
int32_t setAllAngles(const list_float_1_t * angles_deg)
{
int32_t result;
result = s_FaceServo_client->setAllAngles(angles_deg);
return result;
}
int32_t setAngles(const list_ServoCmd_1_t * cmds)
{
int32_t result;
result = s_FaceServo_client->setAngles(cmds);
return result;
}
int32_t setAngle(const char * id, float angle_deg)
{
int32_t result;
result = s_FaceServo_client->setAngle(id, angle_deg);
return result;
}
void initFaceServo_client(erpc_client_t client)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
erpc_assert(s_FaceServo_client == nullptr);
s_FaceServo_client = new FaceServo_client(reinterpret_cast<ClientManager *>(client));
#else
erpc_assert(!s_FaceServo_client.isUsed());
s_FaceServo_client.construct(reinterpret_cast<ClientManager *>(client));
#endif
}
void deinitFaceServo_client(void)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
if (s_FaceServo_client != nullptr)
{
delete s_FaceServo_client;
s_FaceServo_client = nullptr;
}
#else
s_FaceServo_client.destroy();
#endif
}

View File

@ -0,0 +1,51 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_c_face_servo_client_h_)
#define _c_face_servo_client_h_
#include "face_servo_common.h"
#include "erpc_client_manager.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
#define ERPC_FUNCTIONS_DEFINITIONS
/*! @brief FaceServo identifiers */
enum _FaceServo_ids
{
kFaceServo_service_id = 1,
kFaceServo_setAllAngles_id = 1,
kFaceServo_setAngles_id = 2,
kFaceServo_setAngle_id = 3,
};
//! @name FaceServo
//@{
int32_t setAllAngles(const list_float_1_t * angles_deg);
int32_t setAngles(const list_ServoCmd_1_t * cmds);
int32_t setAngle(const char * id, float angle_deg);
//@}
#endif // ERPC_FUNCTIONS_DEFINITIONS
void initFaceServo_client(erpc_client_t client);
void deinitFaceServo_client(void);
#if defined(__cplusplus)
}
#endif
#endif // _c_face_servo_client_h_

View File

@ -0,0 +1,89 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include <new>
#include "c_face_servo_server.h"
#include "face_servo_server.hpp"
#include "erpc_manually_constructed.hpp"
using namespace erpc;
using namespace std;
using namespace erpcShim;
class FaceServo_server: public FaceServo_interface
{
public:
virtual ~FaceServo_server() {};
int32_t setAllAngles(const list_float_1_t * angles_deg)
{
int32_t result;
result = ::setAllAngles(angles_deg);
return result;
}
int32_t setAngles(const list_ServoCmd_1_t * cmds)
{
int32_t result;
result = ::setAngles(cmds);
return result;
}
int32_t setAngle(const char * id, float angle_deg)
{
int32_t result;
result = ::setAngle(id, angle_deg);
return result;
}
};
ERPC_MANUALLY_CONSTRUCTED_STATIC(FaceServo_service, s_FaceServo_service);
ERPC_MANUALLY_CONSTRUCTED_STATIC(FaceServo_server, s_FaceServo_server);
erpc_service_t create_FaceServo_service(void)
{
erpc_service_t service;
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
service = new (nothrow) FaceServo_service(new (nothrow)FaceServo_server());
#else
if (s_FaceServo_service.isUsed())
{
service = NULL;
}
else
{
s_FaceServo_server.construct();
s_FaceServo_service.construct(s_FaceServo_server.get());
service = s_FaceServo_service.get();
}
#endif
return service;
}
void destroy_FaceServo_service(erpc_service_t service)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
if (service)
{
delete (FaceServo_server *)(((FaceServo_service *)service)->getHandler());
delete (FaceServo_service *)service;
}
#else
(void)service;
erpc_assert(service == s_FaceServo_service.get());
s_FaceServo_service.destroy();
s_FaceServo_server.destroy();
#endif
}

View File

@ -0,0 +1,56 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_c_face_servo_server_h_)
#define _c_face_servo_server_h_
#include "face_servo_common.h"
#if defined(__cplusplus)
extern "C"
{
#endif
typedef void * erpc_service_t;
#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
#define ERPC_FUNCTIONS_DEFINITIONS
/*! @brief FaceServo identifiers */
enum _FaceServo_ids
{
kFaceServo_service_id = 1,
kFaceServo_setAllAngles_id = 1,
kFaceServo_setAngles_id = 2,
kFaceServo_setAngle_id = 3,
};
//! @name FaceServo
//@{
int32_t setAllAngles(const list_float_1_t * angles_deg);
int32_t setAngles(const list_ServoCmd_1_t * cmds);
int32_t setAngle(const char * id, float angle_deg);
//@}
#endif // ERPC_FUNCTIONS_DEFINITIONS
/*! @brief Return FaceServo_service service object. */
erpc_service_t create_FaceServo_service(void);
/*! @brief Destroy FaceServo_service service object. */
void destroy_FaceServo_service(erpc_service_t service);
#if defined(__cplusplus)
}
#endif
#endif // _c_face_servo_server_h_

View File

@ -1,61 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "c_head_service_client.h"
#include "head_service_client.hpp"
#include "erpc_manually_constructed.hpp"
using namespace erpc;
using namespace std;
using namespace erpcShim;
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
demo_client *s_demo_client = nullptr;
#else
ERPC_MANUALLY_CONSTRUCTED_STATIC(demo_client, s_demo_client);
#endif
int32_t add(int32_t a, int32_t b)
{
int32_t result;
result = s_demo_client->add(a, b);
return result;
}
int64_t sum_i32(const list_int32_1_t * arr)
{
int64_t result;
result = s_demo_client->sum_i32(arr);
return result;
}
void initdemo_client(erpc_client_t client)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
erpc_assert(s_demo_client == nullptr);
s_demo_client = new demo_client(reinterpret_cast<ClientManager *>(client));
#else
erpc_assert(!s_demo_client.isUsed());
s_demo_client.construct(reinterpret_cast<ClientManager *>(client));
#endif
}
void deinitdemo_client(void)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
if (s_demo_client != nullptr)
{
delete s_demo_client;
s_demo_client = nullptr;
}
#else
s_demo_client.destroy();
#endif
}

View File

@ -1,48 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_c_head_service_client_h_)
#define _c_head_service_client_h_
#include "head_service_common.h"
#include "erpc_client_manager.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
#define ERPC_FUNCTIONS_DEFINITIONS
/*! @brief demo identifiers */
enum _demo_ids
{
kdemo_service_id = 1,
kdemo_add_id = 1,
kdemo_sum_i32_id = 2,
};
//! @name demo
//@{
int32_t add(int32_t a, int32_t b);
int64_t sum_i32(const list_int32_1_t * arr);
//@}
#endif // ERPC_FUNCTIONS_DEFINITIONS
void initdemo_client(erpc_client_t client);
void deinitdemo_client(void);
#if defined(__cplusplus)
}
#endif
#endif // _c_head_service_client_h_

View File

@ -1,81 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include <new>
#include "c_head_service_server.h"
#include "head_service_server.hpp"
#include "erpc_manually_constructed.hpp"
using namespace erpc;
using namespace std;
using namespace erpcShim;
class demo_server: public demo_interface
{
public:
virtual ~demo_server() {};
int32_t add(int32_t a, int32_t b)
{
int32_t result;
result = ::add(a, b);
return result;
}
int64_t sum_i32(const list_int32_1_t * arr)
{
int64_t result;
result = ::sum_i32(arr);
return result;
}
};
ERPC_MANUALLY_CONSTRUCTED_STATIC(demo_service, s_demo_service);
ERPC_MANUALLY_CONSTRUCTED_STATIC(demo_server, s_demo_server);
erpc_service_t create_demo_service(void)
{
erpc_service_t service;
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
service = new (nothrow) demo_service(new (nothrow)demo_server());
#else
if (s_demo_service.isUsed())
{
service = NULL;
}
else
{
s_demo_server.construct();
s_demo_service.construct(s_demo_server.get());
service = s_demo_service.get();
}
#endif
return service;
}
void destroy_demo_service(erpc_service_t service)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
if (service)
{
delete (demo_server *)(((demo_service *)service)->getHandler());
delete (demo_service *)service;
}
#else
(void)service;
erpc_assert(service == s_demo_service.get());
s_demo_service.destroy();
s_demo_server.destroy();
#endif
}

View File

@ -1,53 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_c_head_service_server_h_)
#define _c_head_service_server_h_
#include "head_service_common.h"
#if defined(__cplusplus)
extern "C"
{
#endif
typedef void * erpc_service_t;
#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
#define ERPC_FUNCTIONS_DEFINITIONS
/*! @brief demo identifiers */
enum _demo_ids
{
kdemo_service_id = 1,
kdemo_add_id = 1,
kdemo_sum_i32_id = 2,
};
//! @name demo
//@{
int32_t add(int32_t a, int32_t b);
int64_t sum_i32(const list_int32_1_t * arr);
//@}
#endif // ERPC_FUNCTIONS_DEFINITIONS
/*! @brief Return demo_service service object. */
erpc_service_t create_demo_service(void);
/*! @brief Destroy demo_service service object. */
void destroy_demo_service(erpc_service_t service);
#if defined(__cplusplus)
}
#endif
#endif // _c_head_service_server_h_

View File

@ -0,0 +1,303 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include "erpc_port.h"
#endif
#include "erpc_codec.hpp"
#include "face_servo_client.hpp"
#include "erpc_manually_constructed.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace erpc;
using namespace std;
using namespace erpcShim;
// Constant variable definitions
#if defined(__MINGW32__)
__declspec( selectany )
#else
#pragma weak kServoIdMaxLen
#endif
extern const int32_t kServoIdMaxLen = 32;
#if defined(__MINGW32__)
__declspec( selectany )
#else
#pragma weak kMaxServoCount
#endif
extern const int32_t kMaxServoCount = 48;
//! @brief Function to write struct list_float_1_t
static void write_list_float_1_t_struct(erpc::Codec * codec, const list_float_1_t * data);
//! @brief Function to write struct ServoCmd
static void write_ServoCmd_struct(erpc::Codec * codec, const ServoCmd * data);
//! @brief Function to write struct list_ServoCmd_1_t
static void write_list_ServoCmd_1_t_struct(erpc::Codec * codec, const list_ServoCmd_1_t * data);
// Write struct list_float_1_t function implementation
static void write_list_float_1_t_struct(erpc::Codec * codec, const list_float_1_t * data)
{
if(NULL == data)
{
return;
}
codec->startWriteList(data->elementsCount);
for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
{
codec->write(data->elements[listCount]);
}
}
// Write struct ServoCmd function implementation
static void write_ServoCmd_struct(erpc::Codec * codec, const ServoCmd * data)
{
if(NULL == data)
{
return;
}
{
uint32_t id_len = strlen((const char*)data->id);
codec->writeString(id_len, (const char*)data->id);
}
codec->write(data->angle_deg);
}
// Write struct list_ServoCmd_1_t function implementation
static void write_list_ServoCmd_1_t_struct(erpc::Codec * codec, const list_ServoCmd_1_t * data)
{
if(NULL == data)
{
return;
}
codec->startWriteList(data->elementsCount);
for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
{
write_ServoCmd_struct(codec, &(data->elements[listCount]));
}
}
FaceServo_client::FaceServo_client(ClientManager *manager)
:m_clientManager(manager)
{
}
FaceServo_client::~FaceServo_client()
{
}
// FaceServo interface setAllAngles function client shim.
int32_t FaceServo_client::setAllAngles(const list_float_1_t * angles_deg)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_setAllAnglesId, request.getSequence());
write_list_float_1_t_struct(codec, angles_deg);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_setAllAnglesId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}
// FaceServo interface setAngles function client shim.
int32_t FaceServo_client::setAngles(const list_ServoCmd_1_t * cmds)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_setAnglesId, request.getSequence());
write_list_ServoCmd_1_t_struct(codec, cmds);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_setAnglesId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}
// FaceServo interface setAngle function client shim.
int32_t FaceServo_client::setAngle(const char * id, float angle_deg)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_setAngleId, request.getSequence());
{
uint32_t id_len = strlen((const char*)id);
erpc_assert(kServoIdMaxLen >= 0);
erpc_assert(id_len <= static_cast<uint32_t>(kServoIdMaxLen));
codec->writeString(id_len, (const char*)id);
}
codec->write(angle_deg);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_setAngleId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}

View File

@ -0,0 +1,38 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_face_servo_client_hpp_)
#define _face_servo_client_hpp_
#include "face_servo_interface.hpp"
#include "erpc_client_manager.h"
namespace erpcShim
{
class FaceServo_client: public FaceServo_interface
{
public:
FaceServo_client(erpc::ClientManager *manager);
virtual ~FaceServo_client();
virtual int32_t setAllAngles(const list_float_1_t * angles_deg);
virtual int32_t setAngles(const list_ServoCmd_1_t * cmds);
virtual int32_t setAngle(const char * id, float angle_deg);
protected:
erpc::ClientManager *m_clientManager;
};
} // erpcShim
#endif // _face_servo_client_hpp_

View File

@ -0,0 +1,66 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_face_servo_common_h_)
#define _face_servo_common_h_
#if defined(__cplusplus)
extern "C"
{
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "erpc_version.h"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
#if !defined(ERPC_TYPE_DEFINITIONS_FACE_SERVO)
#define ERPC_TYPE_DEFINITIONS_FACE_SERVO
// Aliases data types declarations
typedef struct list_float_1_t list_float_1_t;
typedef struct ServoCmd ServoCmd;
typedef struct list_ServoCmd_1_t list_ServoCmd_1_t;
// Structures/unions data types declarations
struct list_float_1_t
{
float * elements;
uint32_t elementsCount;
};
struct ServoCmd
{
char * id;
float angle_deg;
};
struct list_ServoCmd_1_t
{
ServoCmd * elements;
uint32_t elementsCount;
};
// Constant variable declarations
extern const int32_t kServoIdMaxLen;
extern const int32_t kMaxServoCount;
#endif // ERPC_TYPE_DEFINITIONS_FACE_SERVO
#if defined(__cplusplus)
}
#endif
#endif // _face_servo_common_h_

View File

@ -0,0 +1,58 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_face_servo_common_hpp_)
#define _face_servo_common_hpp_
#include <cstddef>
#include <cstdint>
#include "erpc_version.h"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
#if !defined(ERPC_TYPE_DEFINITIONS_FACE_SERVO)
#define ERPC_TYPE_DEFINITIONS_FACE_SERVO
// Aliases data types declarations
typedef struct list_float_1_t list_float_1_t;
typedef struct ServoCmd ServoCmd;
typedef struct list_ServoCmd_1_t list_ServoCmd_1_t;
// Structures/unions data types declarations
struct list_float_1_t
{
float * elements;
uint32_t elementsCount;
};
struct ServoCmd
{
char * id;
float angle_deg;
};
struct list_ServoCmd_1_t
{
ServoCmd * elements;
uint32_t elementsCount;
};
// Constant variable declarations
extern const int32_t kServoIdMaxLen;
extern const int32_t kMaxServoCount;
#endif // ERPC_TYPE_DEFINITIONS_FACE_SERVO
#endif // _face_servo_common_hpp_

View File

@ -1,11 +1,11 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "head_service_interface.hpp"
#include "face_servo_interface.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
@ -15,6 +15,6 @@
using namespace std;
using namespace erpcShim;
demo_interface::~demo_interface(void)
FaceServo_interface::~FaceServo_interface(void)
{
}

View File

@ -0,0 +1,38 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_face_servo_interface_hpp_)
#define _face_servo_interface_hpp_
#include "face_servo_common.hpp"
namespace erpcShim
{
// Abstract base class for FaceServo
class FaceServo_interface
{
public:
static const uint8_t m_serviceId = 1;
static const uint8_t m_setAllAnglesId = 1;
static const uint8_t m_setAnglesId = 2;
static const uint8_t m_setAngleId = 3;
virtual ~FaceServo_interface(void);
virtual int32_t setAllAngles(const list_float_1_t * angles_deg) = 0;
virtual int32_t setAngles(const list_ServoCmd_1_t * cmds) = 0;
virtual int32_t setAngle(const char * id, float angle_deg) = 0;
private:
};
} // erpcShim
#endif // _face_servo_interface_hpp_

View File

@ -0,0 +1,384 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "face_servo_server.hpp"
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include <new>
#include "erpc_port.h"
#endif
#include "erpc_manually_constructed.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace erpc;
using namespace std;
using namespace erpcShim;
#if ERPC_NESTED_CALLS_DETECTION
extern bool nestingDetection;
#endif
// Constant variable definitions
#if defined(__MINGW32__)
__declspec( selectany )
#else
#pragma weak kServoIdMaxLen
#endif
extern const int32_t kServoIdMaxLen = 32;
#if defined(__MINGW32__)
__declspec( selectany )
#else
#pragma weak kMaxServoCount
#endif
extern const int32_t kMaxServoCount = 48;
//! @brief Function to read struct list_float_1_t
static void read_list_float_1_t_struct(erpc::Codec * codec, list_float_1_t * data);
//! @brief Function to read struct ServoCmd
static void read_ServoCmd_struct(erpc::Codec * codec, ServoCmd * data);
//! @brief Function to read struct list_ServoCmd_1_t
static void read_list_ServoCmd_1_t_struct(erpc::Codec * codec, list_ServoCmd_1_t * data);
// Read struct list_float_1_t function implementation
static void read_list_float_1_t_struct(erpc::Codec * codec, list_float_1_t * data)
{
if(NULL == data)
{
return;
}
codec->startReadList(data->elementsCount);
data->elements = (float *) erpc_malloc(data->elementsCount * sizeof(float));
if ((data->elements == NULL) && (data->elementsCount > 0))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
{
codec->read(data->elements[listCount]);
}
}
// Read struct ServoCmd function implementation
static void read_ServoCmd_struct(erpc::Codec * codec, ServoCmd * data)
{
if(NULL == data)
{
return;
}
{
uint32_t id_len;
char * id_local;
codec->readString(id_len, &id_local);
data->id = (char*) erpc_malloc((id_len + 1) * sizeof(char));
if ((data->id == NULL) || (id_local == NULL))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
else
{
memcpy(data->id, id_local, id_len);
(data->id)[id_len] = 0;
}
}
codec->read(data->angle_deg);
}
// Read struct list_ServoCmd_1_t function implementation
static void read_list_ServoCmd_1_t_struct(erpc::Codec * codec, list_ServoCmd_1_t * data)
{
if(NULL == data)
{
return;
}
codec->startReadList(data->elementsCount);
data->elements = (ServoCmd *) erpc_malloc(data->elementsCount * sizeof(ServoCmd));
if ((data->elements == NULL) && (data->elementsCount > 0))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
{
read_ServoCmd_struct(codec, &(data->elements[listCount]));
}
}
//! @brief Function to free space allocated inside struct list_float_1_t
static void free_list_float_1_t_struct(list_float_1_t * data);
//! @brief Function to free space allocated inside struct ServoCmd
static void free_ServoCmd_struct(ServoCmd * data);
//! @brief Function to free space allocated inside struct list_ServoCmd_1_t
static void free_list_ServoCmd_1_t_struct(list_ServoCmd_1_t * data);
// Free space allocated inside struct list_float_1_t function implementation
static void free_list_float_1_t_struct(list_float_1_t * data)
{
erpc_free(data->elements);
}
// Free space allocated inside struct ServoCmd function implementation
static void free_ServoCmd_struct(ServoCmd * data)
{
erpc_free(data->id);
}
// Free space allocated inside struct list_ServoCmd_1_t function implementation
static void free_list_ServoCmd_1_t_struct(list_ServoCmd_1_t * data)
{
for (uint32_t listCount = 0; listCount < data->elementsCount; ++listCount)
{
free_ServoCmd_struct(&data->elements[listCount]);
}
erpc_free(data->elements);
}
FaceServo_service::FaceServo_service(FaceServo_interface *_FaceServo_interface)
: erpc::Service(FaceServo_interface::m_serviceId)
, m_handler(_FaceServo_interface)
{
}
FaceServo_service::~FaceServo_service()
{
}
// return service interface handler.
FaceServo_interface* FaceServo_service::getHandler(void)
{
return m_handler;
}
// Call the correct server shim based on method unique ID.
erpc_status_t FaceServo_service::handleInvocation(uint32_t methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory, Transport * transport)
{
erpc_status_t erpcStatus;
switch (methodId)
{
case FaceServo_interface::m_setAllAnglesId:
{
erpcStatus = setAllAngles_shim(codec, messageFactory, transport, sequence);
break;
}
case FaceServo_interface::m_setAnglesId:
{
erpcStatus = setAngles_shim(codec, messageFactory, transport, sequence);
break;
}
case FaceServo_interface::m_setAngleId:
{
erpcStatus = setAngle_shim(codec, messageFactory, transport, sequence);
break;
}
default:
{
erpcStatus = kErpcStatus_InvalidArgument;
break;
}
}
return erpcStatus;
}
// Server shim for setAllAngles of FaceServo interface.
erpc_status_t FaceServo_service::setAllAngles_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
list_float_1_t *angles_deg = NULL;
angles_deg = (list_float_1_t *) erpc_malloc(sizeof(list_float_1_t));
if (angles_deg == NULL)
{
codec->updateStatus(kErpcStatus_MemoryError);
}
int32_t result;
// startReadMessage() was already called before this shim was invoked.
read_list_float_1_t_struct(codec, angles_deg);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->setAllAngles(angles_deg);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, FaceServo_interface::m_serviceId, FaceServo_interface::m_setAllAnglesId, sequence);
codec->write(result);
err = codec->getStatus();
}
if (angles_deg)
{
free_list_float_1_t_struct(angles_deg);
}
erpc_free(angles_deg);
return err;
}
// Server shim for setAngles of FaceServo interface.
erpc_status_t FaceServo_service::setAngles_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
list_ServoCmd_1_t *cmds = NULL;
cmds = (list_ServoCmd_1_t *) erpc_malloc(sizeof(list_ServoCmd_1_t));
if (cmds == NULL)
{
codec->updateStatus(kErpcStatus_MemoryError);
}
int32_t result;
// startReadMessage() was already called before this shim was invoked.
read_list_ServoCmd_1_t_struct(codec, cmds);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->setAngles(cmds);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, FaceServo_interface::m_serviceId, FaceServo_interface::m_setAnglesId, sequence);
codec->write(result);
err = codec->getStatus();
}
if (cmds)
{
free_list_ServoCmd_1_t_struct(cmds);
}
erpc_free(cmds);
return err;
}
// Server shim for setAngle of FaceServo interface.
erpc_status_t FaceServo_service::setAngle_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
char * id = NULL;
float angle_deg;
int32_t result;
// startReadMessage() was already called before this shim was invoked.
{
uint32_t id_len;
char * id_local;
codec->readString(id_len, &id_local);
if ((kServoIdMaxLen >= 0) && (id_len <= static_cast<uint32_t>(kServoIdMaxLen)))
{
id = (char*) erpc_malloc((kServoIdMaxLen + 1) * sizeof(char));
if ((id == NULL) || (id_local == NULL))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
else
{
memcpy(id, id_local, id_len);
(id)[id_len] = 0;
}
}
else
{
codec->updateStatus(kErpcStatus_InvalidArgument);
}
}
codec->read(angle_deg);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->setAngle(id, angle_deg);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, FaceServo_interface::m_serviceId, FaceServo_interface::m_setAngleId, sequence);
codec->write(result);
err = codec->getStatus();
}
erpc_free(id);
return err;
}

View File

@ -0,0 +1,55 @@
/*
* Generated by erpcgen 1.14.0 on Wed Jan 14 16:06:40 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_face_servo_server_hpp_)
#define _face_servo_server_hpp_
#include "face_servo_interface.hpp"
#include "erpc_server.hpp"
#include "erpc_codec.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
namespace erpcShim
{
/*!
* @brief Service subclass for FaceServo.
*/
class FaceServo_service : public erpc::Service
{
public:
FaceServo_service(FaceServo_interface *_FaceServo_interface);
virtual ~FaceServo_service();
/*! @brief return service interface handler. */
FaceServo_interface* getHandler(void);
/*! @brief Call the correct server shim based on method unique ID. */
virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport);
private:
FaceServo_interface *m_handler;
/*! @brief Server shim for setAllAngles of FaceServo interface. */
erpc_status_t setAllAngles_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for setAngles of FaceServo interface. */
erpc_status_t setAngles_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for setAngle of FaceServo interface. */
erpc_status_t setAngle_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
};
} // erpcShim
#endif // _face_servo_server_hpp_

View File

@ -1,180 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include "erpc_port.h"
#endif
#include "erpc_codec.hpp"
#include "head_service_client.hpp"
#include "erpc_manually_constructed.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace erpc;
using namespace std;
using namespace erpcShim;
//! @brief Function to write struct list_int32_1_t
static void write_list_int32_1_t_struct(erpc::Codec * codec, const list_int32_1_t * data);
// Write struct list_int32_1_t function implementation
static void write_list_int32_1_t_struct(erpc::Codec * codec, const list_int32_1_t * data)
{
if(NULL == data)
{
return;
}
codec->startWriteList(data->elementsCount);
for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
{
codec->write(data->elements[listCount]);
}
}
demo_client::demo_client(ClientManager *manager)
:m_clientManager(manager)
{
}
demo_client::~demo_client()
{
}
// demo interface add function client shim.
int32_t demo_client::add(int32_t a, int32_t b)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_addId, request.getSequence());
codec->write(a);
codec->write(b);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_addId);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}
// demo interface sum_i32 function client shim.
int64_t demo_client::sum_i32(const list_int32_1_t * arr)
{
erpc_status_t err = kErpcStatus_Success;
int64_t result;
#if ERPC_PRE_POST_ACTION
pre_post_action_cb preCB = m_clientManager->getPreCB();
if (preCB)
{
preCB();
}
#endif
// Get a new request.
RequestContext request = m_clientManager->createRequest(false);
// Encode the request.
Codec * codec = request.getCodec();
if (codec == NULL)
{
err = kErpcStatus_MemoryError;
}
else
{
codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_sum_i32Id, request.getSequence());
write_list_int32_1_t_struct(codec, arr);
// Send message to server
// Codec status is checked inside this function.
m_clientManager->performRequest(request);
codec->read(result);
err = codec->getStatus();
}
// Dispose of the request.
m_clientManager->releaseRequest(request);
// Invoke error handler callback function
m_clientManager->callErrorHandler(err, m_sum_i32Id);
#if ERPC_PRE_POST_ACTION
pre_post_action_cb postCB = m_clientManager->getPostCB();
if (postCB)
{
postCB();
}
#endif
if (err != kErpcStatus_Success)
{
result = -1;
}
return result;
}

View File

@ -1,36 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_head_service_client_hpp_)
#define _head_service_client_hpp_
#include "head_service_interface.hpp"
#include "erpc_client_manager.h"
namespace erpcShim
{
class demo_client: public demo_interface
{
public:
demo_client(erpc::ClientManager *manager);
virtual ~demo_client();
virtual int32_t add(int32_t a, int32_t b);
virtual int64_t sum_i32(const list_int32_1_t * arr);
protected:
erpc::ClientManager *m_clientManager;
};
} // erpcShim
#endif // _head_service_client_hpp_

View File

@ -1,47 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_head_service_common_h_)
#define _head_service_common_h_
#if defined(__cplusplus)
extern "C"
{
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "erpc_version.h"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
#if !defined(ERPC_TYPE_DEFINITIONS_ERPCSHIM)
#define ERPC_TYPE_DEFINITIONS_ERPCSHIM
// Aliases data types declarations
typedef struct list_int32_1_t list_int32_1_t;
// Structures/unions data types declarations
struct list_int32_1_t
{
int32_t * elements;
uint32_t elementsCount;
};
#endif // ERPC_TYPE_DEFINITIONS_ERPCSHIM
#if defined(__cplusplus)
}
#endif
#endif // _head_service_common_h_

View File

@ -1,39 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_head_service_common_hpp_)
#define _head_service_common_hpp_
#include <cstddef>
#include <cstdint>
#include "erpc_version.h"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
#if !defined(ERPC_TYPE_DEFINITIONS_ERPCSHIM)
#define ERPC_TYPE_DEFINITIONS_ERPCSHIM
// Aliases data types declarations
typedef struct list_int32_1_t list_int32_1_t;
// Structures/unions data types declarations
struct list_int32_1_t
{
int32_t * elements;
uint32_t elementsCount;
};
#endif // ERPC_TYPE_DEFINITIONS_ERPCSHIM
#endif // _head_service_common_hpp_

View File

@ -1,35 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_head_service_interface_hpp_)
#define _head_service_interface_hpp_
#include "head_service_common.hpp"
namespace erpcShim
{
// Abstract base class for demo
class demo_interface
{
public:
static const uint8_t m_serviceId = 1;
static const uint8_t m_addId = 1;
static const uint8_t m_sum_i32Id = 2;
virtual ~demo_interface(void);
virtual int32_t add(int32_t a, int32_t b) = 0;
virtual int64_t sum_i32(const list_int32_1_t * arr) = 0;
private:
};
} // erpcShim
#endif // _head_service_interface_hpp_

View File

@ -1,209 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "head_service_server.hpp"
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include <new>
#include "erpc_port.h"
#endif
#include "erpc_manually_constructed.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace erpc;
using namespace std;
using namespace erpcShim;
#if ERPC_NESTED_CALLS_DETECTION
extern bool nestingDetection;
#endif
//! @brief Function to read struct list_int32_1_t
static void read_list_int32_1_t_struct(erpc::Codec * codec, list_int32_1_t * data);
// Read struct list_int32_1_t function implementation
static void read_list_int32_1_t_struct(erpc::Codec * codec, list_int32_1_t * data)
{
if(NULL == data)
{
return;
}
codec->startReadList(data->elementsCount);
data->elements = (int32_t *) erpc_malloc(data->elementsCount * sizeof(int32_t));
if ((data->elements == NULL) && (data->elementsCount > 0))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount)
{
codec->read(data->elements[listCount]);
}
}
//! @brief Function to free space allocated inside struct list_int32_1_t
static void free_list_int32_1_t_struct(list_int32_1_t * data);
// Free space allocated inside struct list_int32_1_t function implementation
static void free_list_int32_1_t_struct(list_int32_1_t * data)
{
erpc_free(data->elements);
}
demo_service::demo_service(demo_interface *_demo_interface)
: erpc::Service(demo_interface::m_serviceId)
, m_handler(_demo_interface)
{
}
demo_service::~demo_service()
{
}
// return service interface handler.
demo_interface* demo_service::getHandler(void)
{
return m_handler;
}
// Call the correct server shim based on method unique ID.
erpc_status_t demo_service::handleInvocation(uint32_t methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory, Transport * transport)
{
erpc_status_t erpcStatus;
switch (methodId)
{
case demo_interface::m_addId:
{
erpcStatus = add_shim(codec, messageFactory, transport, sequence);
break;
}
case demo_interface::m_sum_i32Id:
{
erpcStatus = sum_i32_shim(codec, messageFactory, transport, sequence);
break;
}
default:
{
erpcStatus = kErpcStatus_InvalidArgument;
break;
}
}
return erpcStatus;
}
// Server shim for add of demo interface.
erpc_status_t demo_service::add_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
int32_t a;
int32_t b;
int32_t result;
// startReadMessage() was already called before this shim was invoked.
codec->read(a);
codec->read(b);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->add(a, b);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, demo_interface::m_serviceId, demo_interface::m_addId, sequence);
codec->write(result);
err = codec->getStatus();
}
return err;
}
// Server shim for sum_i32 of demo interface.
erpc_status_t demo_service::sum_i32_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
list_int32_1_t *arr = NULL;
arr = (list_int32_1_t *) erpc_malloc(sizeof(list_int32_1_t));
if (arr == NULL)
{
codec->updateStatus(kErpcStatus_MemoryError);
}
int64_t result;
// startReadMessage() was already called before this shim was invoked.
read_list_int32_1_t_struct(codec, arr);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->sum_i32(arr);
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = false;
#endif
// preparing MessageBuffer for serializing data
err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize());
}
if (err == kErpcStatus_Success)
{
// preparing codec for serializing data
codec->reset(transport->reserveHeaderSize());
// Build response message.
codec->startWriteMessage(message_type_t::kReplyMessage, demo_interface::m_serviceId, demo_interface::m_sum_i32Id, sequence);
codec->write(result);
err = codec->getStatus();
}
if (arr)
{
free_list_int32_1_t_struct(arr);
}
erpc_free(arr);
return err;
}

View File

@ -1,52 +0,0 @@
/*
* Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_head_service_server_hpp_)
#define _head_service_server_hpp_
#include "head_service_interface.hpp"
#include "erpc_server.hpp"
#include "erpc_codec.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
namespace erpcShim
{
/*!
* @brief Service subclass for demo.
*/
class demo_service : public erpc::Service
{
public:
demo_service(demo_interface *_demo_interface);
virtual ~demo_service();
/*! @brief return service interface handler. */
demo_interface* getHandler(void);
/*! @brief Call the correct server shim based on method unique ID. */
virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport);
private:
demo_interface *m_handler;
/*! @brief Server shim for add of demo interface. */
erpc_status_t add_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for sum_i32 of demo interface. */
erpc_status_t sum_i32_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
};
} // erpcShim
#endif // _head_service_server_hpp_

View File

@ -1,4 +0,0 @@
interface demo {
add(int32 a, int32 b) -> int32;
sum_i32(list<int32> arr) -> int64;
};

View File

@ -7,18 +7,28 @@
#include <stdint.h>
#include "erpc/proto/generated/head_service_interface.hpp"
#include "erpc/proto/generated/face_servo_server.hpp"
#include "servo_manager/include/servo_manager.h"
extern "C" {
#include <rtthread.h>
}
class HeadServiceImpl : public erpcShim::demo_interface
class FaceServoServiceImpl : public erpcShim::FaceServo_interface
{
public:
HeadServiceImpl() = default;
virtual ~HeadServiceImpl() = default;
FaceServoServiceImpl();
virtual ~FaceServoServiceImpl() = default;
int32_t setAllAngles(const list_float_1_t* angles_deg) override;
int32_t setAngle(const char* id, float angle_deg) override;
int32_t setAngles(const list_ServoCmd_1_t* cmds) override;
private:
ServoManager _servos;
rt_err_t _init_err;
static const std::vector<ServoManager::ServoConfig> kServoCfg;
// 实现你 .erpc 里定义的方法(这里只举例 add
int32_t add(int32_t a, int32_t b) override;
int64_t sum_i32(const list_int32_1_t* arr) override;
};

View File

@ -13,20 +13,12 @@
#include "erpc_usb_cdc_transport.hpp"
#include "erpc/proto/generated/head_service_server.hpp"
#include "erpc/proto/generated/head_service_interface.hpp"
#include "erpc/proto/generated/face_servo_server.hpp"
#include "erpc/proto/generated/face_servo_interface.hpp"
#include "erpc/service/include/head_service_impl.h"
#include "erpc/common/include/erpc_error_handler.h"
// ====== 参数 ======
#ifndef ERPC_SERVER_UART_NAME
#define ERPC_SERVER_UART_NAME "uart2"
#endif
#ifndef ERPC_UART_BAUD
#define ERPC_UART_BAUD (921600 )
#endif
#ifndef ERPC_THREAD_STACK
#define ERPC_THREAD_STACK (4096)
@ -43,11 +35,6 @@
static void erpc_server_entry(void *parameter)
{
(void)parameter;
// rt_kprintf("CPACR=%08lx\n", SCB->CPACR);
rt_kprintf("[erpc] server init on %s, %d\r\n", ERPC_SERVER_UART_NAME, ERPC_UART_BAUD);
// 1) transport
static serial_port_usb_cdc_config_t cfg = {
.dev_name = "cdc0",
@ -80,9 +67,9 @@ static void erpc_server_entry(void *parameter)
return;
}
// 4) register service(你生成的是 demo_service + demo_interface
static HeadServiceImpl impl; // 必须继承 erpcShim::demo_interface
static erpcShim::demo_service service(&impl); // 生成的 service wrapper
// 4) register service
static FaceServoServiceImpl impl; // 必须继承 erpcShim::demo_interface
static erpcShim::FaceServo_service service(&impl); // 生成的 service wrapper
erpc_add_service_to_server(server, &service);

View File

@ -2,26 +2,128 @@
// Created by Administrator on 2025/12/24.
//
#include "../include/head_service_impl.h"
#include "erpc/service/include/head_service_impl.h"
#include <rtthread.h>
int32_t HeadServiceImpl::add(int32_t a, int32_t b)
const std::vector<ServoManager::ServoConfig> FaceServoServiceImpl::kServoCfg = {
{"eye_l_up", "pwm1", 1, 20000000, 500000, 2500000, -90.f, 90.f, 0.f},
// {"eye_r_up", "pwm1", 2, 20000000, 500000, 2500000, 0.f, 180.f, 90.f},
// ...
};
FaceServoServiceImpl::FaceServoServiceImpl()
: _servos(kServoCfg), _init_err(RT_EOK)
{
return a + b;
// rt_tick_t now = rt_tick_get();
// rt_uint32_t ms = (rt_uint32_t)((rt_uint64_t)now * 1000 / RT_TICK_PER_SECOND);
// rt_kprintf("[%lu ms] [erpc service] add(%ld,%ld)=%ld\r\n",
// (unsigned long)ms, (long)a, (long)b, (long)r);
// return r;
_init_err = _servos.init(true, true); // enable=true, go_home=true
if (_init_err != RT_EOK)
{
rt_kprintf("[FaceServo][E] init FAILED, err=%d\n", (int)_init_err);
}
}
int64_t HeadServiceImpl::sum_i32(const list_int32_1_t* arr)
int32_t FaceServoServiceImpl::setAllAngles(const list_float_1_t* angles_deg)
{
int64_t sum = 0;
for (int i = 0; i < arr->elementsCount; ++i)
// rt_kprintf("-");
if (_init_err != RT_EOK)
{
sum+= arr->elements[i];
rt_kprintf("[FaceServo][E] setAllAngles: service not ready, init_err=%d\n", (int)_init_err);
return _init_err;
}
return sum;
if (!angles_deg)
{
rt_kprintf("[FaceServo][E] setAllAngles: angles_deg is null\n");
return -RT_EINVAL;
}
if (!angles_deg->elements || angles_deg->elementsCount == 0)
{
rt_kprintf("[FaceServo][E] setAllAngles: empty list (elements=%p, count=%d)\n",
angles_deg->elements, (int)angles_deg->elementsCount);
return -RT_EINVAL;
}
const size_t need = _servos.count();
const size_t got = (size_t)angles_deg->elementsCount;
// 实际使用数量:谁小用谁
const size_t n = (got < need) ? got : need;
rt_err_t err = _servos.setAllAngles(angles_deg->elements, n);
if (err != RT_EOK)
{
rt_kprintf("[FaceServo][E] setAllAngles: ServoManager err=%d\n", (int)err);
return err;
}
return RT_EOK;
}
int32_t FaceServoServiceImpl::setAngle(const char* id, float angle_deg)
{
if (_init_err != RT_EOK)
{
rt_kprintf("[FaceServo][E] setAngle: service not ready, init_err=%d\n", (int)_init_err);
return _init_err;
}
if (!id)
{
rt_kprintf("[FaceServo][E] setAngle: id is null\n");
return -RT_EINVAL;
}
rt_err_t err = _servos.setAngle(id, angle_deg);
if (err != RT_EOK)
{
rt_kprintf("[FaceServo][E] setAngle: id=%s angle=%.2f err=%d\n",
id, (double)angle_deg, (int)err);
return err;
}
return RT_EOK;
}
int32_t FaceServoServiceImpl::setAngles(const list_ServoCmd_1_t* cmds)
{
if (_init_err != RT_EOK)
{
rt_kprintf("[FaceServo][E] setAngles: service not ready, init_err=%d\n", (int)_init_err);
return _init_err;
}
if (!cmds)
{
rt_kprintf("[FaceServo][E] setAngles: cmds is null\n");
return -RT_EINVAL;
}
if (!cmds->elements || cmds->elementsCount == 0)
{
rt_kprintf("[FaceServo][E] setAngles: empty list (elements=%p, count=%d)\n",
cmds->elements, (int)cmds->elementsCount);
return -RT_EINVAL;
}
for (uint32_t i = 0; i < cmds->elementsCount; ++i)
{
const char* id = cmds->elements[i].id;
const float angle = cmds->elements[i].angle_deg;
if (!id)
{
rt_kprintf("[FaceServo][E] setAngles: cmds[%d].id is null\n", (int)i);
return -RT_EINVAL;
}
rt_err_t err = _servos.setAngle(id, angle);
if (err != RT_EOK)
{
rt_kprintf("[FaceServo][E] setAngles: fail i=%d id=%s angle=%.2f err=%d\n",
(int)i, id, (double)angle, (int)err);
return err;
}
}
return RT_EOK;
}

View File

@ -19,9 +19,8 @@
int main(void)
{
int count = 1;
/* set LED0 pin mode to output */
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(GET_PIN(D, 0), PIN_MODE_OUTPUT);
while (count++)
@ -39,4 +38,3 @@ int main(void)

View File

@ -1,83 +0,0 @@
// #include <rtthread.h>
// #include <rtdevice.h>
// #include <board.h>
//
// #define PWM_DEV_NAME "pwm1"
// #define PWM_DEV_CHANNEL 1
//
// /* 常见舵机刷新周期 20ms (50Hz) */
// #define SERVO_PERIOD_NS 20000000UL
//
// /* 你的规格:脉宽限幅 */
// #define SERVO_MIN_US 800
// #define SERVO_MAX_US 2200
//
// /* 你的标定点:-50/0/+50 -> 1000/1500/2000 */
// #define SERVO_CENTER_US 1500
// #define SERVO_US_PER_DEG 10 /* 1° 对应 10us */
//
// static struct rt_device_pwm *pwm_dev = RT_NULL;
//
// static int clamp_int(int v, int lo, int hi)
// {
// if (v < lo) return lo;
// if (v > hi) return hi;
// return v;
// }
//
// /* 角度(°) -> 脉宽(us),按你的三点标定线性换算,并做 800~2200us 限幅 */
// static int angle_to_pulse_us(int angle_deg)
// {
// int pulse = SERVO_CENTER_US + angle_deg * SERVO_US_PER_DEG;
// return clamp_int(pulse, SERVO_MIN_US, SERVO_MAX_US);
// }
//
// /* 设置角度(单位:度),例如 -50 / 0 / +50 */
// static void servo_set_angle(int angle_deg)
// {
// int pulse_us = angle_to_pulse_us(angle_deg);
// rt_uint32_t pulse_ns = (rt_uint32_t)pulse_us * 1000UL; /* us -> ns */
// rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, SERVO_PERIOD_NS, pulse_ns);
// }
//
// static void servo_thread_entry(void *parameter)
// {
// while (1)
// {
// servo_set_angle(50);
// rt_thread_mdelay(1500);
// servo_set_angle(-50);
// rt_thread_mdelay(1500);
//
// }
// }
//
// static int servo_app_init(void)
// {
// pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
// if (pwm_dev == RT_NULL)
// {
// rt_kprintf("can't find %s\n", PWM_DEV_NAME);
// return -RT_ERROR;
// }
//
// /* 中位 0° -> 1500us */
// rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, SERVO_PERIOD_NS, (rt_uint32_t)SERVO_CENTER_US * 1000UL);
// rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
//
// rt_thread_t tid = rt_thread_create("servo",
// servo_thread_entry,
// RT_NULL,
// 1024,
// 20,
// 10);
// if (tid == RT_NULL)
// {
// rt_kprintf("create servo thread failed\n");
// return -RT_ERROR;
// }
// rt_thread_startup(tid);
//
// return RT_EOK;
// }
// INIT_APP_EXPORT(servo_app_init);

View File

@ -0,0 +1,10 @@
from building import *
import os
cwd = GetCurrentDir()
src = Glob('src/*.cpp')
CPPPATH = [cwd]
group = DefineGroup('servo_manager', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,83 @@
//
// Created by Administrator on 2026/1/7.
//
#ifndef SERVO_MANAGER_H
#define SERVO_MANAGER_H
extern "C" {
#include <rtthread.h>
#include <rtdevice.h>
}
#include <stdint.h>
#include <stddef.h>
#include <vector>
class ServoManager
{
public:
struct ServoConfig
{
const char* servo_id; // 唯一ID
const char* pwm_dev_name;
int pwm_channel;
// ns
rt_uint32_t period_ns;
rt_uint32_t min_pulse_ns;
rt_uint32_t max_pulse_ns;
float min_angle_deg;
float max_angle_deg;
float home_angle_deg;
};
struct ServoCmd
{
const char* id;
float angle_deg;
};
public:
explicit ServoManager(const std::vector<ServoConfig> &cfg);
~ServoManager();
size_t count() const { return _cfg.size(); }
rt_err_t init(bool enable_after_init = true, bool go_home = true);
rt_err_t enable(const char* servo_id, bool on);
rt_err_t setAngle(const char* servo_id, float angle_deg);
// 全部设置两种形态vector / 指针)
rt_err_t setAllAngles(const std::vector<float>& angles_deg);
rt_err_t setAllAngles(const float* angles_deg, size_t n);
// 批量设置两种形态vector / 指针)
rt_err_t setAngles(const std::vector<ServoCmd>& cmds);
rt_err_t setAngles(const ServoCmd* cmds, size_t n);
const char* idAt(size_t order) const;
int orderOf(const char* servo_id) const;
private:
rt_err_t enableNoLock(size_t order, bool on);
rt_err_t setAngleNoLock(size_t order, float angle_deg);
int findOrderByIdNoLock(const char* servo_id) const;
static float clampf(float v, float lo, float hi);
static rt_uint32_t angleToPulseNs(const ServoConfig& c, float angle_deg);
private:
std::vector<ServoConfig> _cfg;
std::vector<rt_device_pwm*> _pwm_dev;
std::vector<rt_uint32_t> _last_pulse;
rt_mutex_t _mutex;
};
#endif // SERVO_MANAGER_H

View File

@ -0,0 +1,283 @@
//
// Created by Administrator on 2026/1/7.
//
#include "servo_manager/include/servo_manager.h"
ServoManager::ServoManager(const std::vector<ServoConfig> &cfg)
: _cfg(std::move(cfg)),
_pwm_dev(_cfg.size(), RT_NULL),
_last_pulse(_cfg.size(), 0),
_mutex(RT_NULL)
{
_mutex = rt_mutex_create("sv_mtx", RT_IPC_FLAG_PRIO);
}
ServoManager::~ServoManager()
{
if (_mutex)
{
rt_mutex_delete(_mutex);
_mutex = RT_NULL;
}
}
rt_err_t ServoManager::init(bool enable_after_init, bool go_home)
{
if (_cfg.empty())
{
rt_kprintf("[ServoManager][E] init: empty cfg\n");
return -RT_EINVAL;
}
if (!_mutex)
{
rt_kprintf("[ServoManager][E] init: mutex not created\n");
return -RT_ENOMEM;
}
rt_mutex_take(_mutex, RT_WAITING_FOREVER);
for (size_t i = 0; i < _cfg.size(); ++i)
{
const auto& c = _cfg[i];
rt_device_pwm* dev = (rt_device_pwm*)rt_device_find(c.pwm_dev_name);
if (!dev)
{
rt_kprintf("[ServoManager][E] init: rt_device_find failed, i=%d id=%s pwm=%s ch=%d\n",
(int)i, c.servo_id ? c.servo_id : "null", c.pwm_dev_name ? c.pwm_dev_name : "null", c.pwm_channel);
rt_mutex_release(_mutex);
return -RT_ENOSYS;
}
_pwm_dev[i] = dev;
const float init_angle = go_home ? c.home_angle_deg : c.min_angle_deg;
const rt_uint32_t pulse = angleToPulseNs(c, init_angle);
rt_err_t err = rt_pwm_set(_pwm_dev[i], c.pwm_channel, c.period_ns, pulse);
if (err != RT_EOK)
{
rt_kprintf("[ServoManager][E] init: rt_pwm_set failed, i=%d id=%s pwm=%s ch=%d period=%u pulse=%u err=%d\n",
(int)i, c.servo_id ? c.servo_id : "null", c.pwm_dev_name ? c.pwm_dev_name : "null",
c.pwm_channel, (unsigned)c.period_ns, (unsigned)pulse, (int)err);
rt_mutex_release(_mutex);
return err;
}
_last_pulse[i] = pulse;
if (enable_after_init)
{
err = rt_pwm_enable(_pwm_dev[i], c.pwm_channel);
if (err != RT_EOK)
{
rt_kprintf("[ServoManager][E] init: rt_pwm_enable failed, i=%d id=%s pwm=%s ch=%d err=%d\n",
(int)i, c.servo_id ? c.servo_id : "null", c.pwm_dev_name ? c.pwm_dev_name : "null",
c.pwm_channel, (int)err);
rt_mutex_release(_mutex);
return err;
}
}
rt_kprintf("[ServoManager] init OK: i=%d id=%s pwm=%s ch=%d\n", (int)i, c.servo_id, c.pwm_dev_name, c.pwm_channel);
}
rt_mutex_release(_mutex);
//
rt_kprintf("[ServoManager] init OK: count=%d enable=%d go_home=%d\n",
(int)_cfg.size(), (int)enable_after_init, (int)go_home);
return RT_EOK;
}
rt_err_t ServoManager::enable(const char* servo_id, bool on)
{
if (!servo_id) return -RT_EINVAL;
if (!_mutex) return -RT_ENOMEM;
rt_mutex_take(_mutex, RT_WAITING_FOREVER);
int order = findOrderByIdNoLock(servo_id);
if (order < 0)
{
rt_mutex_release(_mutex);
return -RT_ENOSYS;
}
rt_err_t err = enableNoLock((size_t)order, on);
rt_mutex_release(_mutex);
return err;
}
rt_err_t ServoManager::setAngle(const char* servo_id, float angle_deg)
{
if (!servo_id) return -RT_EINVAL;
if (!_mutex) return -RT_ENOMEM;
rt_mutex_take(_mutex, RT_WAITING_FOREVER);
int order = findOrderByIdNoLock(servo_id);
if (order < 0)
{
rt_mutex_release(_mutex);
return -RT_ENOSYS;
}
rt_err_t err = setAngleNoLock((size_t)order, angle_deg);
rt_mutex_release(_mutex);
return err;
}
rt_err_t ServoManager::setAllAngles(const std::vector<float>& angles_deg)
{
if (angles_deg.size() < _cfg.size()) return -RT_EINVAL;
return setAllAngles(angles_deg.data(), angles_deg.size());
}
rt_err_t ServoManager::setAllAngles(const float* angles_deg, size_t n)
{
if (!angles_deg || n < _cfg.size()) return -RT_EINVAL;
if (!_mutex) return -RT_ENOMEM;
rt_mutex_take(_mutex, RT_WAITING_FOREVER);
for (size_t i = 0; i < _cfg.size(); ++i)
{
rt_err_t err = setAngleNoLock(i, angles_deg[i]);
if (err != RT_EOK)
{
rt_mutex_release(_mutex);
return err;
}
}
rt_mutex_release(_mutex);
return RT_EOK;
}
rt_err_t ServoManager::setAngles(const std::vector<ServoCmd>& cmds)
{
if (cmds.empty()) return -RT_EINVAL;
return setAngles(cmds.data(), cmds.size());
}
rt_err_t ServoManager::setAngles(const ServoCmd* cmds, size_t n)
{
if (!cmds || n == 0) return -RT_EINVAL;
if (!_mutex) return -RT_ENOMEM;
rt_mutex_take(_mutex, RT_WAITING_FOREVER);
for (size_t i = 0; i < n; ++i)
{
if (!cmds[i].id)
{
rt_mutex_release(_mutex);
return -RT_EINVAL;
}
int order = findOrderByIdNoLock(cmds[i].id);
if (order < 0)
{
rt_mutex_release(_mutex);
return -RT_ENOSYS;
}
rt_err_t err = setAngleNoLock((size_t)order, cmds[i].angle_deg);
if (err != RT_EOK)
{
rt_mutex_release(_mutex);
return err;
}
}
rt_mutex_release(_mutex);
return RT_EOK;
}
const char* ServoManager::idAt(size_t order) const
{
if (order >= _cfg.size()) return RT_NULL;
return _cfg[order].servo_id;
}
int ServoManager::orderOf(const char* servo_id) const
{
if (!servo_id) return -1;
for (size_t i = 0; i < _cfg.size(); ++i)
{
const char* sid = _cfg[i].servo_id;
if (sid && (rt_strcmp(sid, servo_id) == 0)) return (int)i;
}
return -1;
}
// ---------- private ----------
rt_err_t ServoManager::enableNoLock(size_t order, bool on)
{
if (order >= _cfg.size()) return -RT_EINVAL;
if (!_pwm_dev[order]) return -RT_ERROR;
return on ? rt_pwm_enable(_pwm_dev[order], _cfg[order].pwm_channel)
: rt_pwm_disable(_pwm_dev[order], _cfg[order].pwm_channel);
}
rt_err_t ServoManager::setAngleNoLock(size_t order, float angle_deg)
{
if (order >= _cfg.size()) return -RT_EINVAL;
if (!_pwm_dev[order]) return -RT_ERROR;
const rt_uint32_t pulse = angleToPulseNs(_cfg[order], angle_deg);
if (pulse != _last_pulse[order])
{
rt_err_t err = rt_pwm_set(_pwm_dev[order], _cfg[order].pwm_channel, _cfg[order].period_ns, pulse);
if (err != RT_EOK) return err;
_last_pulse[order] = pulse;
}
return RT_EOK;
}
int ServoManager::findOrderByIdNoLock(const char* servo_id) const
{
for (size_t i = 0; i < _cfg.size(); ++i)
{
const char* sid = _cfg[i].servo_id;
if (sid && (rt_strcmp(sid, servo_id) == 0))
return (int)i;
}
return -1;
}
float ServoManager::clampf(float v, float lo, float hi)
{
if (v < lo) return lo;
if (v > hi) return hi;
return v;
}
rt_uint32_t ServoManager::angleToPulseNs(const ServoConfig& c, float angle_deg)
{
const float a = clampf(angle_deg, c.min_angle_deg, c.max_angle_deg);
const float in_span = (c.max_angle_deg - c.min_angle_deg);
const float out_span = (float)(c.max_pulse_ns - c.min_pulse_ns);
float t = 0.0f;
if (in_span > 1e-6f)
t = (a - c.min_angle_deg) / in_span;
float pulse = (float)c.min_pulse_ns + t * out_span;
if (pulse < (float)c.min_pulse_ns) pulse = (float)c.min_pulse_ns;
if (pulse > (float)c.max_pulse_ns) pulse = (float)c.max_pulse_ns;
return (rt_uint32_t)(pulse + 0.5f);
}

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,13 @@
#MicroXplorer Configuration settings - do not modify
ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_5
ADC1.IPParameters=Rank-1\#ChannelRegularConversion,master,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,OffsetSignedSaturation-1\#ChannelRegularConversion,NbrOfConversionFlag,Resolution
ADC1.NbrOfConversionFlag=1
ADC1.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.OffsetSignedSaturation-1\#ChannelRegularConversion=DISABLE
ADC1.Rank-1\#ChannelRegularConversion=1
ADC1.Resolution=ADC_RESOLUTION_16B
ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_1CYCLE_5
ADC1.master=1
CAD.formats=
CAD.pinconfig=
CAD.provider=
@ -12,19 +21,21 @@ MMTConfigApplied=false
MMTSectionSuffix=
Mcu.CPN=STM32H750XBH6
Mcu.Family=STM32H7
Mcu.IP0=CORTEX_M7
Mcu.IP1=DEBUG
Mcu.IP10=USB_DEVICE
Mcu.IP11=USB_OTG_FS
Mcu.IP2=MEMORYMAP
Mcu.IP3=NVIC
Mcu.IP4=QUADSPI
Mcu.IP5=RCC
Mcu.IP6=SYS
Mcu.IP7=USART1
Mcu.IP8=USART2
Mcu.IP9=USART3
Mcu.IPNb=12
Mcu.IP0=ADC1
Mcu.IP1=CORTEX_M7
Mcu.IP10=USART2
Mcu.IP11=USART3
Mcu.IP12=USB_DEVICE
Mcu.IP13=USB_OTG_FS
Mcu.IP2=DEBUG
Mcu.IP3=MEMORYMAP
Mcu.IP4=NVIC
Mcu.IP5=QUADSPI
Mcu.IP6=RCC
Mcu.IP7=SYS
Mcu.IP8=TIM1
Mcu.IP9=USART1
Mcu.IPNb=14
Mcu.Name=STM32H750XBHx
Mcu.Package=TFBGA240
Mcu.Pin0=PD5
@ -37,12 +48,14 @@ Mcu.Pin14=PF8
Mcu.Pin15=PF10
Mcu.Pin16=PF9
Mcu.Pin17=PE9
Mcu.Pin18=PD9
Mcu.Pin19=PD8
Mcu.Pin18=PB1
Mcu.Pin19=PD9
Mcu.Pin2=PA14 (JTCK/SWCLK)
Mcu.Pin20=VP_SYS_VS_Systick
Mcu.Pin21=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
Mcu.Pin22=VP_MEMORYMAP_VS_MEMORYMAP
Mcu.Pin20=PD8
Mcu.Pin21=VP_SYS_VS_Systick
Mcu.Pin22=VP_TIM1_VS_ClockSourceINT
Mcu.Pin23=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
Mcu.Pin24=VP_MEMORYMAP_VS_MEMORYMAP
Mcu.Pin3=PC15-OSC32_OUT (OSC32_OUT)
Mcu.Pin4=PC14-OSC32_IN (OSC32_IN)
Mcu.Pin5=PA13 (JTMS/SWDIO)
@ -50,7 +63,7 @@ Mcu.Pin6=PA10
Mcu.Pin7=PA9
Mcu.Pin8=PA12
Mcu.Pin9=PA11
Mcu.PinsNb=23
Mcu.PinsNb=25
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32H750XBHx
@ -88,6 +101,7 @@ PA14\ (JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK
PA9.Locked=true
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB1.Signal=ADCx_INP5
PC14-OSC32_IN\ (OSC32_IN).Mode=LSE-External-Oscillator
PC14-OSC32_IN\ (OSC32_IN).Signal=RCC_OSC32_IN
PC15-OSC32_OUT\ (OSC32_OUT).Mode=LSE-External-Oscillator
@ -155,14 +169,14 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true,5-MX_USART3_UART_Init-USART3-false-HAL-true,6-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true,5-MX_USART3_UART_Init-USART3-false-HAL-true,6-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,7-MX_QUADSPI_Init-QUADSPI-false-HAL-true,8-MX_TIM1_Init-TIM1-false-HAL-true,9-MX_ADC1_Init-ADC1-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
QUADSPI.ChipSelectHighTime=QSPI_CS_HIGH_TIME_5_CYCLE
QUADSPI.ClockPrescaler=5
QUADSPI.FifoThreshold=4
QUADSPI.FlashSize=22
QUADSPI.IPParameters=ClockPrescaler,FifoThreshold,SampleShifting,FlashSize,ChipSelectHighTime
QUADSPI.SampleShifting=QSPI_SAMPLE_SHIFTING_HALFCYCLE
RCC.ADCFreq_Value=50390625
RCC.ADCFreq_Value=75000000
RCC.AHB12Freq_Value=240000000
RCC.AHB4Freq_Value=240000000
RCC.APB1Freq_Value=120000000
@ -182,16 +196,18 @@ RCC.D3PPRE=RCC_APB4_DIV2
RCC.DFSDMACLkFreq_Value=48000000
RCC.DFSDMFreq_Value=120000000
RCC.DIVM1=5
RCC.DIVM2=2
RCC.DIVN1=192
RCC.DIVN2=12
RCC.DIVP1Freq_Value=480000000
RCC.DIVP2Freq_Value=50390625
RCC.DIVP2Freq_Value=75000000
RCC.DIVP3Freq_Value=50390625
RCC.DIVQ1=20
RCC.DIVQ1Freq_Value=48000000
RCC.DIVQ2Freq_Value=50390625
RCC.DIVQ2Freq_Value=75000000
RCC.DIVQ3Freq_Value=50390625
RCC.DIVR1Freq_Value=480000000
RCC.DIVR2Freq_Value=50390625
RCC.DIVR2Freq_Value=75000000
RCC.DIVR3Freq_Value=50390625
RCC.FDCANFreq_Value=48000000
RCC.FMCFreq_Value=240000000
@ -202,7 +218,7 @@ RCC.HPRE=RCC_HCLK_DIV2
RCC.HRTIMFreq_Value=240000000
RCC.I2C123Freq_Value=120000000
RCC.I2C4Freq_Value=120000000
RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVN1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVN1,DIVN2,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
RCC.LPTIM1Freq_Value=120000000
RCC.LPTIM2Freq_Value=120000000
RCC.LPTIM345Freq_Value=120000000
@ -237,13 +253,17 @@ RCC.USART16Freq_Value=120000000
RCC.USART234578Freq_Value=120000000
RCC.USBFreq_Value=48000000
RCC.VCO1OutputFreq_Value=960000000
RCC.VCO2OutputFreq_Value=100781250
RCC.VCO2OutputFreq_Value=150000000
RCC.VCO3OutputFreq_Value=100781250
RCC.VCOInput1Freq_Value=5000000
RCC.VCOInput2Freq_Value=781250
RCC.VCOInput2Freq_Value=12500000
RCC.VCOInput3Freq_Value=781250
SH.S_TIM1_CH1.0=TIM1_CH1
SH.ADCx_INP5.0=ADC1_INP5,IN5-Single-Ended
SH.ADCx_INP5.ConfNb=1
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
SH.S_TIM1_CH1.ConfNb=1
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM1.IPParameters=Channel-PWM Generation1 CH1
USART1.IPParameters=VirtualMode-Asynchronous
USART1.VirtualMode-Asynchronous=VM_ASYNC
USART2.IPParameters=VirtualMode-Asynchronous
@ -261,6 +281,8 @@ VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg
VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM1_VS_ClockSourceINT.Mode=Internal
VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS
board=custom

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -49,6 +49,8 @@ extern "C" {
/* USER CODE END EM */
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);

View File

@ -34,7 +34,7 @@
*/
#define HAL_MODULE_ENABLED
/* #define HAL_ADC_MODULE_ENABLED */
#define HAL_ADC_MODULE_ENABLED
/* #define HAL_FDCAN_MODULE_ENABLED */
/* #define HAL_FMAC_MODULE_ENABLED */
/* #define HAL_CEC_MODULE_ENABLED */
@ -74,7 +74,7 @@
/* #define HAL_SPDIFRX_MODULE_ENABLED */
/* #define HAL_SPI_MODULE_ENABLED */
/* #define HAL_SWPMI_MODULE_ENABLED */
/* #define HAL_TIM_MODULE_ENABLED */
#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */

View File

@ -41,9 +41,12 @@
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
QSPI_HandleTypeDef hqspi;
TIM_HandleTypeDef htim1;
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3;
@ -60,6 +63,8 @@ static void MX_USART1_UART_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_QUADSPI_Init(void);
static void MX_TIM1_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
@ -106,6 +111,8 @@ int main(void)
MX_USART3_UART_Init();
MX_USB_DEVICE_Init();
MX_QUADSPI_Init();
MX_TIM1_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
@ -179,6 +186,75 @@ void SystemClock_Config(void)
}
}
/**
* @brief ADC1 Initialization Function
* @param None
* @retval None
*/
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_16B;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.Oversampling.Ratio = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
/**
* @brief QUADSPI Initialization Function
* @param None
@ -214,6 +290,86 @@ static void MX_QUADSPI_Init(void)
}
/**
* @brief TIM1 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM1_Init(void)
{
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
sBreakDeadTimeConfig.Break2Filter = 0;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */
/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);
}
/**
* @brief USART1 Initialization Function
* @param None
@ -365,7 +521,6 @@ static void MX_USART3_UART_Init(void)
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
@ -378,14 +533,7 @@ static void MX_GPIO_Init(void)
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/*Configure GPIO pin : PE9 */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
__HAL_RCC_GPIOB_CLK_ENABLE();
/* USER CODE BEGIN MX_GPIO_Init_2 */

View File

@ -57,7 +57,9 @@
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
@ -76,6 +78,87 @@ void HAL_MspInit(void)
/* USER CODE END MspInit 1 */
}
/**
* @brief ADC MSP Initialization
* This function configures the hardware resources used in this example
* @param hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(hadc->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInitStruct.PLL2.PLL2M = 2;
PeriphClkInitStruct.PLL2.PLL2N = 12;
PeriphClkInitStruct.PLL2.PLL2P = 2;
PeriphClkInitStruct.PLL2.PLL2Q = 2;
PeriphClkInitStruct.PLL2.PLL2R = 2;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOMEDIUM;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_ADC12_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**ADC1 GPIO Configuration
PB1 ------> ADC1_INP5
*/
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
}
/**
* @brief ADC MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspDeInit 0 */
/* USER CODE END ADC1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ADC12_CLK_DISABLE();
/**ADC1 GPIO Configuration
PB1 ------> ADC1_INP5
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_1);
/* USER CODE BEGIN ADC1_MspDeInit 1 */
/* USER CODE END ADC1_MspDeInit 1 */
}
}
/**
* @brief QSPI MSP Initialization
* This function configures the hardware resources used in this example
@ -176,6 +259,77 @@ void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi)
}
/**
* @brief TIM_Base MSP Initialization
* This function configures the hardware resources used in this example
* @param htim_base: TIM_Base handle pointer
* @retval None
*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspInit 0 */
/* USER CODE END TIM1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM1_CLK_ENABLE();
/* USER CODE BEGIN TIM1_MspInit 1 */
/* USER CODE END TIM1_MspInit 1 */
}
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(htim->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspPostInit 0 */
/* USER CODE END TIM1_MspPostInit 0 */
__HAL_RCC_GPIOE_CLK_ENABLE();
/**TIM1 GPIO Configuration
PE9 ------> TIM1_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* USER CODE BEGIN TIM1_MspPostInit 1 */
/* USER CODE END TIM1_MspPostInit 1 */
}
}
/**
* @brief TIM_Base MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param htim_base: TIM_Base handle pointer
* @retval None
*/
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspDeInit 0 */
/* USER CODE END TIM1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM1_CLK_DISABLE();
/* USER CODE BEGIN TIM1_MspDeInit 1 */
/* USER CODE END TIM1_MspDeInit 1 */
}
}
/**
* @brief UART MSP Initialization
* This function configures the hardware resources used in this example

View File

@ -56,6 +56,8 @@ set(STM32_Drivers_Src
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_delayblock.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c

View File

@ -201,6 +201,18 @@ menu "On-chip Peripheral Drivers"
select RT_USING_QSPI
select RT_USING_SPI
default n
menuconfig BSP_USING_ADC
bool "Enable ADC"
default n
select RT_USING_ADC
if BSP_USING_ADC
config BSP_USING_ADC1
bool "Enable ADC1 "
default n
endif
menuconfig BSP_USING_SPI
bool "Enable SPI BUS"
default n

View File

@ -125,4 +125,25 @@ static int ota_app_vtor_reconfig(void)
return 0;
}
INIT_BOARD_EXPORT(ota_app_vtor_reconfig);
INIT_BOARD_EXPORT(MPU_Config);
INIT_BOARD_EXPORT(MPU_Config);
// rt thread 的
// void __libc_init_array(void)
// {
// /* we not use __libc init_aray to initialize C++ objects */
// /* __libc_init_array is ARM code, not Thumb; it will cause a hardfault. */
// }
// 没有定义不能初始化C++ 的static 变量,故需要添加这个函数
typedef int (*init_func_t)(void);
extern init_func_t __preinit_array_start[];
extern init_func_t __preinit_array_end[];
extern init_func_t __init_array_start[];
extern init_func_t __init_array_end[];
int rt_cpp_init(void)
{
for (init_func_t *p = __preinit_array_start; p < __preinit_array_end; ++p) (*p)();
for (init_func_t *p = __init_array_start; p < __init_array_end; ++p) (*p)();
}
INIT_PLATFORM_EXPORT(rt_cpp_init);

View File

@ -7,6 +7,7 @@
/* rt_vsnprintf options */
#define RT_KLIBC_USING_LIBC_VSNPRINTF
/* end of rt_vsnprintf options */
/* rt_vsscanf options */
@ -144,6 +145,8 @@
#define RT_USING_SERIAL_V1
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_ADC
#define RT_USING_PWM
#define RT_USING_SPI
#define RT_USING_PIN
#define RT_USING_KTIME
@ -336,6 +339,10 @@
/* HPMicro SDK */
/* end of HPMicro SDK */
/* FT32 HAL & SDK Drivers */
/* end of FT32 HAL & SDK Drivers */
/* end of HAL & SDK Drivers */
/* sensors drivers */
@ -442,6 +449,11 @@
#define BSP_UART3_RX_USING_DMA
#define BSP_UART3_RX_BUFSIZE 1024
#define BSP_UART3_TX_BUFSIZE 512
#define BSP_USING_PWM
#define BSP_USING_PWM1
#define BSP_USING_PWM1_CH1
#define BSP_USING_ADC
#define BSP_USING_ADC1
/* end of On-chip Peripheral Drivers */
/* Board extended module Drivers */