看了稚晖君的Dummy机械臂视频后,再一次激发自己做点小玩意,嗯,会动,有显示,有声音,远程能控制。。。,想想做完大抵如此,复刻机械臂?成本有点高,和大佬差距还是有的,至少我不会solidworks,放弃吧。缘于学校里做的智能小车是直流电机驱动,驱动和控制简单,无刷电机没玩过,要不玩一通?说干就干。
看了些资料,感觉odrive是不错的选择,于是阅读了些3.5版本的硬件设计,也着手学习cadence,终于画了一版,下载git fw-v0.5.1版本,烧写下去,玩了起来。
Odrive 体验
后来将odrive 通讯类代码抠掉了,毕竟嵌入式产品这种可视化通讯很少,以备将来项目要用,用核心部分即可。
以上是odrive核心底层关系图,听说simpleFoc也不错,正好有这个主板,那就将simpleFoc也了解一下吧,看了下源码,用了什么鬼arduino,这就更驱使本人想移植到gcc下,复刻了下odrive的编译框架,开始移植起了simpleFoc了,看了里面有许多print函数,准备一个个用printf替代,改起来有点麻烦,索性将print文件准备好吧。
Print.cpp
/*
Print.cpp - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Modified 23 November 2006 by David A. Mellis
Modified 03 August 2015 by Chuck Todd
*/
#include
#include
#include
#include
#include "Print.h"
#include "usart.h"
Print Serial;
void test(void)
{
Serial.write('c');
Serial.write("123456789",9);
Serial.print("hello simpleFoc print\r\n");
}
// Public Methods //
/* default implementation: may be overridden */
size_t Print::write(uint8_t dat)
{
HAL_UART_Transmit(&huart4, (uint8_t*)&dat, 1, 0xFFFF);
return 1;
}
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--) {
if (write(*buffer++)) n++;
else break;
}
return n;
}
/* size_t Print::print(const String &s)
{
return write(s.c_str(), s.length());
}
*/
size_t Print::print(const char str[])
{
return write(str);
}
size_t Print::print(char c)
{
return write(c);
}
size_t Print::print(unsigned char b, int base)
{
return print((unsigned long) b, base);
}
size_t Print::print(int n, int base)
{
return print((long) n, base);
}
size_t Print::print(unsigned int n, int base)
{
return print((unsigned long) n, base);
}
size_t Print::print(long n, int base)
{
if (base == 0) {
return write(n);
} else if (base == 10) {
if (n < 0) {
int t = print('-');
n = -n;
return printNumber(n, 10) + t;
}
return printNumber(n, 10);
} else {
return printNumber(n, base);
}
}
size_t Print::print(unsigned long n, int base)
{
if (base == 0) return write(n);
else return printNumber(n, base);
}
size_t Print::print(double n, int digits)
{
return printFloat(n, digits);
}
/* size_t Print::print(const Printable& x)
{
return x.printTo(*this);
}
*/
size_t Print::println(void)
{
return write("\r\n");
}
/* size_t Print::println(const String &s)
{
size_t n = print(s);
n += println();
return n;
} */
size_t Print::println(const char c[])
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(char c)
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(unsigned char b, int base)
{
size_t n = print(b, base);
n += println();
return n;
}
size_t Print::println(int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(double num, int digits)
{
size_t n = print(num, digits);
n += println();
return n;
}
/* size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
} */
// Private Methods /
size_t Print::printNumber(unsigned long n, uint8_t base)
{
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1];
*str = '\0';
// prevent crash if called with base == 1
if (base < 2) base = 10;
do {
char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n);
return write(str);
}
size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers
if (number < 0.0)
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i 0) {
n += print('.');
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)(remainder);
n += print(toPrint);
remainder -= toPrint;
}
return n;
}
Print.h
/*
Print.h - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Print_h
#define Print_h
#ifdef __cplusplus
#include
#include // for size_t
#include
#define DEC 10
#define HEX 16
#define OCT 8
#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar
#undef BIN
#endif
#define BIN 2
extern "C" {
#endif
void test(void);
#ifdef __cplusplus
}
class Print
{
private:
int write_error;
size_t printNumber(unsigned long, uint8_t);
size_t printFloat(double, uint8_t);
protected:
void setWriteError(int err = 1) { write_error = err; }
public:
Print() : write_error(0) {}
int getWriteError() { return write_error; }
void clearWriteError() { setWriteError(0); }
size_t write(uint8_t);
size_t write(const char *str) {
if (str == NULL) return 0;
return write((const uint8_t *)str, strlen(str));
}
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block"
// should be overridden by subclasses with buffering
virtual int availableForWrite() { return 0; }
size_t print(const char[]);
size_t print(char);
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
// size_t print(const Printable&);
size_t println(const char[]);
size_t println(char);
size_t println(unsigned char, int = DEC);
size_t println(int, int = DEC);
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(double, int = 2);
// size_t println(const Printable&);
size_t println(void);
virtual void flush() { /* Empty implementation for backward compatibility */ }
};
extern Print Serial;
#endif
#endif
Printable.h
/*
Printable.h - Interface class that allows printing of complex types
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Printable_h
#define Printable_h
#include
class Print;
/** The Printable class provides a way for new classes to allow themselves to be printed.
By deriving from Printable and implementing the printTo method, it will then be possible
for users to print out instances of this class by passing them into the usual
Print::print and Print::println methods.
*/
class Printable
{
public:
virtual size_t printTo(Print& p) const = 0;
};
#endif
以上三个文件,都是arduino里掏出来的,嫁接到串口4上去,test()函数放天main.c里测试 OK!,工程是用stm32cube 创建的 gcc编译
makefile
# This is only a stub for various commands.
# Tup is used for the actual compilation.
BUILD_DIR = build
FIRMWARE = $(BUILD_DIR)/simpleFoc.elf
FIRMWARE_HEX = $(BUILD_DIR)/simpleFoc.hex
PROGRAMMER_CMD=$(if $(value PROGRAMMER),-c 'hla_serial $(PROGRAMMER)',)
include tup.config # source build configuration to get CONFIG_BOARD_VERSION
ifeq ($(shell python -c "import sys; print(sys.version_info.major)"), 3)
PY_CMD := python -B
else
PY_CMD := python3 -B
endif
ifneq (,$(findstring v3.,$(CONFIG_BOARD_VERSION)))
OPENOCD := openocd -f interface/stlink-v2.cfg $(PROGRAMMER_CMD) -f target/stm32f4x.cfg -c init
GDB := arm-none-eabi-gdb --ex 'target extended-remote | openocd -f "interface/stlink-v2.cfg" -f "target/stm32f4x.cfg" -c "gdb_port pipe; log_output openocd.log"' --ex 'monitor reset halt'
else ifneq (,$(findstring v4.,$(CONFIG_BOARD_VERSION)))
OPENOCD := openocd -f interface/stlink.cfg $(PROGRAMMER_CMD) -f target/stm32f7x.cfg -c 'reset_config none separate' -c init
GDB := arm-none-eabi-gdb --ex 'target extended-remote | openocd -f "interface/stlink-v2.cfg" -f "target/stm32f7x.cfg" -c "reset_config none separate" -c "gdb_port pipe; log_output openocd.log"' --ex 'monitor reset halt'
else
$(error unknown board version)
endif
$(info board version: $(CONFIG_BOARD_VERSION))
all:
# @mkdir -p autogen
# @$(PY_CMD) ../tools/odrive/version.py --output autogen/version.c
@tup --quiet -no-environ-check
# @$(PY_CMD) interface_generator_stub.py --definitions odrive-interface.yaml --template ../tools/enums_template.j2 --output ../tools/odrive/enums.py
# @$(PY_CMD) interface_generator_stub.py --definitions odrive-interface.yaml --template ../tools/arduino_enums_template.j2 --output ../Arduino/ODriveArduino/ODriveEnums.h
# Copy libfibre files to odrivetool if they were built
# @ ! test -f "fibre-cpp/build/libfibre-linux-amd64.so" || cp fibre-cpp/build/libfibre-linux-amd64.so ../tools/odrive/pyfibre/fibre/
# @ ! test -f "fibre-cpp/build/libfibre-linux-armhf.so" || cp fibre-cpp/build/libfibre-linux-armhf.so ../tools/odrive/pyfibre/fibre/
# @ ! test -f "fibre-cpp/build/libfibre-linux-aarch64.so" || cp fibre-cpp/build/libfibre-linux-aarch64.so ../tools/odrive/pyfibre/fibre/
# @ ! test -f "fibre-cpp/build/libfibre-macos-x86.dylib" || cp fibre-cpp/build/libfibre-macos-x86.dylib ../tools/odrive/pyfibre/fibre/
# @ ! test -f "fibre-cpp/build/libfibre-windows-amd64.dll" || cp fibre-cpp/build/libfibre-windows-amd64.dll ../tools/odrive/pyfibre/fibre/
libfibre-linux-armhf:
docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/fibre-linux-armhf-build:/build/build -w /build fibre-compiler configs/linux-armhf.config
cp /tmp/fibre-linux-armhf-build/libfibre-*.so ../tools/odrive/pyfibre/fibre/
libfibre-all:
docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/libfibre-build:/build/build -w /build fibre-compiler configs/linux-amd64.config
cp /tmp/libfibre-build/libfibre-linux-amd64.so ../tools/odrive/pyfibre/fibre/
docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/libfibre-build:/build/build -w /build fibre-compiler configs/linux-armhf.config
cp /tmp/libfibre-build/libfibre-linux-armhf.so ../tools/odrive/pyfibre/fibre/
docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/libfibre-build:/build/build -w /build fibre-compiler configs/linux-aarch64.config
cp /tmp/libfibre-build/libfibre-linux-aarch64.so ../tools/odrive/pyfibre/fibre/
docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/libfibre-build:/build/build -w /build fibre-compiler configs/macos-x86.config
cp /tmp/libfibre-build/libfibre-macos-x86.dylib ../tools/odrive/pyfibre/fibre/
docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/libfibre-build:/build/build -w /build fibre-compiler configs/windows-amd64.config
cp /tmp/libfibre-build/libfibre-windows-amd64.dll ../tools/odrive/pyfibre/fibre/
docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/libfibre-build:/build/build -w /build fibre-compiler configs/wasm.config
cp /tmp/libfibre-build/libfibre-wasm.* ../GUI/fibre-js/
clean:
-rm -fR .dep $(BUILD_DIR)
flash-stlink2: all
$(OPENOCD) \
-c 'reset halt' \
-c 'flash write_image erase $(FIRMWARE)' \
-c 'reset run' \
-c exit
gdb-stlink2:
$(GDB) $(FIRMWARE)
# Erase entire STM32
erase-stlink2:
$(OPENOCD) -c 'reset halt' -c 'flash erase_sector 0 0 last' -c exit
# Sometimes the STM32 will get it's protection bits set for unknown reasons. Unlock it with this command
unlock-stlink2:
$(OPENOCD) -c 'reset halt' -c 'stm32f2x unlock 0'
flash-bmp: all
arm-none-eabi-gdb --ex 'target extended-remote $(BMP_PORT)' \
--ex 'monitor swdp_scan' \
--ex 'attach 1' \
--ex 'load' \
--ex 'detach' \
--ex 'quit' \
$(FIRMWARE)
gdb-bmp: all
arm-none-eabi-gdb --ex 'target extended-remote /dev/stlink' \
--ex 'monitor swdp_scan' \
--ex 'attach 1' \
--ex 'load' $(FIRMWARE)
dfu: all
python ../tools/odrivetool $(if $(value SERIAL_NUMBER),--serial-number $(SERIAL_NUMBER),) dfu $(FIRMWARE_HEX)
flash: flash-stlink2
gdb: gdb-stlink2
erase: erase-stlink2
unlock: unlock-stlink2
.PHONY: stlink2-config flash-stlink2 gdb-stlink2 erase-stlink2 unlock-stlink2
.PHONY: flash-bmp gdb-bmp
.PHONY: all clean flash gdb erase unlock dfu fibre
Tupfile.lua
-- Utility functions -----------------------------------------------------------
function run_now(command)
local handle
handle = io.popen(command)
local output = handle:read("*a")
local rc = {handle:close()}
return rc[1], output
end
-- If we simply invoke python or python3 on a pristine Windows 10, it will try
-- to open the Microsoft Store which will not work and hang tup instead. The
-- command "python --version" does not open the Microsoft Store.
-- On some systems this may return a python2 command if Python3 is not installed.
function find_python3()
success, python_version = run_now("python --version 2>&1")
if success and string.match(python_version, "Python 3") then return "python -B" end
success, python_version = run_now("python3 --version 2>&1")
if success and string.match(python_version, "Python 3") then return "python3 -B" end
error("Python 3 not found.")
end
function add_pkg(pkg)
if pkg.is_included == true then
return
end
pkg.is_included = true
for _, file in pairs(pkg.code_files or {}) do
code_files += (pkg.root or '.')..'/'..file
end
for _, dir in pairs(pkg.include_dirs or {}) do
CFLAGS += '-I'..(pkg.root or '.')..'/'..dir
end
tup.append_table(CFLAGS, pkg.cflags or {})
tup.append_table(LDFLAGS, pkg.ldflags or {})
for _, pkg in pairs(pkg.include or {}) do
add_pkg(pkg)
end
end
function compile(src_file, obj_file)
compiler = (tup.ext(src_file) == 'c') and CC or CXX
tup.frule{
inputs={src_file},
command='^o^ '..compiler..' -c %f '..tostring(CFLAGS)..' -o %o',
outputs={obj_file}
}
end
-- Packages --------------------------------------------------------------------
stm32f4xx_hal_pkg = {
root = 'Board/Drivers/STM32F4xx_HAL_Driver',
include_dirs = {
'Inc',
-- '../CMSIS/Device/ST/STM32F4xx/Include',
-- '../CMSIS/Include',
},
code_files = {
'Src/stm32f4xx_hal.c',
'Src/stm32f4xx_hal_cortex.c',
'Src/stm32f4xx_hal_dma.c',
'Src/stm32f4xx_hal_dma_ex.c',
'Src/stm32f4xx_hal_flash.c',
'Src/stm32f4xx_hal_flash_ex.c',
'Src/stm32f4xx_hal_flash_ramfunc.c',
'Src/stm32f4xx_hal_gpio.c',
'Src/stm32f4xx_hal_pwr.c',
'Src/stm32f4xx_hal_pwr_ex.c',
'Src/stm32f4xx_hal_rcc.c',
'Src/stm32f4xx_hal_rcc_ex.c',
'Src/stm32f4xx_hal_uart.c',
'Src/stm32f4xx_hal_tim.c',
'Src/stm32f4xx_hal_tim_ex.c',
'Src/stm32f4xx_hal_exti.c',
},
cflags = {'-DARM_MATH_CM4', '-mcpu=cortex-m4', '-mfpu=fpv4-sp-d16', '-DFPU_FPV4'}
}
--[[ freertos_pkg = {
root = 'Board/Middlewares/Third_Party/FreeRTOS',
include_dirs = {
'Source/include',
'Source/CMSIS_RTOS',
},
code_files = {
'Source/croutine.c',
'Source/event_groups.c',
'Source/list.c',
'Source/queue.c',
'Source/stream_buffer.c',
'Source/tasks.c',
'Source/timers.c',
'Source/CMSIS_RTOS/cmsis_os.c',
'Source/portable/MemMang/heap_4.c',
}
} ]]
cmsis_pkg = {
root = 'Board/Drivers/CMSIS',
include_dirs = {
'Include',
'Device/ST/STM32F4xx/Include'
},
ldflags = {'-LBoard/Middlewares/ST/ARM/DSP/Lib'},
}
--[[ stm32_usb_device_library_pkg = {
root = 'Board/Middlewares/ST/STM32_USB_Device_Library',
include_dirs = {
'Core/Inc',
'Class/CDC/Inc',
},
code_files = {
'Core/Src/usbd_core.c',
'Core/Src/usbd_ctlreq.c',
'Core/Src/usbd_ioreq.c',
'Class/CDC/Src/usbd_cdc.c',
}
} ]]
simpleFoc_firmware_pkg = {
root = '.',
include_dirs = {
'.',
'Board/Middlewares/ST/ARM/DSP/Inc',
'arduino',
'communication',
},
code_files = {
'arduino/Print.cpp',
'communication/SimpleFOCDebug.cpp',
-- 'arduino/hwSerial.cpp'
-- 'arduino/WString.cpp',
--[[ 'syscalls.c',
'MotorControl/arm_cos_f32.c',
'MotorControl/arm_sin_f32.c',
'MotorControl/thermistor.cpp',
'MotorControl/trapTraj.cpp',
'MotorControl/endstop.cpp',
'MotorControl/motor.cpp',
'MotorControl/main.cpp',
'MotorControl/low_level.cpp',
'MotorControl/encoder.cpp',
'MotorControl/axis.cpp',
'MotorControl/nvm.c',
'MotorControl/sensorless_estimator.cpp',
'MotorControl/controller.cpp',
'MotorControl/utils.cpp',
'autogen/version.c',
'communication/interface_can.cpp',
'FreeRTOS-openocd.c', ]]
-- 'communication/interface_usb.cpp',
}
}
board_v3 = {
root = 'Board/Core',
include = {stm32f4xx_hal_pkg},
include_dirs = {
'Inc',
-- 'Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F',
-- '../Drivers/DRV8301',
},
code_files = {
'../startup_stm32f405xx.s',
-- './Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c',
-- '../Drivers/DRV8301/drv8301.c',
--'board.cpp',
--[[ 'Src/tim.c',
'Src/dma.c', ]]
'Src/gpio.c',
'Src/main.c',
--[[ 'Src/spi.c',
'Src/stm32f4xx_hal_msp.c',
'Src/stm32f4xx_hal_timebase_TIM.c', ]]
'Src/stm32f4xx_it.c',
'Src/system_stm32f4xx.c',
'Src/usart.c',
--[[ 'Src/usb_device.c',
'Src/usbd_cdc_if.c',
'Src/usbd_conf.c',
'Src/adc.c',
'Src/usbd_desc.c',
'Src/can.c', ]]
--'Src/i2c.c',
},
cflags = {'-DSTM32F405xx', '-DHW_VERSION_MAJOR=3'},
ldflags = {
'-TBoard/STM32F405RGTx_FLASH.ld',
'-l:iar_cortexM4lf_math.a',
}
}
boards = {
["v3.1"] = {include={board_v3}, cflags={"-DHW_VERSION_MINOR=1 -DHW_VERSION_VOLTAGE=24"}},
["v3.2"] = {include={board_v3}, cflags={"-DHW_VERSION_MINOR=2 -DHW_VERSION_VOLTAGE=24"}},
["v3.3"] = {include={board_v3}, cflags={"-DHW_VERSION_MINOR=3 -DHW_VERSION_VOLTAGE=24"}},
["v3.4-24V"] = {include={board_v3}, cflags={"-DHW_VERSION_MINOR=4 -DHW_VERSION_VOLTAGE=24"}},
["v3.4-48V"] = {include={board_v3}, cflags={"-DHW_VERSION_MINOR=4 -DHW_VERSION_VOLTAGE=48"}},
["v3.5-24V"] = {include={board_v3}, cflags={"-DHW_VERSION_MINOR=5 -DHW_VERSION_VOLTAGE=24"}},
["v3.5-48V"] = {include={board_v3}, cflags={"-DHW_VERSION_MINOR=5 -DHW_VERSION_VOLTAGE=48"}},
["v3.6-24V"] = {include={board_v3}, cflags={"-DHW_VERSION_MINOR=6 -DHW_VERSION_VOLTAGE=24"}},
["v3.6-56V"] = {include={board_v3}, cflags={"-DHW_VERSION_MINOR=6 -DHW_VERSION_VOLTAGE=56"}},
["v4.0-56V"] = {include={board_v4}, cflags={"-DHW_VERSION_MINOR=0 -DHW_VERSION_VOLTAGE=56"}},
["v4.1-58V"] = {include={board_v4}, cflags={"-DHW_VERSION_MINOR=1 -DHW_VERSION_VOLTAGE=58"}},
}
-- Toolchain setup -------------------------------------------------------------
CC='arm-none-eabi-gcc -std=c99'
CXX='arm-none-eabi-g++ -std=c++17 -Wno-register'
LINKER='arm-none-eabi-g++'
-- C-specific flags
CFLAGS += '-D__weak="__attribute__((weak))"'
CFLAGS += '-D__packed="__attribute__((__packed__))"'
CFLAGS += '-DUSE_HAL_DRIVER'
CFLAGS += '-mthumb'
CFLAGS += '-mfloat-abi=hard'
CFLAGS += '-Wno-psabi' -- suppress unimportant note about ABI compatibility in GCC 10
CFLAGS += { '-Wall', '-Wdouble-promotion', '-Wfloat-conversion', '-fdata-sections', '-ffunction-sections'}
CFLAGS += '-g'
CFLAGS += '-DFIBRE_ENABLE_SERVER'
CFLAGS += '-Wno-nonnull'
-- linker flags
LDFLAGS += '-flto -lc -lm -lnosys' -- libs
-- LDFLAGS += '-mthumb -mfloat-abi=hard -specs=nosys.specs -specs=nano.specs -u _printf_float -u _scanf_float -Wl,--cref -Wl,--gc-sections'
LDFLAGS += '-mthumb -mfloat-abi=hard -specs=nosys.specs -u _printf_float -u _scanf_float -Wl,--cref -Wl,--gc-sections'
LDFLAGS += '-Wl,--undefined=uxTopUsedPriority'
-- Handle Configuration Options ------------------------------------------------
-- Switch between board versions
boardversion = tup.getconfig("BOARD_VERSION")
if boardversion == "" then
error("board version not specified - take a look at tup.config.default")
elseif boards[boardversion] == nil then
error("unknown board version "..boardversion)
end
board = boards[boardversion]
-- --not
-- TODO: remove this setting
if tup.getconfig("USB_PROTOCOL") ~= "native" and tup.getconfig("USB_PROTOCOL") ~= "" then
error("CONFIG_USB_PROTOCOL is deprecated")
end
-- UART I/O settings
if tup.getconfig("UART_PROTOCOL") ~= "ascii" and tup.getconfig("UART_PROTOCOL") ~= "" then
error("CONFIG_UART_PROTOCOL is deprecated")
end
-- Compiler settings
if tup.getconfig("STRICT") == "true" then
CFLAGS += '-Werror'
end
if tup.getconfig("NO_DRM") == "true" then
CFLAGS += '-DNO_DRM'
end
-- debug build
if tup.getconfig("DEBUG") == "true" then
CFLAGS += '-gdwarf-2 -Og'
else
CFLAGS += '-O2'
end
if tup.getconfig("USE_LTO") == "true" then
CFLAGS += '-flto'
end
-- Generate Tup Rules ----------------------------------------------------------
python_command = find_python3()
print('Using python command "'..python_command..'"')
-- TODO: use CI to verify that on PRs the enums.py file is consistent with the YAML.
-- Note: we currently check this file into source control for two reasons:
-- - Don't require tup to run in order to use odrivetool from the repo
-- - On Windows, tup is unhappy with writing outside of the tup directory
--tup.frule{command=python_command..' interface_generator_stub.py --definitions odrive-interface.yaml --template enums_template.j2 --output ../tools/odrive/enums.py'}
-- tup.frule{
-- command=python_command..' ../tools/odrive/version.py --output %o',
-- outputs={'autogen/version.c'}
-- }
-- Autogen files from YAML interface definitions
--root_interface = board.include[1].root_interface
--tup.frule{inputs={'fibre-cpp/interfaces_template.j2', extra_inputs='odrive-interface.yaml'}, command=python_command..' interface_generator_stub.py --definitions odrive-interface.yaml --template %f --output %o', outputs='autogen/interfaces.hpp'}
--tup.frule{inputs={'fibre-cpp/function_stubs_template.j2', extra_inputs='odrive-interface.yaml'}, command=python_command..' interface_generator_stub.py --definitions odrive-interface.yaml --template %f --output %o', outputs='autogen/function_stubs.hpp'}
--tup.frule{inputs={'fibre-cpp/endpoints_template.j2', extra_inputs='odrive-interface.yaml'}, command=python_command..' interface_generator_stub.py --definitions odrive-interface.yaml --generate-endpoints '..root_interface..' --template %f --output %o', outputs='autogen/endpoints.hpp'}
--tup.frule{inputs={'fibre-cpp/type_info_template.j2', extra_inputs='odrive-interface.yaml'}, command=python_command..' interface_generator_stub.py --definitions odrive-interface.yaml --template %f --output %o', outputs='autogen/type_info.hpp'}
add_pkg(board)
-- add_pkg(freertos_pkg)
add_pkg(cmsis_pkg)
-- add_pkg(stm32_usb_device_library_pkg)
--add_pkg(fibre_pkg)
add_pkg(simpleFoc_firmware_pkg)
for _, src_file in pairs(code_files) do
obj_file = "build/obj/"..src_file:gsub("/","_"):gsub("%.","")..".o"
object_files += obj_file
compile(src_file, obj_file)
end
tup.frule{
inputs=object_files,
command='^o^ '..LINKER..' %f '..tostring(CFLAGS)..' '..tostring(LDFLAGS)..
' -Wl,-Map=%O.map -o %o',
outputs={'build/simpleFoc.elf', extra_outputs={'build/simpleFoc.map'}}
}
-- display the size
tup.frule{inputs={'build/simpleFoc.elf'}, command='arm-none-eabi-size %f'}
-- create *.hex and *.bin output formats
tup.frule{inputs={'build/simpleFoc.elf'}, command='arm-none-eabi-objcopy -O ihex %f %o', outputs={'build/simpleFoc.hex'}}
tup.frule{inputs={'build/simpleFoc.elf'}, command='arm-none-eabi-objcopy -O binary -S %f %o', outputs={'build/simpleFoc.bin'}}
if tup.getconfig('ENABLE_DISASM') == 'true' then
tup.frule{inputs={'build/simpleFoc.elf'}, command='arm-none-eabi-objdump %f -dSC > %o', outputs={'build/simpleFoc.asm'}}
end
if tup.getconfig('DOCTEST') == 'true' then
TEST_INCLUDES = '-I. -I./MotorControl -I./fibre-cpp/include -I./Drivers/DRV8301 -I./doctest'
tup.foreach_rule('Tests/*.cpp', 'g++ -O3 -std=c++17 '..TEST_INCLUDES..' -c %f -o %o', 'Tests/bin/%B.o')
tup.frule{inputs='Tests/bin/*.o', command='g++ %f -o %o', outputs='Tests/test_runner.exe'}
tup.frule{inputs='Tests/test_runner.exe', command='%f'}
end
好了,今天移植成果记录到此!源码工程在 https://github.com/wenyezhong/simpleFoc
commit信息 :构建编译框架和调试信息 准备部分 版本。