CMAKE无法为atxmega256A3u生成正确的makefile

ajsxfq5m  于 2023-04-21  发布在  其他
关注(0)|答案(2)|浏览(101)

我正在尝试创建一个通用的cmake文件,用于CLion和VSCode。其想法是创建一个目录,并在其中为每个作业创建一个子目录(这是为我的学生)。在子目录中,他们可以创建各种C/C++/S源代码。还有一个CMakeLists.txt,用于确定包括哪些附加库(以及可能编译的库)。
在超级或主目录中有一个CMakeLists.txt,如下所示:

# @file     CMakeLists.txt
# @brief    Generic CMakeFile for ATXMega in VSCode and CLion
# @author   Nico Verduin
# @date     29-3-2023
#

cmake_minimum_required(VERSION 3.12)
set(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)

project(start_voorbeelden CXX C NONE)

# add our sub projects
add_subdirectory(blink)
#add_subdirectory(blink2)
#add_subdirectory(ucg_test)

然后是子目录中的CMakeLists.txt

#
# @file     CMakeLists.txt
# @brief    root CMakeList.txt for sub projects
# @author   Nico Verduin
# @date     29-3-2023
#
#import the standard cmake
set (USE_SPILIB 1)
#set (USE_UCGLIB 1)
 
include(../generic.cmake)

最后但并非最不重要的是generic. cmake。这是所有魔术都应该发生的地方。

#
# @file     generic.cmake
# @brief    Generic CMakeFile for ATXMega in VSCode and CLion
#           Needs to be imported into the root of the individual
#           sub projects
# @author   Nico Verduin
# @date     29-3-2023
#

# give the project the root folder name
cmake_path(GET CMAKE_CURRENT_SOURCE_DIR FILENAME PROJECT_NAME)
message(STATUS "Current source dir = ${CMAKE_CURRENT_SOURCE_DIR}")

string(REPLACE " " "_" ProjectId ${PROJECT_NAME})
project(${PROJECT_NAME} C CXX NONE)

set(DEV_ROOT d:/vsavr8)
# avrdude
set(AVR_DUDE_EXECUTABLE ${DEV_ROOT}/tools/avrdude.exe)
# compiler path in root/gcc
set(COMPILE_PATH ${DEV_ROOT}/gcc/bin/)

# additional libraries
if(USE_SPILIB)
    set (SPILIB         "../spi/")
    message (STATUS "Including ${SPILIB}")
    include_directories(${SPILIB})
endif()

if(USE_UCGLIB)
    set (UCGLIB         "../ucglib/csrc/")
    set (UCG_CALLBACK   "../ucglib/callback/")
    message (STATUS "Including ${UCGLIB} and ${UCG_CALLBACK}")
    include_directories(${UCGLIB})
    include_directories(${UCG_CALLBACK})
endif()

# CPU to build for
set(TARGET_CPU ATxmega256A3U)

# our compilers
set (CMAKE_C_COMPILER ${COMPILE_PATH}avr-gcc.exe )
set (CMAKE_CXX_COMPILER ${COMPILE_PATH}avr-g++.exe )

#check if we can find the compilers
include(../CMakeVerifyCompiler.txt)

#list all search directories
message(STATUS "Included directories")
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
    message(STATUS "dir='${dir}'")
endforeach()

# compiler switches and definitions
# compiler switches and definitions
add_compile_definitions("__AVR_${TARGET_CPU}__")
add_compile_options("-O3")
add_compile_options(-fdata-sections)
add_compile_options(-ffunction-sections)
add_compile_options("-fpack-struct")
add_compile_options("-fshort-enums")
add_compile_options("-Wall")
add_compile_options("-Werror")
add_compile_options("-funsigned-char")
add_compile_options("-funsigned-bitfields")
add_compile_options("-c")
add_link_options(-Wl,--gc-sections)
add_link_options(-Wl,--print-memory-usage)
add_link_options(-Wl,--print-gc-sections)

# set verbose on
add_compile_options("-v")

# if you want to program in C++ or assembly that option is also added
# just the standard folders in the root
set(PROJECT_SOURCE_DIR  "*.c" "*.h" "*.cpp" "*.hpp" "*.s" )

# add additional library source folders
if (USE_SPILIB)
list( APPEND PROJECT_SOURCE_DIR "${SPILIB}*.c" "${SPILIB}*.h")
endif()

if (USE_UCGLIB)
    list( APPEND PROJECT_SOURCE_DIR "${UCGLIB}*.c" "${UCGLIB}*.h" "${UCG_CALLBACK}*.c" "${UCG_CALLBACK}*.h")
endif()

# get all the sources.
file(GLOB PROJECT_SRC CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR})
MESSAGE(${PROJECT_SRC})

# define our elf file
add_executable(${PROJECT_NAME}.elf
        ${PROJECT_SRC})

#### Uncomment this to see flashing process details
#set(FLASH_VERBOSE_FLAG "-v")
add_custom_target(FLASH_${PROJECT_NAME}
    ${AVR_DUDE_EXECUTABLE} -p x256a3u -P usb -c avrispmkII -b115200  ${FLASH_VERBOSE_FLAG} -U flash:w:${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf:a
    DEPENDS ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf
)

不幸的是,这个魔术有点令人失望。如果程序很小,它编译得很好。然后我添加了ucg lib(来自olikraus)。现在flash文件比芯片的flash(atxmega 256 a3 u)大。所以显然包含所有代码的flash文件都包括在内(大约1.3 MB)。
我在网上发现我应该添加编译器开关

add_compile_options(-fdata-sections)
add_compile_options(-ffunction-sections)

而在连接器部分

add_link_options(-Wl,--gc-sections)

现在我的flash文件被缩减为24字节的文本。我认为这还不够。
我进行了一个较小的测试(使用一些SPI函数进行 Flink ),并添加了verbose,看看结果如何

"C:\Program Files\JetBrains\CLion 2022.2.3\bin\cmake\win\bin\cmake.exe" --build D:\vsavr8\start_voorbeeld\cmake-build-debug --target blink.elf -- -j 6
Consolidate compiler generated dependencies of target blink.elf
[ 33%] Building C object blink/CMakeFiles/blink.elf.dir/blink.c.obj
Using built-in specs.
Reading specs from d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/device-specs/specs-avr2
COLLECT_GCC=d:\vsavr8\gcc\bin\avr-gcc.exe
Target: avr
Configured with: ../configure --prefix=/opt/avr-gcc-mingw32 --target=avr --enable-languages=c,c++ --disable-nls --disable-libssp --with-dwarf2 --host=x86_64-w64-mingw32 --build=x86_64-pc-linux-gnu : (reconfigured) ../configure --prefix=/opt/avr-gcc-mingw32 --target=avr --host=x86_64-w64-mingw32 --build=x86_64-pc-linux-gnu --enable-languages=c,c++ --disable-nls --disable-libssp --with-dwarf2 --with-newlib --disable-__cxa_atexit --disable-threads --disable-shared --enable-static --disable-sjlj-exceptions --enable-libstdcxx --enable-lto --disable-hosted-libstdcxx
Thread model: single
gcc version 9.2.0 (GCC) 
COLLECT_GCC_OPTIONS='-D' '__AVR_ATxmega256A3U__' '-I' 'D:\vsavr8\start_voorbeeld\blink\..\spi' '-g' '-O3' '-fdata-sections' '-ffunction-sections' '-fpack-struct' '-fshort-enums' '-Wall' '-Werror' '-funsigned-char' '-funsigned-bitfields' '-c' '-v' '-MD' '-MT' 'blink/CMakeFiles/blink.elf.dir/blink.c.obj' '-MF' 'CMakeFiles\blink.elf.dir\blink.c.obj.d' '-o' 'CMakeFiles\blink.elf.dir\blink.c.obj' '-c' '-specs=device-specs/specs-avr2'
 d:/vsavr8/gcc/bin/../libexec/gcc/avr/9.2.0/cc1.exe -quiet -v -I D:\vsavr8\start_voorbeeld\blink\..\spi -iprefix d:\vsavr8\gcc\bin\../lib/gcc/avr/9.2.0/ -MD CMakeFiles\blink.elf.dir\blink.c.d -MF CMakeFiles\blink.elf.dir\blink.c.obj.d -MT blink/CMakeFiles/blink.elf.dir/blink.c.obj -D __AVR_ATxmega256A3U__ D:\vsavr8\start_voorbeeld\blink\blink.c -mn-flash=6 -mskip-bug -quiet -dumpbase blink.c -auxbase-strip CMakeFiles\blink.elf.dir\blink.c.obj -g -O3 -Wall -Werror -version -fdata-sections -ffunction-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -o C:\Users\NICOVE~1\AppData\Local\Temp\ccyLTv7f.s
GNU C17 (GCC) version 9.2.0 (avr)
    compiled by GNU C version 7.3-win32 20180312, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "d:\vsavr8\gcc\bin\../lib/gcc/avr/9.2.0/../../../../avr/sys-include"
ignoring duplicate directory "d:/vsavr8/gcc/lib/gcc/../../lib/gcc/avr/9.2.0/include"
ignoring duplicate directory "d:/vsavr8/gcc/lib/gcc/../../lib/gcc/avr/9.2.0/include-fixed"
ignoring nonexistent directory "d:/vsavr8/gcc/lib/gcc/../../lib/gcc/avr/9.2.0/../../../../avr/sys-include"
ignoring duplicate directory "d:/vsavr8/gcc/lib/gcc/../../lib/gcc/avr/9.2.0/../../../../avr/include"
#include "..." search starts here:
#include <...> search starts here:
 D:\vsavr8\start_voorbeeld\blink\..\spi
 d:\vsavr8\gcc\bin\../lib/gcc/avr/9.2.0/include
 d:\vsavr8\gcc\bin\../lib/gcc/avr/9.2.0/include-fixed
 d:\vsavr8\gcc\bin\../lib/gcc/avr/9.2.0/../../../../avr/include
End of search list.
GNU C17 (GCC) version 9.2.0 (avr)
    compiled by GNU C version 7.3-win32 20180312, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: cf45033fcb74fa02d7459bd3a612262e
COLLECT_GCC_OPTIONS='-D' '__AVR_ATxmega256A3U__' '-I' 'D:\vsavr8\start_voorbeeld\blink\..\spi' '-g' '-O3' '-fdata-sections' '-ffunction-sections' '-fpack-struct' '-fshort-enums' '-Wall' '-Werror' '-funsigned-char' '-funsigned-bitfields' '-c' '-v' '-MD' '-MT' 'blink/CMakeFiles/blink.elf.dir/blink.c.obj' '-MF' 'CMakeFiles\blink.elf.dir\blink.c.obj.d' '-o' 'CMakeFiles\blink.elf.dir\blink.c.obj' '-c' '-specs=device-specs/specs-avr2'
 d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/as.exe -mmcu=avr2 -mgcc-isr -o CMakeFiles\blink.elf.dir\blink.c.obj C:\Users\NICOVE~1\AppData\Local\Temp\ccyLTv7f.s
COMPILER_PATH=d:/vsavr8/gcc/bin/../libexec/gcc/avr/9.2.0/;d:/vsavr8/gcc/bin/../libexec/gcc/;d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/
LIBRARY_PATH=d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/;d:/vsavr8/gcc/bin/../lib/gcc/;d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/lib/
COLLECT_GCC_OPTIONS='-D' '__AVR_ATxmega256A3U__' '-I' 'D:\vsavr8\start_voorbeeld\blink\..\spi' '-g' '-O3' '-fdata-sections' '-ffunction-sections' '-fpack-struct' '-fshort-enums' '-Wall' '-Werror' '-funsigned-char' '-funsigned-bitfields' '-c' '-v' '-MD' '-MT' 'blink/CMakeFiles/blink.elf.dir/blink.c.obj' '-MF' 'CMakeFiles\blink.elf.dir\blink.c.obj.d' '-o' 'CMakeFiles\blink.elf.dir\blink.c.obj' '-c' '-specs=device-specs/specs-avr2'
[ 66%] Linking C executable blink.elf
Memory region         Used Size  Region Size  %age Used
            text:          24 B         8 KB      0.29%
            data:          0 GB      65440 B      0.00%
          eeprom:          0 GB        64 KB      0.00%
            fuse:          0 GB         1 KB      0.00%
            lock:          0 GB         1 KB      0.00%
       signature:          0 GB         1 KB      0.00%
 user_signatures:          0 GB         1 KB      0.00%
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.text.spi_init' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.text.spi_transfer' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.text.spi_write' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.text.spi_read' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_DBLCLK_MASK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_SPEED_MASK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_MODE_MASK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_MASTER_MASK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_LSBFIRST_MASK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_SCK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_MISO' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_MOSI' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_info' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_abbrev' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_loc' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_aranges' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_ranges' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_line' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_str' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.comment' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_frame' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.text.startup.main' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_info' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_abbrev' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_loc' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_aranges' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_ranges' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_line' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_str' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.comment' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_frame' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
[100%] Built target blink.elf

Build finished

最后但并非最不重要的是我的示例代码:
blink.c

/**
 * @file blink.c
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2023-03-29
 *
 * @copyright Copyright (c) 2023
 *
 */
#define  F_CPU 2000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <spi.h>

/**
 * @brief
 * @return int
 */
int main() {

  spi_init();

  uint8_t x = 0;;
  spi_write(x);

  PORTC.DIRSET = PIN0_bm;       // bit 0 port C is set, it is an output

  while (1) {
    PORTC.OUTSET = PIN0_bm;     // bit 0 port C is high, led is on
    _delay_ms (500);
    PORTC.OUTCLR = PIN0_bm;     // bit 0 port C is low, led is off
    _delay_ms (950);
  }
}

spi.h和spi.c位于与blink并行的目录中(称为spi)
spi.h

#ifndef __SPI_H
#define __SPI_H

#include <inttypes.h>

#define SPI_SS_bm   0x10
#define SPI_MOSI_bm 0x20
#define SPI_MISO_bm 0x40
#define SPI_SCK_bm  0x80

#define FOO         0x00

// prototypes
void    spi_init(void);                   // init spi
uint8_t spi_transfer(uint8_t data);       // transfer data to slave
void    spi_write(uint8_t data);          // write (register?)
uint8_t spi_read(void);                   // read spi slave

#endif

spi.c

#include <inttypes.h>
#include <avr/io.h>
#include <spi_pins.h>
#include <spi.h>

// SPI on port D
#define __SPI_PORT PORTD
#define __SPI_DDR POR
const uint8_t __SPI_MOSI = 5;
const uint8_t __SPI_MISO = 6;
const uint8_t __SPI_SCK = 7;
const uint8_t __SPI_LSBFIRST_MASK = 0x01;
const uint8_t __SPI_MASTER_MASK = 0x01;
const uint8_t __SPI_MODE_MASK = 0x03;
const uint8_t __SPI_SPEED_MASK = 0x03;
const uint8_t __SPI_DBLCLK_MASK = 0x01;

//initialize the SPI bus
//  uint8_t lsbfirst - if 0: most significant bit is transmitted first
//  uint8_t master - if 1: use master mode, if 0: slave mode is used
//  uint8_t mode - sets the transfer mode:
//                 mode   leading clock edge   trailing clock edge
//                 -----------------------------------------------
//                 0      sample (rising)      setup  (falling)
//                 1      setup  (rising)      sample (falling)
//                 2      sample (falling)     setup  (rising)
//                 3      setup  (falling)     sample (rising)
//  uint8_t clkrate - spi bus clock rate, valid speeds are 0-3
//                    rate   speed
//                    ------------
//                    0      CPUCLK/4
//                    1      CPUCLK/16
//                    2      CPUCLK/64
//                    3      CPUCLK/128
//  uint8_t dblclk - if 1: doubles the SPI clock rate in master mode
//  EXAMPLE: spi_init(0, 1, 0, 3, 0)
void spi_init(void ) {

  // set IO ports
  PORTD.DIRSET = 1 << TFT_SCK | 1 << TFT_MOSI | 1 << TFT_CS;
  PORTD.DIRCLR = 1 << TFT_MISO;

  // deselect CS
  PORTD.OUTSET = 1 << TFT_CS;

  SPID.CTRL = SPI_ENABLE_bm |   // enable SPI
              SPI_MASTER_bm |   // Act as MAster
              SPI_CLK2X_bm  |   // double clock speed
              SPI_DORD_bm   |   // MSB first
              SPI_MODE_0_gc |   // SPI mode 0
              SPI_PRESCALER_DIV4_gc; // prescaling 4

}

/**
 * Transfer data over SPI
 * @param data
 * @return
 */
uint8_t spi_transfer(uint8_t data) {
  SPID.DATA = data;                       // fill SPI data register
  while (!(SPID.STATUS & (SPI_IF_bm)));   // wait until transferred
  return SPIC.DATA;                       // return sent data
}

/**
 * write data but do chip select first and deselect when sent
 * @param data
 */
void spi_write(uint8_t data) {
  PORTD.OUTCLR = 1 << TFT_CS;
  spi_transfer(data);
  PORTD.OUTSET = 1 << TFT_CS;
}

uint8_t spi_read(void){
  uint8_t data;

  PORTD.OUTCLR = 1 << TFT_CS;
  data = spi_transfer(FOO);
  PORTD.OUTSET = 1 << TFT_CS;

  return data;
}

这个概念看起来很好,允许学生在每个主题上创建目录,然后在每个作业上创建子目录。通过使用附加库创建通用的cmake,他们可以专注于实际的编程,而不会被环境中复杂的东西所干扰。我们正在谈论的学生中,有些人刚刚开始学习编程。
所有的帮助将不胜感激问候尼科

更正的文件从@Tsyvarev输入后,文件现在如下:
CMakeLists.txt

#
# @file     CMakeLists.txt
# @brief    Generic CMakeFile for ATXMega in VSCode and CLion
# @author   Nico Verduin
# @date     6-4-3-2023
#

cmake_minimum_required(VERSION 3.12)
set(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)

# get our avr toolchain lo ation
include(file_locations.cmake)

# CPU to build for
set(TARGET_CPU ATxmega256A3U)

# our compilers
set (CMAKE_C_COMPILER ${COMPILE_PATH}avr-gcc.exe )
set (CMAKE_CXX_COMPILER ${COMPILE_PATH}avr-g++.exe )
set (AVR_SIZE ${COMPILE_PATH}avr-size.exe )
set (AVR_OBJCOPY ${COMPILE_PATH}avr-objcopy.exe )

#check if we can find the compilers
include(CMakeVerifyCompiler.cmake)

# ser our compiler and link options
add_compile_definitions("__AVR_${TARGET_CPU}__")
add_compile_options("-Os")
add_compile_options(-fdata-sections)
add_compile_options(-ffunction-sections)
add_compile_options("-fpack-struct")
add_compile_options("-fshort-enums")
add_compile_options("-Wall")
add_compile_options("-Werror")
add_compile_options("-funsigned-char")
add_compile_options("-funsigned-bitfields")
add_compile_options("-mmcu=${TARGET_CPU}")
add_compile_options("-c")
add_link_options(-Wl,--gc-sections)
add_link_options(-mmcu=${TARGET_CPU})

# create our root project name
get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})

# this line is needed almost at the end of this CMakeLists.txt
project(start_voorbeeld CXX C NONE)

# add our sub projects
add_subdirectory(example_assignment)
add_subdirectory(blink)
add_subdirectory(ucg_test)

generic.cmake

#
# @file     generic.cmake
# @brief    Generic CMakeFile for ATXMega in VSCode and CLion
#           Needs to be imported into the root of the individual
#           sub projects
# @author   Nico Verduin
# @date     6-4-2023
#

# give the project the root folder name
cmake_path(GET CMAKE_CURRENT_SOURCE_DIR FILENAME PROJECT_NAME)

string(REPLACE " " "_" ProjectId ${PROJECT_NAME})
project(${PROJECT_NAME} C CXX NONE)

# additional optional libraries
# these are switched ON in the  CMakeLists.txt of a subdirectory
if(USE_SPILIB)
    set (SPILIB         "../spi/")
    include_directories(${SPILIB})
endif()

if(USE_UCGLIB)
    set (UCGLIB         "../ucglib/csrc/")
    set (UCG_CALLBACK   "../ucglib/callback/")
    include_directories(${UCGLIB})
    include_directories(${UCG_CALLBACK})
endif()

add_link_options("-Wl,--Map=${PROJECT_NAME}.map")

# if you want to program in C++ or assembly that option is also added
# just the standard folders in the root
set(PROJECT_SOURCE_DIR RECURSE "*.c" "*.h" "*.cpp" "*.hpp" "*.s" )

# add additional library source folders. Keep in mind that it does not look in lower
# directories
if (USE_SPILIB)
    list( APPEND  PROJECT_SOURCE_DIR "${SPILIB}*.c" "${SPILIB}*.h")
endif()

if (USE_UCGLIB)
    list( APPEND PROJECT_SOURCE_DIR "${UCGLIB}*.c" "${UCGLIB}*.h" "${UCG_CALLBACK}*.c" "${UCG_CALLBACK}*.h")
endif()

# get all the sources. including thous from sub directories
file(GLOB_RECURSE PROJECT_SRC CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR})

# Set to 1 in local CmakeLists.txt and will generate lots of output
if (VERBOSE)
    # print the memory used in the elf file. A bit useless as it contains
    # lots of info not flashed to the chip
    add_link_options(-Wl,--print-memory-usage)

    # outputs all the parts of .data and .text (mostly defined as .rodata)
    # that are remove due to --gc-sections option
    add_link_options(-Wl,--print-gc-sections)

    # show in detail every compile step
    add_compile_options("-v")

    # set verbose on during flash
    set(FLASH_VERBOSE_FLAG "-v")
endif()

# create our elf file
add_executable(${PROJECT_NAME}.elf
        ${PROJECT_SRC}
        )

# Clean up unused and info code y removing DEBUG info etc
add_custom_command(
        TARGET ${PROJECT_NAME}.elf
        POST_BUILD
        COMMAND ${AVR_OBJCOPY} --strip-all ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf
        # and show the size of our program. Change the -A to -B to get a one line size format
        # has no impact on execution
        COMMAND ${AVR_SIZE} -A ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf

)

add_custom_target(${PROJECT_NAME}_FLASH
        ${AVR_DUDE_EXECUTABLE} -p x256a3u -P usb -c avrispmkII -b115200  ${FLASH_VERBOSE_FLAG} -U flash:w:${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf:a
        DEPENDS ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf
)

本地CMakeLists.txt

#
# @file     CMakeLists.txt
# @brief    root CMakeList.txt for sub projects
# @author   Nico Verduin
# @date     29-3-2023
#

# set optional used libraries
set (USE_SPILIB 1)
set (USE_UCGLIB 1)

# If you want to see lots of verbose output from the compilers set VERBOSE to 1
set (VERBOSE)

# do not change this line
include(../generic.cmake)
wdebmtf2

wdebmtf21#

这里有很多(潜在的)问题...让我们来看看gcc的-v babbling。不幸的是,我们没有看到生成make的命令。

不要-D __AVR_ATxmega256A3U__

这个定义只是avr-gcc支持ATxmega 256 A3 U的一小部分。相反,在avr-gcc / avr-g++的所有调用(编译,汇编和链接)中使用-mmcu=atxmega256a3u。丢弃-D __AVR_<device>__,它将来自设备规范文件。
您(无意中)编译了设备系列avr2,而不是单个设备。结果是没有启动代码被链接,因此没有调用main,因此--gc-sections将丢弃下面的所有内容,包括main。同样,修复是-mmcu=atxmega256a3u
当您检查-v的输出并发现除-mmcu=atxmega256a3u-mmcu=avrxmega6之外的任何内容时,您在make过程或选项处理中有错误。

blink.c的编译在哪里?blink.elf的链接在哪里?

没有一个调用显示blink.c的编译。这可能是由于make的特性,当目标比依赖项旧时才(重新)编译。为了完整的编译和验证所有步骤,最好在make clean之后发布-v的输出。
此外,-v不包含从对象文件blink.c.obj构建blink.elf的链接器调用。由于后者比前者更新,make应该发出一个命令来链接blink.elf。所以你的cmake配置有问题吗?

spi.c在哪里处理?

SPI模块也是如此:没有编译,没有链接。main使用SPI,但你不会从链接器得到任何“未定义引用”错误,因为所有代码都是死的,无论如何(因为没有引用main)。

“现在闪存文件比芯片的闪存还大。”

这里可能有三个问题:

  • 您有效地编译了-mmcu=avr2,因此任何地方都没有ATxmega 256 A3 U的设备属性。
  • 您正在使用-O3,它展开循环并尝试内联函数,无论代码大小增加多少。尽可能使用-Os或至少-O2
  • 您正在使用的v9受到PR90706的影响。此PR可能会导致10%或更多的代码膨胀,具体取决于代码。如果可能,请避免从v9到v12.2的任何版本。PR 90706在v12.3+中得到修复。v8和更低版本不受此PR的影响。请注意,迄今为止,v12.3和v13都没有发布。
    无关,但以防万一:
  • GCC不支持在源代码树中进行配置。最好使用GCC源代码树外部的构建目录。
  • 你使用了avr-gcc不支持的--with-newlib。唯一支持的libc实现是AVR-LibC
n3ipq98p

n3ipq98p2#

我把仓库up here .这是目前最新的版本.
使用VSCode和CLion测试
尼科

相关问题