#3 Xilinx µB example with the silly bare metal API

已合并
basiliscos 3 年之前 将 2 次代码提交从 am/mb合并至 basiliscos/master

+ 2 - 0
README.md

@@ -35,11 +35,13 @@ care about thread-safety.
 |:--------------:|:---------------:|:--------------:
 | host (1)       | ~48.7M          | ~26kb
 | Arduino Uno R3 | ~5.2K           | ~9kb
+| Microblaze (2) | ~58.8K          | ~42kb
 
 All examples can be measured with `examples/ping-pong-throughput.cpp`,
 compiled with `CMAKE_BUILD_TYPE=MinSizeRel` and the stripped
 
 (1) Setup: Intel Core i7-8550U, Void Linux 5.15.
+(2) Zynq xc7z020clg400-1, QMTECH development board. Microblaze standard config, hw mul/div instr. enabled, clocking is 50Mhz.
 
 ## license
 

+ 2 - 0
examples/CMakeLists.txt

@@ -6,6 +6,8 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AVR")
     add_subdirectory("atmega328p")
 elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "Cortex-M7")
     add_subdirectory("NUCLEO-H743ZI2")
+elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "MICROBLAZE")
+    add_subdirectory("mb")
 elseif ("${TOOLCHAIN_PREFIX}" STREQUAL "")
     add_subdirectory("host")
 endif()

+ 35 - 0
examples/mb/CMakeLists.txt

@@ -0,0 +1,35 @@
+# Example:
+# cmake -DLIBSTDCPP_HOME=/path/to/avr-libstdcpp -DCMAKE_TOOLCHAIN_FILE=../examples/mb/toolchain.cmake -DCMAKE_BUILD_TYPE=MinSizeRel
+# -DXIL_STANDALONE_BSP_INCLUDE=/path/to/bspinclude/include -DXIL_STANDALONE_BSP_LIB=/path/to/bsplib/lib -DCMAKE_CXX_COMPILER_AR=mb-ar
+# -DCMAKE_CXX_COMPILER_RANLIB=mb-ranlib  ..
+
+cmake_minimum_required(VERSION 3.8)
+cmake_policy(SET CMP0069 NEW)
+
+include(CheckIPOSupported)
+check_ipo_supported(RESULT supported OUTPUT error)
+if( supported )
+    message(STATUS "IPO / LTO enabled for the microblaze builds")
+    set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+else()
+    message(STATUS "IPO / LTO not supported: <${error}>")
+endif()
+
+if (NOT ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "MICROBLAZE" ))
+  message(FATAL_ERROR "wrong system processor ${CMAKE_SYSTEM_PROCESSOR}, expected: MICROBLAZE")
+endif()
+
+message(STATUS "will use stdlib++ from '${LIBSTDCPP_HOME}'")
+add_library(microblaze common.cpp)
+
+target_include_directories(rotor_light PUBLIC "${LIBSTDCPP_HOME}/include")
+
+target_include_directories(microblaze PUBLIC "${LIBSTDCPP_HOME}/include")
+target_link_libraries(microblaze rotor_light)
+
+
+add_executable(blink-led blink-led.cpp)
+target_link_libraries(blink-led microblaze)
+
+add_executable(ping-pong-poll ping-pong-poll.cpp)
+target_link_libraries(ping-pong-poll microblaze)

+ 91 - 0
examples/mb/blink-led.cpp

@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: 2022 Aliaksei Makarau
+
+#include "common.h"
+#include "rotor-light.hpp"
+
+#include "xparameters.h"
+#include "xgpio.h"
+
+#define GPIO_OUTPUT_DEVICE_ID	XPAR_GPIO_0_DEVICE_ID
+#define LED_CHANNEL           1
+
+namespace rl = rotor_light;
+
+namespace message {
+
+struct BlinkCommand: rl::Message {
+  static constexpr auto type_id = __LINE__;
+  using rl::Message::Message;
+  rl::MessageTypeId get_type_id() const override { return type_id; }
+};
+
+} // namespace message
+
+XGpio xil_gpio;
+uint32_t gpio_flag = 0xFFFF;
+
+struct Blinker : rl::Actor<2> {
+  using Parent = Actor<2>;
+
+  void initialize() override {
+    subscribe(&Blinker::on_blink_command);
+    Parent::initialize();
+  }
+
+  void advance_start() override {
+    Parent::advance_start();
+    add_event(delay, [](void *data) { static_cast<Blinker *>(data)->blink(); }, this);
+  }
+
+  void blink() {
+    XGpio_Out32(xil_gpio.BaseAddress + XGPIO_DATA_OFFSET, gpio_flag);
+    gpio_flag ^= 0xFFFF;
+    add_event(delay, [](void *data) { static_cast<Blinker *>(data)->blink(); }, this);
+  }
+
+  void on_blink_command(message::BlinkCommand &msg) {
+    blink();
+  }
+
+  rl::Duration delay;
+};
+
+static void app_hw_init();
+
+using Supervisor =
+    rl::Supervisor<rl::SupervisorBase::min_handlers_amount, Blinker>;
+using Storage =
+    rl::traits::MessageStorage<rl::message::ChangeState,
+                               rl::message::ChangeStateAck,
+                               message::BlinkCommand>;
+using Queue = rl::Queue<Storage, 5>; /* upto 5 messages in 1 queue */
+using Planner = rl::Planner<2>;      /* upto 2 time events */
+
+Queue queue;
+Planner planner;
+rl::Context context{&queue, &planner, &get_now};
+Supervisor sup;
+
+int main(int, char **) {
+  app_hw_init();
+
+  /* setup */
+  sup.bind(context);
+  auto blinker = sup.get_child<0>();
+  blinker->delay = rl::Duration{1};
+  /* let it polls timer */
+  sup.start(true);
+
+  /* main cycle */
+  sup.process();
+  return 0;
+}
+
+static void app_hw_init() {
+  XGpio_Initialize(&xil_gpio, GPIO_OUTPUT_DEVICE_ID);
+  XGpio_SetDataDirection(&xil_gpio, LED_CHANNEL, 0x0);
+
+	microblaze_enable_interrupts();
+  enable_timer();
+}

+ 70 - 0
examples/mb/common.cpp

@@ -0,0 +1,70 @@
+#include "common.h"
+
+#include "xparameters.h"
+#include "xtmrctr.h"
+#include "xintc.h"
+
+#define TMRCTR_DEVICE_ID    XPAR_TMRCTR_0_DEVICE_ID
+#define TMRCTR_BASEADDR     XPAR_TMRCTR_0_BASEADDR
+#define INTC_DEVICE_ID      XPAR_INTC_0_DEVICE_ID
+#define TMRCTR_INTERRUPT_ID XPAR_MICROBLAZE_0_AXI_INTC_AXI_TIMER_0_INTERRUPT_INTR
+#define TIMER_CNTR_0        0
+
+// reset after 1 sec
+#define RESET_VALUE	        (0xFFFFFFFF - XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ)
+
+XIntc InterruptController;
+XTmrCtr xil_timer;
+
+void TimerCounterHandler(void *CallBackRef, u8 TmrCtrNumber);
+
+std::uint64_t gpt_system_tick = 0;
+
+void adjust_timer(const rotor_light::Duration &value) {
+  gpt_system_tick += value;
+}
+
+// return seconds from the Big Start
+rl::TimePoint get_now() {
+  return gpt_system_tick;
+}
+
+void enable_timer() {
+  XTmrCtr_Initialize(&xil_timer, TMRCTR_DEVICE_ID);
+  XTmrCtr_SelfTest(&xil_timer, TIMER_CNTR_0);
+  XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+  XIntc_Connect(&InterruptController,
+                TMRCTR_INTERRUPT_ID,
+                (XInterruptHandler)XTmrCtr_InterruptHandler,
+                (void*) &xil_timer);
+
+  XIntc_Start(&InterruptController, XIN_REAL_MODE);
+
+  XIntc_Enable(&InterruptController, TMRCTR_INTERRUPT_ID);
+
+  Xil_ExceptionInit();
+  Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+                               (Xil_ExceptionHandler) XIntc_InterruptHandler,
+                               &InterruptController);
+  Xil_ExceptionEnable();
+
+  XTmrCtr_SetHandler(&xil_timer,
+                     TimerCounterHandler,
+                     &xil_timer);
+  XTmrCtr_SetOptions(&xil_timer,
+                      TIMER_CNTR_0,
+                      XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION);
+  XTmrCtr_SetResetValue(&xil_timer, TIMER_CNTR_0, RESET_VALUE);
+  XTmrCtr_Start(&xil_timer, TIMER_CNTR_0);
+}
+
+void disable_timer() {
+  XTmrCtr_Stop(&xil_timer, TIMER_CNTR_0);
+  XIntc_Disable(&InterruptController, TMRCTR_INTERRUPT_ID);
+}
+
+// on interrupt add 1 second
+void TimerCounterHandler(void *CallBackRef, u8 TmrCtrNumber)
+{
+  gpt_system_tick ++;
+}

+ 13 - 0
examples/mb/common.h

@@ -0,0 +1,13 @@
+#pragma once
+
+#include "rotor-light.hpp"
+
+namespace rl = rotor_light;
+
+rl::TimePoint get_now();
+
+void enable_timer();
+
+void disable_timer();
+
+void adjust_timer(const rl::Duration &);

+ 216 - 0
examples/mb/lscript.ld

@@ -0,0 +1,216 @@
+/*******************************************************************/
+/*                                                                 */
+/* This file is automatically generated by linker script generator.*/
+/*                                                                 */
+/* Version: 2018.3                                                 */
+/*                                                                 */
+/* Copyright (c) 2010-2019 Xilinx, Inc.  All rights reserved.      */
+/*                                                                 */
+/* Description : MicroBlaze Linker Script                           */
+/*                                                                 */
+/*******************************************************************/
+
+_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
+_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x800;
+
+/* Define Memories in the system */
+
+MEMORY
+{
+   microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem : ORIGIN = 0x50, LENGTH = 0x1FFB0
+}
+
+/* Specify the default entry point to the program */
+
+ENTRY(_start)
+
+/* Define the sections, and where they are mapped in memory */
+
+SECTIONS
+{
+.vectors.reset 0x0 : {
+   KEEP (*(.vectors.reset))
+} 
+
+.vectors.sw_exception 0x8 : {
+   KEEP (*(.vectors.sw_exception))
+} 
+
+.vectors.interrupt 0x10 : {
+   KEEP (*(.vectors.interrupt))
+} 
+
+.vectors.hw_exception 0x20 : {
+   KEEP (*(.vectors.hw_exception))
+} 
+
+.text : {
+   *(.text)
+   *(.text.*)
+   *(.gnu.linkonce.t.*)
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.note.gnu.build-id : {
+   KEEP (*(.note.gnu.build-id))
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.init : {
+   KEEP (*(.init))
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.fini : {
+   KEEP (*(.fini))
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.ctors : {
+   __CTOR_LIST__ = .;
+   ___CTORS_LIST___ = .;
+   KEEP (*crtbegin.o(.ctors))
+   KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
+   KEEP (*(SORT(.ctors.*)))
+   KEEP (*(.ctors))
+   __CTOR_END__ = .;
+   ___CTORS_END___ = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.dtors : {
+   __DTOR_LIST__ = .;
+   ___DTORS_LIST___ = .;
+   KEEP (*crtbegin.o(.dtors))
+   KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
+   KEEP (*(SORT(.dtors.*)))
+   KEEP (*(.dtors))
+   PROVIDE(__DTOR_END__ = .);
+   PROVIDE(___DTORS_END___ = .);
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.rodata : {
+   __rodata_start = .;
+   *(.rodata)
+   *(.rodata.*)
+   *(.gnu.linkonce.r.*)
+   __rodata_end = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.sdata2 : {
+   . = ALIGN(8);
+   __sdata2_start = .;
+   *(.sdata2)
+   *(.sdata2.*)
+   *(.gnu.linkonce.s2.*)
+   . = ALIGN(8);
+   __sdata2_end = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.sbss2 : {
+   __sbss2_start = .;
+   *(.sbss2)
+   *(.sbss2.*)
+   *(.gnu.linkonce.sb2.*)
+   __sbss2_end = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.data : {
+   . = ALIGN(4);
+   __data_start = .;
+   *(.data)
+   *(.data.*)
+   *(.gnu.linkonce.d.*)
+   __data_end = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.got : {
+   *(.got)
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.got1 : {
+   *(.got1)
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.got2 : {
+   *(.got2)
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.eh_frame : {
+   *(.eh_frame)
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.jcr : {
+   *(.jcr)
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.gcc_except_table : {
+   *(.gcc_except_table)
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.sdata : {
+   . = ALIGN(8);
+   __sdata_start = .;
+   *(.sdata)
+   *(.sdata.*)
+   *(.gnu.linkonce.s.*)
+   __sdata_end = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.sbss (NOLOAD) : {
+   . = ALIGN(4);
+   __sbss_start = .;
+   *(.sbss)
+   *(.sbss.*)
+   *(.gnu.linkonce.sb.*)
+   . = ALIGN(8);
+   __sbss_end = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.tdata : {
+   __tdata_start = .;
+   *(.tdata)
+   *(.tdata.*)
+   *(.gnu.linkonce.td.*)
+   __tdata_end = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.tbss : {
+   __tbss_start = .;
+   *(.tbss)
+   *(.tbss.*)
+   *(.gnu.linkonce.tb.*)
+   __tbss_end = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.bss (NOLOAD) : {
+   . = ALIGN(4);
+   __bss_start = .;
+   *(.bss)
+   *(.bss.*)
+   *(.gnu.linkonce.b.*)
+   *(COMMON)
+   . = ALIGN(4);
+   __bss_end = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
+
+_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
+
+/* Generate Stack and Heap definitions */
+
+.heap (NOLOAD) : {
+   . = ALIGN(8);
+   _heap = .;
+   _heap_start = .;
+   . += _HEAP_SIZE;
+   _heap_end = .;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+.stack (NOLOAD) : {
+   _stack_end = .;
+   . += _STACK_SIZE;
+   . = ALIGN(8);
+   _stack = .;
+   __stack = _stack;
+} > microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem
+
+_end = .;
+}
+

+ 114 - 0
examples/mb/ping-pong-poll.cpp

@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: 2022 Aliaksei Makarau
+
+#include "common.h"
+#include "rotor-light.hpp"
+
+#include "xparameters.h"
+#include "xgpio.h"
+
+#define GPIO_OUTPUT_DEVICE_ID	XPAR_GPIO_0_DEVICE_ID
+#define LED_CHANNEL           1
+
+namespace rl = rotor_light;
+
+namespace message {
+struct Ping : rl::Message {
+  using Message::Message;
+  static constexpr auto type_id = __LINE__;
+  rl::MessageTypeId get_type_id() const override { return type_id; }
+};
+
+struct Pong : rl::Message {
+  using Message::Message;
+  static constexpr auto type_id = __LINE__;
+  rl::MessageTypeId get_type_id() const override { return type_id; }
+};
+} // namespace message
+
+XGpio xil_gpio;
+uint32_t gpio_flag = 0xFFFF;
+
+struct Pinger : rl::Actor<2> {
+  using Parent = Actor<2>;
+
+  void initialize() override {
+    subscribe(&Pinger::on_pong);
+    Parent::initialize();
+  }
+
+  void advance_start() override {
+    Parent::advance_start();
+    ping();
+  }
+
+  void ping() {
+    /* toggle led */
+    XGpio_Out32(xil_gpio.BaseAddress + XGPIO_DATA_OFFSET, gpio_flag);
+    gpio_flag ^= 0xFFFF;
+    send<message::Ping>(0, ponger_id);
+  }
+
+  void on_pong(message::Pong &) {
+    add_event(
+        1, [](void *data) { static_cast<Pinger *>(data)->ping(); }, this);
+  }
+
+  rl::ActorId ponger_id;
+};
+
+struct Ponger : rl::Actor<2> {
+  using Parent = Actor<2>;
+
+  void initialize() override {
+    subscribe(&Ponger::on_ping);
+    Parent::initialize();
+  }
+  void on_ping(message::Ping &) {
+    //
+    send<message::Pong>(0, pinger_id);
+  }
+  rl::ActorId pinger_id;
+};
+
+using Supervisor =
+    rl::Supervisor<rl::SupervisorBase::min_handlers_amount, Pinger, Ponger>;
+using Storage = rl::traits::MessageStorage<rl::message::ChangeState,
+                                           rl::message::ChangeStateAck,
+                                           message::Ping, message::Pong>;
+using Queue = rl::Queue<Storage, 5>; /* upto 5 messages in 1 queue */
+using Planner = rl::Planner<1>;      /* upto 1 time event */
+
+static void app_hw_init();
+
+/* allocate */
+Queue queue;
+Planner planner;
+rl::Context context{&queue, &planner, &get_now};
+Supervisor sup;
+
+int main(int, char **) {
+
+  app_hw_init();
+
+  /* setup */
+  sup.bind(context);
+  auto pinger = sup.get_child<0>();
+  auto ponger = sup.get_child<1>();
+  pinger->ponger_id = ponger->get_id();
+  ponger->pinger_id = pinger->get_id();
+  /* let it polls timer */
+  sup.start(true);
+
+  /* main cycle */
+  sup.process();
+  return 0;
+}
+
+static void app_hw_init() {
+  XGpio_Initialize(&xil_gpio, GPIO_OUTPUT_DEVICE_ID);
+  XGpio_SetDataDirection(&xil_gpio, LED_CHANNEL, 0x0);
+
+	microblaze_enable_interrupts();
+  enable_timer();
+}

+ 65 - 0
examples/mb/toolchain.cmake

@@ -0,0 +1,65 @@
+set(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_SYSTEM_PROCESSOR MICROBLAZE)
+
+if(MINGW OR CYGWIN OR WIN32)
+    set(UTIL_SEARCH_CMD where)
+elseif(UNIX OR APPLE)
+    set(UTIL_SEARCH_CMD which)
+endif()
+
+set(TOOLCHAIN_PREFIX mb-)
+
+execute_process(
+  COMMAND ${UTIL_SEARCH_CMD} ${TOOLCHAIN_PREFIX}gcc
+  OUTPUT_VARIABLE BINUTILS_PATH
+  OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+get_filename_component(XIL_TOOLCHAIN_DIR ${BINUTILS_PATH} DIRECTORY)
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+
+set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
+set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
+set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
+
+set(CMAKE_OBJCOPY ${XIL_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}objcopy CACHE INTERNAL "objcopy tool")
+set(CMAKE_SIZE_UTIL ${XIL_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}size CACHE INTERNAL "size tool")
+
+set(CMAKE_FIND_ROOT_PATH ${BINUTILS_PATH})
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+add_compile_options("-Wall"
+  "-I${XIL_STANDALONE_BSP_INCLUDE}"
+  "-fmessage-length=0"
+  "-mno-xl-reorder"
+  "-mlittle-endian"
+  "-mxl-barrel-shift"
+  "-mxl-pattern-compare"
+  "-mcpu=v11.0"
+  "-mno-xl-soft-mul"
+  "-mhard-float"
+  "-mno-xl-soft-div"
+  "-Wl,--no-relax"
+  "-ffunction-sections"
+  "-fdata-sections"
+  "-MMD"
+  "-MP"
+)
+
+add_link_options(
+  "-L${XIL_STANDALONE_BSP_LIB}"
+  "-Wl,-T"
+  "-Wl,${CMAKE_CURRENT_LIST_DIR}/lscript.ld"
+  "-mlittle-endian"
+  "-mxl-barrel-shift"
+  "-mxl-pattern-compare"
+  "-mcpu=v11.0"
+  "-mno-xl-soft-mul"
+  "-mhard-float"
+  "-mno-xl-soft-div"
+  "-Wl,-no-relax"
+  "-Wl,--gc-sections"
+  "-Wl,--start-group,-lxil,-lgcc,-lc,-lstdc++,--end-group"
+)

+ 0 - 0
examples/ping-pong-throughput.cpp


部分文件因为文件数量过多而无法显示