NXP MCUXPresso - cc1plus.exe: out of memory allocating 65536 bytes

article/2025/11/8 13:24:04

文章目录

    • NXP MCUXPresso - cc1plus.exe: out of memory allocating 65536 bytes
    • 概述
    • 实验结论
    • 补充
    • END

NXP MCUXPresso - cc1plus.exe: out of memory allocating 65536 bytes

概述

在尝试迁移 openpnp - Smoothieware project 从gcc命令行 + MRI调试方式 到NXP MCUXpresso工程.
遇到了编译器错误 cc1plus.exe: out of memory allocating
在这里插入图片描述
错误后面的字节数, 根据代码实现的不同, 也可能是其他数字.

查到资料上说的原始资料 cc1plus.exe: out of memory allocating 65536 bytes

尝试对MCUXPresso的cc1plus.exe做修改.
我的环境为win10x64工作站版

bcdedit /set IncreaseUserVa 3072

先查一下, editbin在哪里?
我计算机上装了vs2022
在这里插入图片描述
进入命令行, 到达editbin的目录

C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.32215\bin\Hostx86\arm>

看看MCUXPresso用的cc1plus在哪里? 还好, 就一个.
在这里插入图片描述
执行官方资料的第2步修改.

C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.32215\bin\Hostx86\arm>
editbin /LARGEADDRESSAWARE "D:\nxp\MCUXpressoIDE_11.7.1_9221\ide\plugins\com.nxp.mcuxpresso.tools.win32_11.7.1.202301190959\tools\lib\gcc\arm-none-eabi\10.3.1\cc1plus.exe"Microsoft (R) COFF/PE Editor Version 14.35.32215.0
Copyright (C) Microsoft Corporation.  All rights reserved.

查看修改后的cc1plus

D:\nxp\MCUXpressoIDE_11.7.1_9221\ide\plugins\com.nxp.mcuxpresso.tools.win32_11.7.1.202301190959\tools\lib\gcc\arm-none-eabi\10.3.1>dumpbin -headers cc1plus.exe | more
Microsoft (R) COFF/PE Dumper Version 14.29.30148.0
Copyright (C) Microsoft Corporation.  All rights reserved.Dump of file cc1plus.exePE signature foundFile Type: EXECUTABLE IMAGEFILE HEADER VALUES14C machine (x86)7 number of sections0 time date stamp0 file pointer to symbol table0 number of symbolsE0 size of optional header32F characteristicsRelocations strippedExecutableLine numbers strippedSymbols strippedApplication can handle large (>2GB) addresses // 这里已经修改过来了.32 bit word machineDebug information strippedOPTIONAL HEADER VALUES10B magic # (PE32)2.30 linker version
-- More  --

再尝试编译迁移中的工程, cc1plus 内存不够的报错还有.
尝试关掉MCUXpresso, 再打开工程编译. 还是报错.

最后根据提示信息, 定位到 路径 /my_Smoothieware_best-for-pnp/src/src/modules/robot/Robot.cpp 编译不过.

cc1plus.exe: out of memory allocating 65536 bytes
Building file: ../src/mbed/src/cpp/Timeout.cpp
Finished building: ../src/mbed/src/cpp/Serial.cpp
Finished building: ../src/mbed/src/cpp/Stream.cpp
Invoking: MCU C++ Compiler
Invoking: MCU C++ Compilermake[1]: *** [src/src/modules/robot/subdir.mk:30: src/src/modules/robot/Robot.o] Error 1
arm-none-eabi-c++ -DDEBUG -DMRI_INIT_PARAMETERS=\"MRI_UART_3\" -DWRITE_BUFFER_DISABLE=1 -DMRI_BREAK_ON_INIT=0 -DMRI_SEMIHOST_STDIO=0 -DSTACK_SIZE=1024 -DMRI_ENABLE=1 -DDEFAULT_SERIAL_BAUD_RATE=115200 -D__CODE_RED -D__NEWLIB__ -DCORE_M3 -DCPP_NO_HEAP -D__LPC17XX__ -I"D:\my_dev\my_local_git_prj\hardware\LS_openpnp_hardware\src\my_Smoothieware_best-for-pnp\my_Smoothieware_best-for-pnp\inc" -I"D:\my_dev\my_local_git_prj\hardware\LS_openpnp_hardware\src\my_Smoothieware_best-for-pnp\my_Smoothieware_best-for-pnp\src\src\libs" -I"D:\my_dev\my_local_git_prj\hardware\LS_openpnp_hardware\src\my_Smoothieware_best-for-pnp\my_Smoothieware_best-for-pnp\src\src" -I"D:\my_dev\my_local_git_prj\hardware\LS_openpnp_hardware\src\my_Smoothieware_best-for-pnp\my_Smoothieware_best-for-pnp\src\mbed\src" -O0 -fno-common -g3 -Wall -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fmerge-constants -fmacro-prefix-map="../src/mbed/src/cpp/"= -mcpu=cortex-m3 -mthumb -D__NEWLIB__ -fstack-usage -MMD -MP -MF"src/mbed/src/cpp/Ticker.d" -MT"src/mbed/src/cpp/Ticker.o" -MT"src/mbed/src/cpp/Ticker.d" -o "src/mbed/src/cpp/Ticker.o" "../src/mbed/src/cpp/Ticker.cpp"
make[1]: *** Waiting for unfinished jobs....

去查看src/src/modules/robot/subdir.mk

################################################################################
# Automatically-generated file. Do not edit!
################################################################################# Add inputs and outputs from these tool invocations to the build variables 
CPP_SRCS += \
../src/src/modules/robot/Block.cpp \
../src/src/modules/robot/BlockQueue.cpp \
../src/src/modules/robot/Conveyor.cpp \
../src/src/modules/robot/Planner.cpp \
../src/src/modules/robot/Robot.cpp CPP_DEPS += \
./src/src/modules/robot/Block.d \
./src/src/modules/robot/BlockQueue.d \
./src/src/modules/robot/Conveyor.d \
./src/src/modules/robot/Planner.d \
./src/src/modules/robot/Robot.d OBJS += \
./src/src/modules/robot/Block.o \
./src/src/modules/robot/BlockQueue.o \
./src/src/modules/robot/Conveyor.o \
./src/src/modules/robot/Planner.o \
./src/src/modules/robot/Robot.o # Each subdirectory must supply rules for building sources it contributes
src/src/modules/robot/%.o: ../src/src/modules/robot/%.cpp src/src/modules/robot/subdir.mk@echo 'Building file: $<'@echo 'Invoking: MCU C++ Compiler'arm-none-eabi-c++ -DDEBUG -DMRI_INIT_PARAMETERS=\"MRI_UART_3\" -DWRITE_BUFFER_DISABLE=1 -DMRI_BREAK_ON_INIT=0 -DMRI_SEMIHOST_STDIO=0 -DSTACK_SIZE=1024 -DMRI_ENABLE=1 -DDEFAULT_SERIAL_BAUD_RATE=115200 -D__CODE_RED -D__NEWLIB__ -DCORE_M3 -DCPP_NO_HEAP -D__LPC17XX__ -I"D:\my_dev\my_local_git_prj\hardware\LS_openpnp_hardware\src\my_Smoothieware_best-for-pnp\my_Smoothieware_best-for-pnp\inc" -I"D:\my_dev\my_local_git_prj\hardware\LS_openpnp_hardware\src\my_Smoothieware_best-for-pnp\my_Smoothieware_best-for-pnp\src\src\libs" -I"D:\my_dev\my_local_git_prj\hardware\LS_openpnp_hardware\src\my_Smoothieware_best-for-pnp\my_Smoothieware_best-for-pnp\src\src" -I"D:\my_dev\my_local_git_prj\hardware\LS_openpnp_hardware\src\my_Smoothieware_best-for-pnp\my_Smoothieware_best-for-pnp\src\mbed\src" -O0 -fno-common -g3 -Wall -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fmerge-constants -fmacro-prefix-map="$(<D)/"= -mcpu=cortex-m3 -mthumb -D__NEWLIB__ -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -MT"$(@:%.o=%.d)" -o "$@" "$<"@echo 'Finished building: $<'@echo ' 'clean: clean-src-2f-src-2f-modules-2f-robotclean-src-2f-src-2f-modules-2f-robot:-$(RM) ./src/src/modules/robot/Block.d ./src/src/modules/robot/Block.o ./src/src/modules/robot/BlockQueue.d ./src/src/modules/robot/BlockQueue.o ./src/src/modules/robot/Conveyor.d ./src/src/modules/robot/Conveyor.o ./src/src/modules/robot/Planner.d ./src/src/modules/robot/Planner.o ./src/src/modules/robot/Robot.d ./src/src/modules/robot/Robot.o.PHONY: clean-src-2f-src-2f-modules-2f-robot

查看生成的.o, 发现robot.o没有生成出来.
在这里插入图片描述
尝试单独编译robot.cpp, 还是编译不过, 报错信息同样是cc1plus.exe …
在这里插入图片描述

12:02:10 **** Building Selected Files of configuration Debug for project my_Smoothieware_best-for-pnp ****
Info: Internal Builder is used for build
arm-none-eabi-c++ -DDEBUG "-DMRI_INIT_PARAMETERS=\\MRI_UART_3\\" -DWRITE_BUFFER_DISABLE=1 -DMRI_BREAK_ON_INIT=0 -DMRI_SEMIHOST_STDIO=0 -DSTACK_SIZE=1024 -DMRI_ENABLE=1 -DDEFAULT_SERIAL_BAUD_RATE=115200 -D__CODE_RED -D__NEWLIB__ -DCORE_M3 -DCPP_NO_HEAP -D__LPC17XX__ "-ID:\\my_dev\\my_local_git_prj\\hardware\\LS_openpnp_hardware\\src\\my_Smoothieware_best-for-pnp\\my_Smoothieware_best-for-pnp\\inc" "-ID:\\my_dev\\my_local_git_prj\\hardware\\LS_openpnp_hardware\\src\\my_Smoothieware_best-for-pnp\\my_Smoothieware_best-for-pnp\\src\\src\\libs" "-ID:\\my_dev\\my_local_git_prj\\hardware\\LS_openpnp_hardware\\src\\my_Smoothieware_best-for-pnp\\my_Smoothieware_best-for-pnp\\src\\src" "-ID:\\my_dev\\my_local_git_prj\\hardware\\LS_openpnp_hardware\\src\\my_Smoothieware_best-for-pnp\\my_Smoothieware_best-for-pnp\\src\\mbed\\src" -O0 -fno-common -g3 -Wall -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fmerge-constants -fmacro-prefix-map=$(<D)/= -mcpu=cortex-m3 -mthumb -D__NEWLIB__ -fstack-usage -o "src\\src\\modules\\robot\\Robot.o" "..\\src\\src\\modules\\robot\\Robot.cpp" cc1plus.exe: out of memory allocating 65536 bytes12:02:44 Build Finished. 0 errors, 0 warnings. (took 33s.373ms)

不知道cc1plus.exe内部哪里内存开小了. 找一下解决方法.
打开cc1plus.exe看了一下, 报错信息的提示引用处, 都是给了一个size, 如果分配失败, 就打印报错信息.
分配内存的函数调用点很多, 而且给的size各种各样的大小. 可以确定, 不是cc1plus.exe实现的问题.

是不是robot.cpp写的不合适?

从定位到的robot.cpp的实现上, 用排除法看看, 到底是哪里引起cc1plus报错.
将robot.cpp分为2个文件. robot_A.cpp, robot_B.cpp.
2个实现, 都包含同样的头内容.
然后用二分法, 将实现拆开. 尝试编译2个实现.
发现, 其中一个是能编译过的, 一个是编译不过的.
将实现函数向能编译过的.cpp转移. 直到定位到编译不过的函数实现为止.
最后确定, 是Robot::load_config()函数编译不过, 引起cc1plus.exe报错.
将Robot::load_config()函数从下到上开始注释(用2分法), 最后确定, 是函数尾部几行实现引起编译报错.
在类中, 新添了一个函数void Robot::load_config_next1(), 将报错函数引起报错的语句, 改为调用load_config_next1().
在load_config_next1()中, 将引起报错的多余实现丢进去.
再编译, 编译通过! 搞定:)

void Robot::load_config()
{// Arm solutions are used to convert positions in millimeters into position in steps for each stepper motor.// While for a cartesian arm solution, this is a simple multiplication, in other, less simple cases, there is some serious math to be done.// To make adding those solution easier, they have their own, separate object.// Here we read the config to find out which arm solution to useif (this->arm_solution) delete this->arm_solution;int solution_checksum = get_checksum(THEKERNEL->config->value(arm_solution_checksum)->by_default("cartesian")->as_string());// Note checksums are not const expressions when in debug mode, so don't use switchif(solution_checksum == hbot_checksum || solution_checksum == corexy_checksum) {this->arm_solution = new HBotSolution(THEKERNEL->config);} else if(solution_checksum == corexz_checksum) {this->arm_solution = new CoreXZSolution(THEKERNEL->config);} else if(solution_checksum == rostock_checksum || solution_checksum == kossel_checksum || solution_checksum == delta_checksum || solution_checksum ==  linear_delta_checksum) {this->arm_solution = new LinearDeltaSolution(THEKERNEL->config);} else if(solution_checksum == rotatable_cartesian_checksum) {this->arm_solution = new RotatableCartesianSolution(THEKERNEL->config);} else if(solution_checksum == rotary_delta_checksum) {this->arm_solution = new RotaryDeltaSolution(THEKERNEL->config);} else if(solution_checksum == morgan_checksum) {this->arm_solution = new MorganSCARASolution(THEKERNEL->config);} else if(solution_checksum == cartesian_checksum) {this->arm_solution = new CartesianSolution(THEKERNEL->config);} else {this->arm_solution = new CartesianSolution(THEKERNEL->config);}// 以上可以编译过this->feed_rate           = THEKERNEL->config->value(default_feed_rate_checksum   )->by_default(  100.0F)->as_number();this->seek_rate           = THEKERNEL->config->value(default_seek_rate_checksum   )->by_default(  100.0F)->as_number();this->mm_per_line_segment = THEKERNEL->config->value(mm_per_line_segment_checksum )->by_default(    0.0F)->as_number();this->delta_segments_per_second = THEKERNEL->config->value(delta_segments_per_second_checksum )->by_default(0.0f   )->as_number();this->mm_per_arc_segment  = THEKERNEL->config->value(mm_per_arc_segment_checksum  )->by_default(    0.0f)->as_number();this->mm_max_arc_error    = THEKERNEL->config->value(mm_max_arc_error_checksum    )->by_default(   0.01f)->as_number();this->arc_correction      = THEKERNEL->config->value(arc_correction_checksum      )->by_default(    5   )->as_number();// in mm/sec but specified in config as mm/minthis->max_speeds[X_AXIS]  = THEKERNEL->config->value(x_axis_max_speed_checksum    )->by_default(60000.0F)->as_number() / 60.0F;this->max_speeds[Y_AXIS]  = THEKERNEL->config->value(y_axis_max_speed_checksum    )->by_default(60000.0F)->as_number() / 60.0F;this->max_speeds[Z_AXIS]  = THEKERNEL->config->value(z_axis_max_speed_checksum    )->by_default(  300.0F)->as_number() / 60.0F;this->max_speed           = THEKERNEL->config->value(max_speed_checksum           )->by_default(  -60.0F)->as_number() / 60.0F;this->segment_z_moves     = THEKERNEL->config->value(segment_z_moves_checksum     )->by_default(true)->as_bool();this->save_g92            = THEKERNEL->config->value(save_g92_checksum            )->by_default(false)->as_bool();this->save_g54            = THEKERNEL->config->value(save_g54_checksum            )->by_default(THEKERNEL->is_grbl_mode())->as_bool();string g92                = THEKERNEL->config->value(set_g92_checksum             )->by_default("")->as_string();if(!g92.empty()) {// optional setting for a fixed G92 offsetstd::vector<float> t= parse_number_list(g92.c_str());if(t.size() == 3) {g92_offset[0] = t[0];g92_offset[1] = t[1];g92_offset[2] = t[2];}}// 以上可以编译过// default s value for laserthis->s_value             = THEKERNEL->config->value(laser_module_default_power_checksum)->by_default(0.8F)->as_number();// 以上编译过了// default acceleration setting, can be overriden with newer per axis settingsthis->default_acceleration= THEKERNEL->config->value(acceleration_checksum)->by_default(100.0F )->as_number(); // Acceleration is in mm/s^2// make each motorfor (size_t a = 0; a < MAX_ROBOT_ACTUATORS; a++) {Pin pins[3]; //step, dir, enablefor (size_t i = 0; i < 3; i++) {pins[i].from_string(THEKERNEL->config->value(motor_checksums[a][i])->by_default("nc")->as_string())->as_output();}if(!pins[0].connected() || !pins[1].connected()) { // step and dir must be defined, but enable is optionalif(a <= Z_AXIS) {THEKERNEL->streams->printf("FATAL: motor %c is not defined in config\n", 'X'+a);n_motors= a; // we only have this number of motorsreturn;}break; // if any pin is not defined then the axis is not defined (and axis need to be defined in contiguous order)}StepperMotor *sm = new StepperMotor(pins[0], pins[1], pins[2]);// register this motor (NB This must be 0,1,2) of the actuators arrayuint8_t n= register_motor(sm);if(n != a) {// this is a fatal errorTHEKERNEL->streams->printf("FATAL: motor %d does not match index %d\n", n, a);return;}actuators[a]->change_steps_per_mm(THEKERNEL->config->value(motor_checksums[a][3])->by_default(a == 2 ? 2560.0F : 80.0F)->as_number());actuators[a]->set_max_rate(THEKERNEL->config->value(motor_checksums[a][4])->by_default(30000.0F)->as_number()/60.0F); // it is in mm/min and converted to mm/secactuators[a]->set_acceleration(THEKERNEL->config->value(motor_checksums[a][5])->by_default(NAN)->as_number()); // mm/secs²}check_max_actuator_speeds(); // check the configs are sane// if we have not specified a z acceleration see if the legacy config was setif(isnan(actuators[Z_AXIS]->get_acceleration())) {float acc= THEKERNEL->config->value(z_acceleration_checksum)->by_default(NAN)->as_number(); // disabled by defaultif(!isnan(acc)) {actuators[Z_AXIS]->set_acceleration(acc);}}// initialise actuator positions to current cartesian position (X0 Y0 Z0)// so the first move can be correct if homing is not performedActuatorCoordinates actuator_pos;arm_solution->cartesian_to_actuator(machine_position, actuator_pos);for (size_t i = X_AXIS; i <= Z_AXIS; i++) {actuators[i]->change_last_milestone(actuator_pos[i]);}#if MAX_ROBOT_ACTUATORS > 3// initialize any extra axis to machine positionfor (size_t i = A_AXIS; i < n_motors; i++) {actuators[i]->change_last_milestone(machine_position[i]);}#endif// 以上编译过//this->clearToolOffset(); // 这句原来就注释了load_config_next1(); // 函数的size有限制(根据编译器而不同), 分成多个小函数搞定:)}void Robot::load_config_next1()
{soft_endstop_enabled= THEKERNEL->config->value(soft_endstop_checksum, enable_checksum)->by_default(false)->as_bool();soft_endstop_halt= THEKERNEL->config->value(soft_endstop_checksum, halt_checksum)->by_default(true)->as_bool();soft_endstop_min[X_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, xmin_checksum)->by_default(NAN)->as_number();soft_endstop_min[Y_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, ymin_checksum)->by_default(NAN)->as_number();soft_endstop_min[Z_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, zmin_checksum)->by_default(NAN)->as_number();soft_endstop_max[X_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, xmax_checksum)->by_default(NAN)->as_number();soft_endstop_max[Y_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, ymax_checksum)->by_default(NAN)->as_number();soft_endstop_max[Z_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, zmax_checksum)->by_default(NAN)->as_number();}

实验结论

通过这次排错, 可以猜测到, 编译器对一个函数实现编译后的大小是有限制的, 具体是多少, 根据目标平台和编译器的实现而定.
函数太大就会引起报错.

同样的代码, 换用特定的编译器, 就能直接编译过. 但是换用另外一种IDE自带的编译器, 就可能报错.

Smoothieware作者在文档中还特意说了, 只能用他们命令行安装的工具链才能编译过, 如果用其他工具链, 可能有各种各样的编译问题.
Smoothieware作者整的不规范, 能看出来, 他们不想带小白玩.
如果想膜拜Smoothieware的实现, 只能像我这样, 自己迁移Smoothieware工程, 从命令行到其他嵌入式开发的IDE. 这活, 不是随便拉一个项目小白就能搞的, 有点门槛.

如果编译不过, 出现cc1plus的报错, 可以试试排除法, 将引起的报错的函数找到, 然后将报错函数拆成几个较小的函数, 然后在报错点调用这几个小函数, 问题就解决了.

这个问题头一次遇到, 当网上公版的方法不好使的时候, 还可以依靠自己以前积累下来的调试感觉, 不断折腾, 终于搞定:) 机智!

补充

在正式工程中搞了一下, 有一些细节出入. 总体思路是对的.
文件还是一个robot.cpp
添加了一个函数load_config_next1(), 用来放装不下的实现 然后load_config()尾部上调用load_config_next1().
常量数组不能放在函数中间, 这个数组是一个常量数组(相当于一个常量数组), 可以放到函数外面.
数组的大小是根据宏来实现的, 需要设置预定义宏 MAX_ROBOT_ACTUATORS 为确定的值, 否则编译器可能将数组的size搞错, 导致编译不过.

感觉原始工程这块的编码不规范, 引起好多不必要的麻烦.
依然已经使用了类, 这个数组又是常量的, 放在类里作为成员. 在类初始化函数中赋值就好了. 为啥要放在函数中间, 将编译器搞懵逼呢?
C++的高级特性和编译器有关系, 不是不得已就不用. 使用C++简单一些好, 就像使用带类的C那样简单的使用C++就挺好. 即使换了编译器(或者换了C++标准), 也没啥影响.

如果在非必要场景下, 使用了C++高级特性, 纯粹在给自己找麻烦.

// 在工程设置中, 添加预定义宏  MAX_ROBOT_ACTUATORS=5
// 给这个宏一个确定的值, 因为这个宏的值影响这个常量数组的大小. 否则编译器不知道这个数组多大. 会导致编译不过.// Make our Primary XYZ StepperMotors, and potentially A B Cuint16_t const motor_checksums[][6] = {ACTUATOR_CHECKSUMS("alpha"), // XACTUATOR_CHECKSUMS("beta"),  // YACTUATOR_CHECKSUMS("gamma"), // Z#if MAX_ROBOT_ACTUATORS > 3ACTUATOR_CHECKSUMS("delta"),   // A#if MAX_ROBOT_ACTUATORS > 4ACTUATOR_CHECKSUMS("epsilon"), // B#if MAX_ROBOT_ACTUATORS > 5ACTUATOR_CHECKSUMS("zeta")     // C#endif#endif#endif};void Robot::load_config()
{// Arm solutions are used to convert positions in millimeters into position in steps for each stepper motor.// While for a cartesian arm solution, this is a simple multiplication, in other, less simple cases, there is some serious math to be done.// To make adding those solution easier, they have their own, separate object.// Here we read the config to find out which arm solution to useif (this->arm_solution) delete this->arm_solution;int solution_checksum = get_checksum(THEKERNEL->config->value(arm_solution_checksum)->by_default("cartesian")->as_string());// Note checksums are not const expressions when in debug mode, so don't use switchif(solution_checksum == hbot_checksum || solution_checksum == corexy_checksum) {this->arm_solution = new HBotSolution(THEKERNEL->config);} else if(solution_checksum == corexz_checksum) {this->arm_solution = new CoreXZSolution(THEKERNEL->config);} else if(solution_checksum == rostock_checksum || solution_checksum == kossel_checksum || solution_checksum == delta_checksum || solution_checksum ==  linear_delta_checksum) {this->arm_solution = new LinearDeltaSolution(THEKERNEL->config);} else if(solution_checksum == rotatable_cartesian_checksum) {this->arm_solution = new RotatableCartesianSolution(THEKERNEL->config);} else if(solution_checksum == rotary_delta_checksum) {this->arm_solution = new RotaryDeltaSolution(THEKERNEL->config);} else if(solution_checksum == morgan_checksum) {this->arm_solution = new MorganSCARASolution(THEKERNEL->config);} else if(solution_checksum == cartesian_checksum) {this->arm_solution = new CartesianSolution(THEKERNEL->config);} else {this->arm_solution = new CartesianSolution(THEKERNEL->config);}this->feed_rate           = THEKERNEL->config->value(default_feed_rate_checksum   )->by_default(  100.0F)->as_number();this->seek_rate           = THEKERNEL->config->value(default_seek_rate_checksum   )->by_default(  100.0F)->as_number();this->mm_per_line_segment = THEKERNEL->config->value(mm_per_line_segment_checksum )->by_default(    0.0F)->as_number();this->delta_segments_per_second = THEKERNEL->config->value(delta_segments_per_second_checksum )->by_default(0.0f   )->as_number();this->mm_per_arc_segment  = THEKERNEL->config->value(mm_per_arc_segment_checksum  )->by_default(    0.0f)->as_number();this->mm_max_arc_error    = THEKERNEL->config->value(mm_max_arc_error_checksum    )->by_default(   0.01f)->as_number();this->arc_correction      = THEKERNEL->config->value(arc_correction_checksum      )->by_default(    5   )->as_number();// in mm/sec but specified in config as mm/minthis->max_speeds[X_AXIS]  = THEKERNEL->config->value(x_axis_max_speed_checksum    )->by_default(60000.0F)->as_number() / 60.0F;this->max_speeds[Y_AXIS]  = THEKERNEL->config->value(y_axis_max_speed_checksum    )->by_default(60000.0F)->as_number() / 60.0F;this->max_speeds[Z_AXIS]  = THEKERNEL->config->value(z_axis_max_speed_checksum    )->by_default(  300.0F)->as_number() / 60.0F;this->max_speed           = THEKERNEL->config->value(max_speed_checksum           )->by_default(  -60.0F)->as_number() / 60.0F;this->segment_z_moves     = THEKERNEL->config->value(segment_z_moves_checksum     )->by_default(true)->as_bool();this->save_g92            = THEKERNEL->config->value(save_g92_checksum            )->by_default(false)->as_bool();this->save_g54            = THEKERNEL->config->value(save_g54_checksum            )->by_default(THEKERNEL->is_grbl_mode())->as_bool();string g92                = THEKERNEL->config->value(set_g92_checksum             )->by_default("")->as_string();if(!g92.empty()) {// optional setting for a fixed G92 offsetstd::vector<float> t= parse_number_list(g92.c_str());if(t.size() == 3) {g92_offset[0] = t[0];g92_offset[1] = t[1];g92_offset[2] = t[2];}}// default s value for laserthis->s_value             = THEKERNEL->config->value(laser_module_default_power_checksum)->by_default(0.8F)->as_number();// 下面这个数组放在这里, 编译不过// cc1plus.exe: out of memory allocating 65536 bytes// 只是一个常量数组, 移到函数外面//     // Make our Primary XYZ StepperMotors, and potentially A B C
//    uint16_t const motor_checksums[][6] = {
//        ACTUATOR_CHECKSUMS("alpha"), // X
//        ACTUATOR_CHECKSUMS("beta"),  // Y
//        ACTUATOR_CHECKSUMS("gamma"), // Z
//        #if MAX_ROBOT_ACTUATORS > 3
//        ACTUATOR_CHECKSUMS("delta"),   // A
//        #if MAX_ROBOT_ACTUATORS > 4
//        ACTUATOR_CHECKSUMS("epsilon"), // B
//        #if MAX_ROBOT_ACTUATORS > 5
//        ACTUATOR_CHECKSUMS("zeta")     // C
//        #endif
//        #endif
//        #endif
//    };// default acceleration setting, can be overriden with newer per axis settingsthis->default_acceleration= THEKERNEL->config->value(acceleration_checksum)->by_default(100.0F )->as_number(); // Acceleration is in mm/s^2// make each motorfor (size_t a = 0; a < MAX_ROBOT_ACTUATORS; a++) {Pin pins[3]; //step, dir, enablefor (size_t i = 0; i < 3; i++) {pins[i].from_string(THEKERNEL->config->value(motor_checksums[a][i])->by_default("nc")->as_string())->as_output();}if(!pins[0].connected() || !pins[1].connected()) { // step and dir must be defined, but enable is optionalif(a <= Z_AXIS) {THEKERNEL->streams->printf("FATAL: motor %c is not defined in config\n", 'X'+a);n_motors= a; // we only have this number of motorsreturn;}break; // if any pin is not defined then the axis is not defined (and axis need to be defined in contiguous order)}StepperMotor *sm = new StepperMotor(pins[0], pins[1], pins[2]);// register this motor (NB This must be 0,1,2) of the actuators arrayuint8_t n= register_motor(sm);if(n != a) {// this is a fatal errorTHEKERNEL->streams->printf("FATAL: motor %d does not match index %d\n", n, a);return;}actuators[a]->change_steps_per_mm(THEKERNEL->config->value(motor_checksums[a][3])->by_default(a == 2 ? 2560.0F : 80.0F)->as_number());actuators[a]->set_max_rate(THEKERNEL->config->value(motor_checksums[a][4])->by_default(30000.0F)->as_number()/60.0F); // it is in mm/min and converted to mm/secactuators[a]->set_acceleration(THEKERNEL->config->value(motor_checksums[a][5])->by_default(NAN)->as_number()); // mm/secs²}check_max_actuator_speeds(); // check the configs are sane// if we have not specified a z acceleration see if the legacy config was setif(isnan(actuators[Z_AXIS]->get_acceleration())) {float acc= THEKERNEL->config->value(z_acceleration_checksum)->by_default(NAN)->as_number(); // disabled by defaultif(!isnan(acc)) {actuators[Z_AXIS]->set_acceleration(acc);}}load_config_next1();}void Robot::load_config_next1()
{// initialise actuator positions to current cartesian position (X0 Y0 Z0)// so the first move can be correct if homing is not performedActuatorCoordinates actuator_pos;arm_solution->cartesian_to_actuator(machine_position, actuator_pos);for (size_t i = X_AXIS; i <= Z_AXIS; i++) {actuators[i]->change_last_milestone(actuator_pos[i]);}#if MAX_ROBOT_ACTUATORS > 3// initialize any extra axis to machine positionfor (size_t i = A_AXIS; i < n_motors; i++) {actuators[i]->change_last_milestone(machine_position[i]);}#endif//this->clearToolOffset();soft_endstop_enabled= THEKERNEL->config->value(soft_endstop_checksum, enable_checksum)->by_default(false)->as_bool();soft_endstop_halt= THEKERNEL->config->value(soft_endstop_checksum, halt_checksum)->by_default(true)->as_bool();soft_endstop_min[X_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, xmin_checksum)->by_default(NAN)->as_number();soft_endstop_min[Y_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, ymin_checksum)->by_default(NAN)->as_number();soft_endstop_min[Z_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, zmin_checksum)->by_default(NAN)->as_number();soft_endstop_max[X_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, xmax_checksum)->by_default(NAN)->as_number();soft_endstop_max[Y_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, ymax_checksum)->by_default(NAN)->as_number();soft_endstop_max[Z_AXIS]= THEKERNEL->config->value(soft_endstop_checksum, zmax_checksum)->by_default(NAN)->as_number();}

END


http://chatgpt.dhexx.cn/article/eYifg2Rl.shtml

相关文章

65536 65535 65534

65536 65535 65534 通常在导入模型的时候会遇到65534的限制&#xff0c;比如Unity里的“Meshes may not have more than 65534 vertices or triangles at the moment”提示。开起来像是2的16次方&#xff0c;但为什么不是65536&#xff1f;65536和65535会有什么问题&#xff1…

Eclipse中65536的解决办法

最近在做项目的时候&#xff0c;发现引入的第三方工程太多&#xff0c;无法打包成app文件了。如下 遇到这种问题怎么办呢&#xff1f;&#xff1f;&#xff1f;我们先看问题描述&#xff1a;方法数不在0-65536内&#xff0c;dalvik。。错误&#xff0c;不懂&#xff0c;还是先百…

Android中65536问题剖析

问题出现的原因是因为导入融云通信的包后&#xff0c;突然提示&#xff1a; Error:The number of method references in a .dex file cannot exceed 64K. Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html。 解决办法&#xf…

数据类型

强类型语言 强类型语言是一种强制类型定义的语言&#xff0c;一旦某一个变量被定义类型&#xff0c;如果不经过强制转换&#xff0c;则它永远就是该数据类型了&#xff0c;强类型语言包括Java、.net 、Python、C等语言&#xff0c;要求变量的使用要严格符合规定&#xff0c;所有…

C语言自己写代码实现的strcmp函数

我们在面试的时候&#xff0c;经常会被笔试实现C语言系统函数&#xff0c;比如strcmp函数&#xff0c;主要考察大家的C语言功底&#xff01; #include <assert.h> #include <stdio.h>int MyStrCmp(const char* str1, const char* str2) {assert((str1 ! NULL) &a…

用指针实现strcmp函数功能

strcmp函数的原理&#xff1a; 将两个字符串&#x1f50d;&#xff08;s1&#xff0c;s2&#xff09;的元素ascii码依次比较&#xff0c;直到遇到最短字符串的‘\0’&#xff0c;返回最后一个元素ascii码比较结果。 指针实现方式&#xff1a; 通过定义两个char*指针&#x1f5…

C语言中的strcmp函数的作用是什么,c语言strcmp函数用法是什么?

c语言strcmp函数用法&#xff1a;语法结构为【int strcmp(char *str1, char *str2)】&#xff0c;比较字符串str1和str2是否相同&#xff0c;如果相同则返回0&#xff0c;如果不同&#xff0c;在不同的字符处如果str1的字符大于str2字符&#xff0c;则返回负1。 c语言strcmp函数…

strcmp函数及模拟

strcmp包含在<string.h>的头文件中&#xff0c;作用是比较两个字符串。将 C 字符串 str1 与 C 字符串 str2 进行比较。 1.strcmp函数的参数和返回值、 参数&#xff1a;是两个待比较字符串的首地址 返回值&#xff1a;此函数开始比较每个字符串的第一个字符。如果它们彼此…

自定义strcmp函数

不调用#include<string.h>实现strcmp函的功能&#xff1a; 先说一下strcmp的功能&#xff0c;是一个字符串处理函数&#xff0c;是一个用于对两组字符串进行比较的函数&#xff0c;它的返回值是int类型。 例如&#xff1a; int strcmp(char s1 , char s2) char s1[ ]…

一文吃透strcmp函数

年轻是我们唯一拥有权利去编织梦想的时光&#xff01;&#x1f493;&#x1f493;&#x1f493; 文章目录 •&#x1f319;写在前面• &#x1f34b;1.函数介绍• &#x1f330;1.1.函数接口• &#x1f330;1.2.函数分析• &#x1f330;1.3.函数的简单使用• &#x1f330;1.…

比较函数大合集:strcmp,strncmp,memcmp

前言&#xff1a; 接着奏乐接着舞&#xff0c;我们继续来看字符串函数和内存函数。今天要讲的是比较函数大合集&#xff0c;话不多说&#xff0c;开肝&#xff01;&#xff01;&#xff01; strcmp函数&#xff1a; 什么是strcmp函数&#xff1f; strcmp即string compare&#…

Linux 字符串截取命令

Linux 字符串截取&#xff0c;一般用在 shell 脚本中&#xff0c;本篇写几个简单的 demo 跟大家分享一下 首先&#xff0c;定义一个变量 demohttps://blog.csdn.net/ 1.使用 # 号截取&#xff0c;删除左边字符&#xff0c;保留右边字符 echo ${demo#*//} 其中&#xff0c;demo…

bat字符串截取

举例&#xff1a;输入hello world和-2&#xff0c;输出ld 这个简单。代码如下 echo off&Setlocal enabledelayedexpansion :标签1 set 文本hello world set 开头-2 set 结尾 set /p 文本请输入文本&#xff0c;留空使用默认值hello world set /p 开头请输入取值开头位…

批处理字符串截取

批处理字符串截取 在批处理中&#xff0c;set的功能有点繁杂&#xff1a;设置变量、显示环境变量的名及值、做算术运算、等待用户的输入、字符串截取、替换字符串&#xff0c;是我们常用的命令之一。 在字符串截取方面&#xff0c;新手因为没能注意到偏移量的问题&#xff0c;…

整理了几种字符串截取方法

一、 (Substring);(Remove);(Replace) 1、取字符串的前i个字符 (1)string str1str.Substring(0,i);(2)string str1str.Remove(i,str.Length-i); 2、去掉字符串的前i个字符 string str1str.Remove(0,i);string str1str.SubString(i); 3、从右边开始取i个字符 string str1str.Sub…

JSTL标签的使用详情

if 标签 choose标签 forEach标签 这里是JSTL的标签文档&#xff0c;我们主要介绍几个常用的 https://www.runoob.com/jsp/jsp-jstl.html if 标签 if标签为判断标签&#xff0c;没有else标签&#xff0c;多个分支就用个if判断 例子 访问结果 choose标签 choose标签为选择标签…

JSTL标签库的使用及其常用标签

目录 什么是JSTL标签库&#xff1f; 使用JSTL标签库的步骤&#xff1a; 第一步&#xff1a;引入JSTL标签库对应的jar包。 第二步&#xff1a;在JSP中引入要使用标签库。&#xff08;使用taglib指令引入标签库。&#xff09; 第三步&#xff1a;在需要使用标签的位置使用即可。…

JSP之自定义jstl标签

目录 一&#xff0c;什么是JSP&#x1f351; 二&#xff0c;什么是JSTL&#xff08;JSTL标签库&#xff09;&#x1f353; 三&#xff0c;如何使用JSTL&#x1f345; 在项目中如何使用JSTL标签&#xff1f;在发开中使用JSTL标签库需要执行如下两个步骤。 &#xff08;1&a…

什么是JSTL标签?常用的标签库有哪些?

从JSP1.1规范开始&#xff0c;JSP就支持使用自定义标签&#xff0c;使用自定义标签大大降低了JSP页面的复杂度&#xff0c;同时增强了代码的重用性。为此&#xff0c;许多Web应用厂商都定制了自身应用的标签库&#xff0c;然而同一功能的标签由不同的Web应用厂商制定可能是不同…

jsp--JSTL标签库

目录 1.JSTL标签库介绍 2.JSTL 标签库的使用步骤 3.core核心库使用 3.1 <c:set> 3.2 <c:if /> 3.3 <c:choose> <c:when> <c:otherwise >标签 3.4 <c:forEach /> 1.JSTL标签库介绍 JSTL 标签库&#xff0c;全称是指 JSP Standard …