我是靠谱客的博主 清新小海豚,最近开发中收集的这篇文章主要介绍移植 simpleFoc笔记(一),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

         看了稚晖君的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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "Print.h"
#include "usart.h"

Print Serial;

void test(void)
{
  Serial.write('c');
  Serial.write("123456789",9);
  Serial.print("hello simpleFoc printrn");
}

// 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("rn");
}

/* 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 = '';

  // 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<digits; ++i)
    rounding /= 10.0;
  
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  n += print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 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 <inttypes.h>
#include <stdio.h> // for size_t
#include <string.h>

#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 <stdlib.h>

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信息 :构建编译框架和调试信息 准备部分     版本。

最后

以上就是清新小海豚为你收集整理的移植 simpleFoc笔记(一)的全部内容,希望文章能够帮你解决移植 simpleFoc笔记(一)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部