feat: add config file transfer by erpc

This commit is contained in:
lgv 2026-04-28 16:48:03 +08:00
parent ab4c5fdaa0
commit 7813023069
35 changed files with 1622 additions and 73 deletions

View File

@ -659,6 +659,8 @@ CONFIG_RT_USING_CPP_EXCEPTIONS=y
# tools packages
#
# CONFIG_PKG_USING_VECTOR is not set
# CONFIG_PKG_USING_SORCH is not set
# CONFIG_PKG_USING_DICT is not set
# CONFIG_PKG_USING_CMBACKTRACE is not set
# CONFIG_PKG_USING_MCOREDUMP is not set
# CONFIG_PKG_USING_EASYFLASH is not set
@ -840,6 +842,8 @@ CONFIG_PKG_LITTLEFS_VER="latest"
# CONFIG_PKG_USING_HEARTBEAT is not set
# CONFIG_PKG_USING_MICRO_ROS_RTTHREAD_PACKAGE is not set
# CONFIG_PKG_USING_CHERRYECAT is not set
# CONFIG_PKG_USING_EVENT_LOOP is not set
# CONFIG_PKG_USING_THREAD_MANAGER is not set
# end of system packages
#

1
.idea/editor.xml generated
View File

@ -139,6 +139,7 @@
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOverrideWithDifferentVisibility/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexedValue" value="HINT" type="string" />

1
.idea/vcs.xml generated
View File

@ -2,6 +2,7 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/packages/ArduinoJson-latest" vcs="Git" />
<mapping directory="$PROJECT_DIR$/packages/CMSIS-Core-latest" vcs="Git" />
<mapping directory="$PROJECT_DIR$/packages/littlefs-latest" vcs="Git" />
<mapping directory="$PROJECT_DIR$/packages/stm32h7_cmsis_driver-latest" vcs="Git" />

View File

@ -112,11 +112,14 @@ ADD_DEFINITIONS(
# Library source files
SET(RT_APP_ERPC_SOURCES
applications/erpc/proto/generated/file_service_interface.cpp
applications/erpc/proto/generated/servo_service_server.cpp
applications/erpc/service/src/file_service_impl.cpp
applications/erpc/service/src/erpc_server_main.cpp
applications/erpc/proto/generated/file_service_server.cpp
applications/erpc/service/src/servo_service_impl.cpp
applications/erpc/proto/generated/servo_service_interface.cpp
applications/erpc/common/src/erpc_error_handler.cpp
applications/erpc/service/src/servo_service_impl.cpp
applications/erpc/proto/generated/servo_service_server.cpp
applications/erpc/service/src/erpc_server_main.cpp
)
SET(RT_APPLICATIONS_SOURCES
@ -124,13 +127,13 @@ SET(RT_APPLICATIONS_SOURCES
)
SET(RT_CHERRYUSB_SOURCES
rt-thread/components/drivers/usb/cherryusb/core/usbd_core.c
rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c
rt-thread/components/drivers/usb/cherryusb/class/msc/usbd_msc.c
rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c
rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_msh.c
rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c
rt-thread/components/drivers/usb/cherryusb/core/usbd_core.c
rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c
rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c
rt-thread/components/drivers/usb/cherryusb/class/msc/usbd_msc.c
rt-thread/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c
)
@ -199,30 +202,30 @@ SET(RT_DRIVERS_SOURCES
)
SET(RT_ERPC_SOURCES
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
packages/erpc-1.14.0/erpc_c/port/erpc_threading_pthreads.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_server.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/transports/erpc_usb_cdc_transport.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_transport_arbitrator.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_setup_mbf_dynamic.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_setup_usb_cdc.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_basic_codec.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_server_setup.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_message_buffer.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_framed_transport.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_pre_post_action.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_simple_server.cpp
packages/erpc-1.14.0/erpc_c/setup/erpc_setup_mbf_static.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_server.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_crc16.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_message_loggers.cpp
packages/erpc-1.14.0/erpc_c/port/erpc_threading_pthreads.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_mbf_static.cpp
packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_pre_post_action.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_message_buffer.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_basic_codec.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_framed_transport.cpp
packages/erpc-1.14.0/erpc_c/infra/erpc_crc16.cpp
)
SET(RT_FAL_SOURCES
rt-thread/components/fal/src/fal_partition.c
rt-thread/components/fal/src/fal.c
rt-thread/components/fal/src/fal_rtt.c
rt-thread/components/fal/src/fal_flash.c
rt-thread/components/fal/src/fal_partition.c
rt-thread/components/fal/src/fal_rtt.c
)
SET(RT_FILESYSTEM_SOURCES
@ -234,11 +237,11 @@ SET(RT_FILESYSTEM_SOURCES
)
SET(RT_FINSH_SOURCES
rt-thread/components/finsh/msh_file.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
rt-thread/components/finsh/msh_parse.c
rt-thread/components/finsh/shell.c
rt-thread/components/finsh/cmd.c
rt-thread/components/finsh/msh_file.c
)
SET(RT_KERNEL_SOURCES
@ -261,15 +264,15 @@ SET(RT_KERNEL_SOURCES
SET(RT_KLIBC_SOURCES
rt-thread/src/klibc/kstdio.c
rt-thread/src/klibc/kstring.c
rt-thread/src/klibc/rt_vsscanf.c
rt-thread/src/klibc/kstring.c
rt-thread/src/klibc/kerrno.c
)
SET(RT_KTIME_SOURCES
rt-thread/components/drivers/ktime/src/cputimer.c
rt-thread/components/drivers/ktime/src/boottime.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
@ -282,45 +285,45 @@ SET(RT_LIBCPU_SOURCES
)
SET(RT_LIBRARIES_SOURCES
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_lptim.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rng.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cryp.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_usart.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_nor.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_comp.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c
libraries/STM32H7xx_HAL/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc.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_flash.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cec.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sram.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c
libraries/STM32H7xx_HAL/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rng.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_nor.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_usart.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_lptim.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_comp.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cec.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cryp.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_adc_ex.c
libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c
)
SET(RT_LITTLEFS_SOURCES
packages/littlefs-latest/lfs.c
packages/littlefs-latest/dfs_lfs.c
packages/littlefs-latest/lfs_crc.c
packages/littlefs-latest/lfs_util.c
packages/littlefs-latest/lfs_crc.c
packages/littlefs-latest/dfs_lfs.c
packages/littlefs-latest/lfs.c
)
SET(RT_POSIX_SOURCES
@ -338,9 +341,9 @@ SET(RT_POSIX_SOURCES
)
SET(RT_SERVO_CONTROL_SOURCES
applications/servo_manager/src/servo_driver.cpp
applications/servo_manager/src/servo_manager.cpp
applications/servo_manager/src/servo_control.cpp
applications/servo_manager/src/servo_driver.cpp
)
SET(RT_UTC_UTEST_SOURCES

View File

@ -23,12 +23,18 @@ gen_dir = p('proto', 'generated')
# interface 建议始终编译(两端都可能需要)
src += [p('proto', 'generated', 'servo_service_interface.cpp')]
if os.path.exists(p('proto', 'generated', 'file_service_interface.cpp')):
src += [p('proto', 'generated', 'file_service_interface.cpp')]
src += [p('common', 'src', 'erpc_error_handler.cpp')]
if GetDepend(['ERPC_MODE_SERVER']):
src += [p('proto', 'generated', 'servo_service_server.cpp')]
if os.path.exists(p('proto', 'generated', 'file_service_server.cpp')):
src += [p('proto', 'generated', 'file_service_server.cpp')]
if GetDepend(['ERPC_MODE_CLIENT']):
src += [p('proto', 'generated', 'servo_service_client.cpp')]
if os.path.exists(p('proto', 'generated', 'file_service_client.cpp')):
src += [p('proto', 'generated', 'file_service_client.cpp')]
CPPPATH = [
cwd,

View File

@ -0,0 +1,39 @@
// file_service.erpc
program file_service
@id(2)
interface file_service
{
/**
* @brief 开始一次文件上传会话。
* @param path 目标文件路径;服务端会先写入 "<path>.part" 临时文件。
* @param total_size 本次上传的文件总字节数,用于服务端校验最终大小。
* @return RT_EOK 表示成功;负数表示 RT-Thread/POSIX 错误码。
*/
fileWriteBegin(string path, uint32 total_size) -> int32
/**
* @brief 写入一个文件分块。
* @param data 当前分块的二进制内容dataLength 是分块字节数data 是分块数据指针。
* @return RT_EOK 表示成功;负数表示 RT-Thread/POSIX 错误码。
*
* @note 单个分块会被封装进一次 eRPC 消息,最大可用长度受 ERPC_DEFAULT_BUFFER_SIZE 限制。
*/
fileWriteChunk(binary data) -> int32
/**
* @brief 完成上传会话。
* @return RT_EOK 表示成功;负数表示 RT-Thread/POSIX 错误码。
*
* @note 服务端会先校验已接收字节数是否等于 total_size然后把临时文件重命名为目标文件。
*/
fileWriteEnd() -> int32
/**
* @brief 取消当前上传会话。
* @return RT_EOK 表示成功;负数表示 RT-Thread/POSIX 错误码。
*
* @note 服务端会关闭当前文件并删除残留的 ".part" 临时文件。
*/
fileWriteAbort() -> int32
}

View File

@ -0,0 +1,77 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "c_file_service_client.h"
#include "file_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
file_service_client *s_file_service_client = nullptr;
#else
ERPC_MANUALLY_CONSTRUCTED_STATIC(file_service_client, s_file_service_client);
#endif
int32_t fileWriteBegin(const char * path, uint32_t total_size)
{
int32_t result;
result = s_file_service_client->fileWriteBegin(path, total_size);
return result;
}
int32_t fileWriteChunk(const binary_t * data)
{
int32_t result;
result = s_file_service_client->fileWriteChunk(data);
return result;
}
int32_t fileWriteEnd(void)
{
int32_t result;
result = s_file_service_client->fileWriteEnd();
return result;
}
int32_t fileWriteAbort(void)
{
int32_t result;
result = s_file_service_client->fileWriteAbort();
return result;
}
void initfile_service_client(erpc_client_t client)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
erpc_assert(s_file_service_client == nullptr);
s_file_service_client = new file_service_client(reinterpret_cast<ClientManager *>(client));
#else
erpc_assert(!s_file_service_client.isUsed());
s_file_service_client.construct(reinterpret_cast<ClientManager *>(client));
#endif
}
void deinitfile_service_client(void)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
if (s_file_service_client != nullptr)
{
delete s_file_service_client;
s_file_service_client = nullptr;
}
#else
s_file_service_client.destroy();
#endif
}

View File

@ -0,0 +1,54 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_c_file_service_client_h_)
#define _c_file_service_client_h_
#include "file_service_common.h"
#include "erpc_client_manager.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
#define ERPC_FUNCTIONS_DEFINITIONS
/*! @brief file_service identifiers */
enum _file_service_ids
{
kfile_service_service_id = 2,
kfile_service_fileWriteBegin_id = 1,
kfile_service_fileWriteChunk_id = 2,
kfile_service_fileWriteEnd_id = 3,
kfile_service_fileWriteAbort_id = 4,
};
//! @name file_service
//@{
int32_t fileWriteBegin(const char * path, uint32_t total_size);
int32_t fileWriteChunk(const binary_t * data);
int32_t fileWriteEnd(void);
int32_t fileWriteAbort(void);
//@}
#endif // ERPC_FUNCTIONS_DEFINITIONS
void initfile_service_client(erpc_client_t client);
void deinitfile_service_client(void);
#if defined(__cplusplus)
}
#endif
#endif // _c_file_service_client_h_

View File

@ -0,0 +1,97 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include <new>
#include "c_file_service_server.h"
#include "file_service_server.hpp"
#include "erpc_manually_constructed.hpp"
using namespace erpc;
using namespace std;
using namespace erpcShim;
class file_service_server: public file_service_interface
{
public:
virtual ~file_service_server() {};
int32_t fileWriteBegin(const char * path, uint32_t total_size)
{
int32_t result;
result = ::fileWriteBegin(path, total_size);
return result;
}
int32_t fileWriteChunk(const binary_t * data)
{
int32_t result;
result = ::fileWriteChunk(data);
return result;
}
int32_t fileWriteEnd(void)
{
int32_t result;
result = ::fileWriteEnd();
return result;
}
int32_t fileWriteAbort(void)
{
int32_t result;
result = ::fileWriteAbort();
return result;
}
};
ERPC_MANUALLY_CONSTRUCTED_STATIC(file_service_service, s_file_service_service);
ERPC_MANUALLY_CONSTRUCTED_STATIC(file_service_server, s_file_service_server);
erpc_service_t create_file_service_service(void)
{
erpc_service_t service;
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
service = new (nothrow) file_service_service(new (nothrow)file_service_server());
#else
if (s_file_service_service.isUsed())
{
service = NULL;
}
else
{
s_file_service_server.construct();
s_file_service_service.construct(s_file_service_server.get());
service = s_file_service_service.get();
}
#endif
return service;
}
void destroy_file_service_service(erpc_service_t service)
{
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
if (service)
{
delete (file_service_server *)(((file_service_service *)service)->getHandler());
delete (file_service_service *)service;
}
#else
(void)service;
erpc_assert(service == s_file_service_service.get());
s_file_service_service.destroy();
s_file_service_server.destroy();
#endif
}

View File

@ -0,0 +1,59 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_c_file_service_server_h_)
#define _c_file_service_server_h_
#include "file_service_common.h"
#if defined(__cplusplus)
extern "C"
{
#endif
typedef void * erpc_service_t;
#if !defined(ERPC_FUNCTIONS_DEFINITIONS)
#define ERPC_FUNCTIONS_DEFINITIONS
/*! @brief file_service identifiers */
enum _file_service_ids
{
kfile_service_service_id = 2,
kfile_service_fileWriteBegin_id = 1,
kfile_service_fileWriteChunk_id = 2,
kfile_service_fileWriteEnd_id = 3,
kfile_service_fileWriteAbort_id = 4,
};
//! @name file_service
//@{
int32_t fileWriteBegin(const char * path, uint32_t total_size);
int32_t fileWriteChunk(const binary_t * data);
int32_t fileWriteEnd(void);
int32_t fileWriteAbort(void);
//@}
#endif // ERPC_FUNCTIONS_DEFINITIONS
/*! @brief Return file_service_service service object. */
erpc_service_t create_file_service_service(void);
/*! @brief Destroy file_service_service service object. */
void destroy_file_service_service(erpc_service_t service);
#if defined(__cplusplus)
}
#endif
#endif // _c_file_service_server_h_

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -0,0 +1,302 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
#include "erpc_port.h"
#endif
#include "erpc_codec.hpp"
#include "file_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 binary_t
static void write_binary_t_struct(erpc::Codec * codec, const binary_t * data);
// Write struct binary_t function implementation
static void write_binary_t_struct(erpc::Codec * codec, const binary_t * data)
{
if(NULL == data)
{
return;
}
codec->writeBinary(data->dataLength, data->data);
}
file_service_client::file_service_client(ClientManager *manager)
:m_clientManager(manager)
{
}
file_service_client::~file_service_client()
{
}
// file_service interface fileWriteBegin function client shim.
int32_t file_service_client::fileWriteBegin(const char * path, uint32_t total_size)
{
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_fileWriteBeginId, request.getSequence());
{
uint32_t path_len = strlen((const char*)path);
codec->writeString(path_len, (const char*)path);
}
codec->write(total_size);
// 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_fileWriteBeginId);
#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;
}
// file_service interface fileWriteChunk function client shim.
int32_t file_service_client::fileWriteChunk(const binary_t * data)
{
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_fileWriteChunkId, request.getSequence());
write_binary_t_struct(codec, data);
// 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_fileWriteChunkId);
#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;
}
// file_service interface fileWriteEnd function client shim.
int32_t file_service_client::fileWriteEnd(void)
{
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_fileWriteEndId, request.getSequence());
// 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_fileWriteEndId);
#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;
}
// file_service interface fileWriteAbort function client shim.
int32_t file_service_client::fileWriteAbort(void)
{
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_fileWriteAbortId, request.getSequence());
// 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_fileWriteAbortId);
#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,40 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_file_service_client_hpp_)
#define _file_service_client_hpp_
#include "file_service_interface.hpp"
#include "erpc_client_manager.h"
namespace erpcShim
{
class file_service_client: public file_service_interface
{
public:
file_service_client(erpc::ClientManager *manager);
virtual ~file_service_client();
virtual int32_t fileWriteBegin(const char * path, uint32_t total_size);
virtual int32_t fileWriteChunk(const binary_t * data);
virtual int32_t fileWriteEnd(void);
virtual int32_t fileWriteAbort(void);
protected:
erpc::ClientManager *m_clientManager;
};
} // erpcShim
#endif // _file_service_client_hpp_

View File

@ -0,0 +1,47 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_file_service_common_h_)
#define _file_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_FILE_SERVICE)
#define ERPC_TYPE_DEFINITIONS_FILE_SERVICE
// Aliases data types declarations
typedef struct binary_t binary_t;
// Structures/unions data types declarations
struct binary_t
{
uint8_t * data;
uint32_t dataLength;
};
#endif // ERPC_TYPE_DEFINITIONS_FILE_SERVICE
#if defined(__cplusplus)
}
#endif
#endif // _file_service_common_h_

View File

@ -0,0 +1,39 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_file_service_common_hpp_)
#define _file_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_FILE_SERVICE)
#define ERPC_TYPE_DEFINITIONS_FILE_SERVICE
// Aliases data types declarations
typedef struct binary_t binary_t;
// Structures/unions data types declarations
struct binary_t
{
uint8_t * data;
uint32_t dataLength;
};
#endif // ERPC_TYPE_DEFINITIONS_FILE_SERVICE
#endif // _file_service_common_hpp_

View File

@ -0,0 +1,20 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "file_service_interface.hpp"
#if 11400 != ERPC_VERSION_NUMBER
#error "The generated shim code version is different to the rest of eRPC code."
#endif
using namespace std;
using namespace erpcShim;
file_service_interface::~file_service_interface(void)
{
}

View File

@ -0,0 +1,41 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_file_service_interface_hpp_)
#define _file_service_interface_hpp_
#include "file_service_common.hpp"
namespace erpcShim
{
// Abstract base class for file_service
class file_service_interface
{
public:
static const uint8_t m_serviceId = 2;
static const uint8_t m_fileWriteBeginId = 1;
static const uint8_t m_fileWriteChunkId = 2;
static const uint8_t m_fileWriteEndId = 3;
static const uint8_t m_fileWriteAbortId = 4;
virtual ~file_service_interface(void);
virtual int32_t fileWriteBegin(const char * path, uint32_t total_size) = 0;
virtual int32_t fileWriteChunk(const binary_t * data) = 0;
virtual int32_t fileWriteEnd(void) = 0;
virtual int32_t fileWriteAbort(void) = 0;
private:
};
} // erpcShim
#endif // _file_service_interface_hpp_

View File

@ -0,0 +1,327 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#include "file_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 binary_t
static void read_binary_t_struct(erpc::Codec * codec, binary_t * data);
// Read struct binary_t function implementation
static void read_binary_t_struct(erpc::Codec * codec, binary_t * data)
{
if(NULL == data)
{
return;
}
uint8_t * data_local;
codec->readBinary(data->dataLength, &data_local);
if (data->dataLength > 0)
{
data->data = (uint8_t *) erpc_malloc(data->dataLength * sizeof(uint8_t));
if (data->data == NULL)
{
codec->updateStatus(kErpcStatus_MemoryError);
}
else
{
memcpy(data->data, data_local, data->dataLength);
}
}
else
{
data->data = NULL;
}
}
//! @brief Function to free space allocated inside struct binary_t
static void free_binary_t_struct(binary_t * data);
// Free space allocated inside struct binary_t function implementation
static void free_binary_t_struct(binary_t * data)
{
erpc_free(data->data);
}
file_service_service::file_service_service(file_service_interface *_file_service_interface)
: erpc::Service(file_service_interface::m_serviceId)
, m_handler(_file_service_interface)
{
}
file_service_service::~file_service_service()
{
}
// return service interface handler.
file_service_interface* file_service_service::getHandler(void)
{
return m_handler;
}
// Call the correct server shim based on method unique ID.
erpc_status_t file_service_service::handleInvocation(uint32_t methodId, uint32_t sequence, Codec * codec, MessageBufferFactory *messageFactory, Transport * transport)
{
erpc_status_t erpcStatus;
switch (methodId)
{
case file_service_interface::m_fileWriteBeginId:
{
erpcStatus = fileWriteBegin_shim(codec, messageFactory, transport, sequence);
break;
}
case file_service_interface::m_fileWriteChunkId:
{
erpcStatus = fileWriteChunk_shim(codec, messageFactory, transport, sequence);
break;
}
case file_service_interface::m_fileWriteEndId:
{
erpcStatus = fileWriteEnd_shim(codec, messageFactory, transport, sequence);
break;
}
case file_service_interface::m_fileWriteAbortId:
{
erpcStatus = fileWriteAbort_shim(codec, messageFactory, transport, sequence);
break;
}
default:
{
erpcStatus = kErpcStatus_InvalidArgument;
break;
}
}
return erpcStatus;
}
// Server shim for fileWriteBegin of file_service interface.
erpc_status_t file_service_service::fileWriteBegin_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
char * path = NULL;
uint32_t total_size;
int32_t result;
// startReadMessage() was already called before this shim was invoked.
{
uint32_t path_len;
char * path_local;
codec->readString(path_len, &path_local);
path = (char*) erpc_malloc((path_len + 1) * sizeof(char));
if ((path == NULL) || (path_local == NULL))
{
codec->updateStatus(kErpcStatus_MemoryError);
}
else
{
memcpy(path, path_local, path_len);
(path)[path_len] = 0;
}
}
codec->read(total_size);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->fileWriteBegin(path, total_size);
#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, file_service_interface::m_serviceId, file_service_interface::m_fileWriteBeginId, sequence);
codec->write(result);
err = codec->getStatus();
}
erpc_free(path);
return err;
}
// Server shim for fileWriteChunk of file_service interface.
erpc_status_t file_service_service::fileWriteChunk_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
binary_t *data = NULL;
data = (binary_t *) erpc_malloc(sizeof(binary_t));
if (data == NULL)
{
codec->updateStatus(kErpcStatus_MemoryError);
}
int32_t result;
// startReadMessage() was already called before this shim was invoked.
read_binary_t_struct(codec, data);
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->fileWriteChunk(data);
#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, file_service_interface::m_serviceId, file_service_interface::m_fileWriteChunkId, sequence);
codec->write(result);
err = codec->getStatus();
}
if (data)
{
free_binary_t_struct(data);
}
erpc_free(data);
return err;
}
// Server shim for fileWriteEnd of file_service interface.
erpc_status_t file_service_service::fileWriteEnd_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
// startReadMessage() was already called before this shim was invoked.
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->fileWriteEnd();
#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, file_service_interface::m_serviceId, file_service_interface::m_fileWriteEndId, sequence);
codec->write(result);
err = codec->getStatus();
}
return err;
}
// Server shim for fileWriteAbort of file_service interface.
erpc_status_t file_service_service::fileWriteAbort_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence)
{
erpc_status_t err = kErpcStatus_Success;
int32_t result;
// startReadMessage() was already called before this shim was invoked.
err = codec->getStatus();
if (err == kErpcStatus_Success)
{
// Invoke the actual served function.
#if ERPC_NESTED_CALLS_DETECTION
nestingDetection = true;
#endif
result = m_handler->fileWriteAbort();
#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, file_service_interface::m_serviceId, file_service_interface::m_fileWriteAbortId, sequence);
codec->write(result);
err = codec->getStatus();
}
return err;
}

View File

@ -0,0 +1,58 @@
/*
* Generated by erpcgen 1.14.0 on Tue Apr 28 12:01:23 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/
#if !defined(_file_service_server_hpp_)
#define _file_service_server_hpp_
#include "file_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 file_service.
*/
class file_service_service : public erpc::Service
{
public:
file_service_service(file_service_interface *_file_service_interface);
virtual ~file_service_service();
/*! @brief return service interface handler. */
file_service_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:
file_service_interface *m_handler;
/*! @brief Server shim for fileWriteBegin of file_service interface. */
erpc_status_t fileWriteBegin_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for fileWriteChunk of file_service interface. */
erpc_status_t fileWriteChunk_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for fileWriteEnd of file_service interface. */
erpc_status_t fileWriteEnd_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
/*! @brief Server shim for fileWriteAbort of file_service interface. */
erpc_status_t fileWriteAbort_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence);
};
} // erpcShim
#endif // _file_service_server_hpp_

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -1,5 +1,5 @@
/*
* Generated by erpcgen 1.14.0 on Thu Apr 23 10:54:10 2026.
* Generated by erpcgen 1.14.0 on Tue Apr 28 13:10:25 2026.
*
* AUTOGENERATED - DO NOT EDIT
*/

View File

@ -0,0 +1,43 @@
//
// Created by Administrator on 2026/4/27.
//
#ifndef RTTHREAD_HEAD_FILE_SERVICE_IMPL_H
#define RTTHREAD_HEAD_FILE_SERVICE_IMPL_H
#include <string>
#include "erpc/proto/generated/file_service_server.hpp"
#include <rtthread.h>
class FileServiceImpl : public erpcShim::file_service_interface
{
public:
FileServiceImpl();
~FileServiceImpl() override;
int32_t fileWriteBegin(const char* path, uint32_t total_size) override;
int32_t fileWriteChunk(const binary_t* data) override;
int32_t fileWriteEnd(void) override;
int32_t fileWriteAbort(void) override;
private:
// 当前实现一次只允许一个上传会话;下面的上传状态由 upload_mutex_ 保护。
rt_mutex_t upload_mutex_;
int upload_fd_;
uint32_t upload_expected_size_;
uint32_t upload_received_size_;
std::string upload_target_path_;
std::string upload_temp_path_;
// 规范化上传路径,并拒绝设备路径和父目录跳转。
static bool normalizeUploadPath(const char* path, std::string* normalized);
static int32_t posixErrorToRtError(void);
void resetUploadStateLocked(void);
// 调用方必须已经持有 upload_mutex_。
int32_t abortUploadLocked(void);
};
#endif

View File

@ -11,9 +11,9 @@
#include "erpc/proto/generated/servo_service_server.hpp"
#include "servo_manager/include/servo_manager.h"
extern "C" {
#include <rtthread.h>
}
class ServoServiceImpl : public erpcShim::servo_service_interface
{

View File

@ -19,6 +19,12 @@
#include "erpc/common/include/erpc_error_handler.h"
#include "erpc/proto/generated/file_service_server.hpp"
#include "erpc/proto/generated/file_service_interface.hpp"
#include "erpc/service/include/file_service_impl.h"
#ifndef ERPC_THREAD_STACK
#define ERPC_THREAD_STACK (4096)
#endif
@ -72,6 +78,11 @@ static void erpc_server_entry(void *parameter)
erpc_add_service_to_server(server, &service);
static FileServiceImpl file_impl;
static erpcShim::file_service_service file_service(&file_impl);
erpc_add_service_to_server(server, &file_service);
rt_kprintf("[erpc] server run\r\n");
erpc_server_run(server);
while (true){

View File

@ -0,0 +1,278 @@
//
// Created by Administrator on 2026/4/27.
//
#include "erpc/service/include/file_service_impl.h"
#include <fcntl.h>
#include <unistd.h>
FileServiceImpl::FileServiceImpl()
: upload_mutex_(RT_NULL),
upload_fd_(-1),
upload_expected_size_(0),
upload_received_size_(0)
{
upload_mutex_ = rt_mutex_create("sv_file", RT_IPC_FLAG_PRIO);
}
FileServiceImpl::~FileServiceImpl()
{
if (upload_mutex_) {
rt_mutex_take(upload_mutex_, RT_WAITING_FOREVER);
(void)abortUploadLocked();
rt_mutex_release(upload_mutex_);
rt_mutex_delete(upload_mutex_);
upload_mutex_ = RT_NULL;
}
}
bool FileServiceImpl::normalizeUploadPath(const char* path, std::string* normalized)
{
std::string local_path;
if (!path || !normalized) {
return false;
}
local_path.assign(path);
if (local_path.empty()) {
return false;
}
if (local_path[0] != '/') {
local_path.insert(local_path.begin(), '/');
}
// 避免覆盖设备节点,也避免通过 ".." 跳出预期目录。
if (local_path == "/" ||
local_path.rfind("/dev", 0) == 0 ||
local_path.find("/../") != std::string::npos ||
(local_path.size() >= 3 && local_path.compare(local_path.size() - 3, 3, "/..") == 0)) {
return false;
}
*normalized = local_path;
return true;
}
int32_t FileServiceImpl::posixErrorToRtError(void)
{
const int err = rt_get_errno();
if (err > 0) {
return -err;
}
if (err < 0) {
return err;
}
return -RT_ERROR;
}
void FileServiceImpl::resetUploadStateLocked(void)
{
upload_fd_ = -1;
upload_expected_size_ = 0;
upload_received_size_ = 0;
upload_target_path_.clear();
upload_temp_path_.clear();
}
int32_t FileServiceImpl::abortUploadLocked(void)
{
// 取消上传时尽量关闭文件、删除残留的 .part 文件,并清空内存状态。
if (upload_fd_ >= 0) {
if (::close(upload_fd_) != 0) {
const int32_t err = posixErrorToRtError();
upload_fd_ = -1;
if (!upload_temp_path_.empty()) {
(void)::unlink(upload_temp_path_.c_str());
}
resetUploadStateLocked();
return err;
}
}
if (!upload_temp_path_.empty()) {
(void)::unlink(upload_temp_path_.c_str());
}
resetUploadStateLocked();
return RT_EOK;
}
int32_t FileServiceImpl::fileWriteBegin(const char* path, uint32_t total_size)
{
std::string normalized_path;
std::string temp_path;
int fd;
if (!upload_mutex_) {
rt_kprintf("[FileService][E] fileWriteBegin: upload mutex is null\n");
return -RT_ENOMEM;
}
if (!normalizeUploadPath(path, &normalized_path)) {
rt_kprintf("[FileService][E] fileWriteBegin: invalid path=%s\n",
path ? path : "(null)");
return -RT_EINVAL;
}
temp_path = normalized_path + ".part";
rt_mutex_take(upload_mutex_, RT_WAITING_FOREVER);
// 单会话上传可以避免多个客户端同时写同一组上传状态。
if (upload_fd_ >= 0) {
rt_mutex_release(upload_mutex_);
rt_kprintf("[FileService][E] fileWriteBegin: upload already active, path=%s\n",
upload_target_path_.c_str());
return -RT_EBUSY;
}
// 先写临时文件,只有 fileWriteEnd() 校验完整大小后才发布到目标路径。
(void)::unlink(temp_path.c_str());
fd = ::open(temp_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0) {
const int32_t err = posixErrorToRtError();
rt_mutex_release(upload_mutex_);
rt_kprintf("[FileService][E] fileWriteBegin: open failed, path=%s err=%d\n",
temp_path.c_str(),
(int)err);
return err;
}
upload_fd_ = fd;
upload_expected_size_ = total_size;
upload_received_size_ = 0;
upload_target_path_ = normalized_path;
upload_temp_path_ = temp_path;
rt_mutex_release(upload_mutex_);
rt_kprintf("[FileService] fileWriteBegin: path=%s size=%u\n",
upload_target_path_.c_str(),
(unsigned)upload_expected_size_);
return RT_EOK;
}
int32_t FileServiceImpl::fileWriteChunk(const binary_t* data)
{
uint32_t remaining;
const uint8_t* cursor;
if (!upload_mutex_) {
return -RT_ENOMEM;
}
if (!data || (!data->data && data->dataLength > 0)) {
rt_kprintf("[FileService][E] fileWriteChunk: invalid chunk\n");
return -RT_EINVAL;
}
rt_mutex_take(upload_mutex_, RT_WAITING_FOREVER);
if (upload_fd_ < 0) {
rt_mutex_release(upload_mutex_);
rt_kprintf("[FileService][E] fileWriteChunk: upload not started\n");
return -RT_ERROR;
}
// 防止客户端重传、偏移错误或长度错误导致写入超过声明的 total_size。
if (data->dataLength > (upload_expected_size_ - upload_received_size_)) {
rt_mutex_release(upload_mutex_);
rt_kprintf("[FileService][E] fileWriteChunk: chunk overflow, recv=%u chunk=%u total=%u\n",
(unsigned)upload_received_size_,
(unsigned)data->dataLength,
(unsigned)upload_expected_size_);
return -RT_EINVAL;
}
remaining = data->dataLength;
cursor = data->data;
// write() 可能只写入部分数据,因此循环直到当前 eRPC binary 块全部落盘。
while (remaining > 0) {
const ssize_t written = ::write(upload_fd_, cursor, remaining);
if (written <= 0) {
const int32_t err = posixErrorToRtError();
(void)abortUploadLocked();
rt_mutex_release(upload_mutex_);
rt_kprintf("[FileService][E] fileWriteChunk: write failed, err=%d\n", (int)err);
return err;
}
remaining -= (uint32_t)written;
cursor += written;
upload_received_size_ += (uint32_t)written;
}
rt_mutex_release(upload_mutex_);
return RT_EOK;
}
int32_t FileServiceImpl::fileWriteEnd(void)
{
if (!upload_mutex_) {
return -RT_ENOMEM;
}
rt_mutex_take(upload_mutex_, RT_WAITING_FOREVER);
if (upload_fd_ < 0) {
rt_mutex_release(upload_mutex_);
rt_kprintf("[FileService][E] fileWriteEnd: upload not started\n");
return -RT_ERROR;
}
// 最终大小必须完全一致,避免缺块时发布不完整文件。
if (upload_received_size_ != upload_expected_size_) {
const uint32_t received = upload_received_size_;
const uint32_t expected = upload_expected_size_;
(void)abortUploadLocked();
rt_mutex_release(upload_mutex_);
rt_kprintf("[FileService][E] fileWriteEnd: size mismatch, recv=%u expected=%u\n",
(unsigned)received,
(unsigned)expected);
return -RT_EINVAL;
}
if (::close(upload_fd_) != 0) {
const int32_t err = posixErrorToRtError();
upload_fd_ = -1;
(void)::unlink(upload_temp_path_.c_str());
resetUploadStateLocked();
rt_mutex_release(upload_mutex_);
rt_kprintf("[FileService][E] fileWriteEnd: close failed, err=%d\n", (int)err);
return err;
}
upload_fd_ = -1;
if (::rename(upload_temp_path_.c_str(), upload_target_path_.c_str()) != 0) {
(void)::unlink(upload_target_path_.c_str());
if (::rename(upload_temp_path_.c_str(), upload_target_path_.c_str()) != 0) {
const int32_t err = posixErrorToRtError();
(void)::unlink(upload_temp_path_.c_str());
resetUploadStateLocked();
rt_mutex_release(upload_mutex_);
rt_kprintf("[FileService][E] fileWriteEnd: rename failed, err=%d\n", (int)err);
return err;
}
}
rt_kprintf("[FileService] fileWriteEnd: path=%s size=%u\n",
upload_target_path_.c_str(),
(unsigned)upload_received_size_);
resetUploadStateLocked();
rt_mutex_release(upload_mutex_);
return RT_EOK;
}
int32_t FileServiceImpl::fileWriteAbort(void)
{
int32_t err;
if (!upload_mutex_) {
return -RT_ENOMEM;
}
rt_mutex_take(upload_mutex_, RT_WAITING_FOREVER);
err = abortUploadLocked();
rt_mutex_release(upload_mutex_);
return err;
}

View File

@ -114,7 +114,9 @@
//! Uncomment to change the size of buffers allocated by one of MessageBufferFactory.
//! (@ref client_setup and @ref server_setup). The default size is set to 256.
//! For RPMsg transport layer, ERPC_DEFAULT_BUFFER_SIZE must be 2^n - 16.
#define ERPC_DEFAULT_BUFFER_SIZE (512U)
// fileWriteChunk(binary) with a 4096 byte payload needs at least:
// 6 bytes framed header + 8 bytes eRPC message header + 4 bytes binary length + 4096 bytes data.
#define ERPC_DEFAULT_BUFFER_SIZE (8192U)
//! @def ERPC_DEFAULT_BUFFERS_COUNT
//!