5 次代碼提交 06cdab196b ... 00c53f8127

作者 SHA1 備註 提交日期
  basiliscos 00c53f8127 Merge branch 'mb' of am/cpp-rotor-light into master 2 年之前
  Aliaksei Makarau aae79fe3aa Update to use the board.h/.cpp 2 年之前
  Ivan Baidakou d5e0501a7a update stm32 info 2 年之前
  basiliscos 9d83da6a38 Merge branch 'nucleoH743_throughput' of korifey/cpp-rotor-light into master 2 年之前
  Andrey Nikolaev 5b1a4332d1 throughput example 2 年之前

+ 1 - 1
README.md

@@ -33,9 +33,9 @@ care about thread-safety.
 |                       | messages/second | binary size
 |:---------------------:|:---------------:|:--------------:
 | host (1)              | ~47.7M          | 13026 bytes
+| STM32-H743ZI          | ~2.3M           | 14330 bytes
 | Arduino Uno R3        | ~10.0K          | 8872 bytes
 | xilinx microblaze (2) | ~58.8K          | 42868 byes
-| STM32-H743ZI          |  ...            | 13724 bytes
 
 All examples can be measured with `examples/ping-pong-throughput.cpp`,
 compiled with `CMAKE_BUILD_TYPE=MinSizeRel` and the stripped

+ 5 - 0
examples/CMakeLists.txt

@@ -19,3 +19,8 @@ add_executable(ping-pong-throughput ping-pong-throughput.cpp)
 target_link_libraries(ping-pong-throughput board)
 add_custom_command(TARGET ping-pong-throughput
     POST_BUILD COMMAND ${CMAKE_SIZE_UTIL} ping-pong-throughput)
+
+if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "Cortex-M7")
+    set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/NUCLEO-H743ZI2/STM32H743ZITx_FLASH.ld)
+    target_link_options(ping-pong-throughput PUBLIC -T ${LINKER_SCRIPT})
+endif()

+ 11 - 1
examples/NUCLEO-H743ZI2/board.cpp

@@ -18,6 +18,13 @@ void Board::init_start() {
   /* Configure the system clock */
   SystemClock_Config();
   MX_GPIO_Init();
+
+    /* Enable I-Cache---------------------------------------------------------*/
+    SCB_EnableICache();
+
+    /* Enable D-Cache---------------------------------------------------------*/
+    SCB_EnableDCache();
+
 }
 
 void Board::enable_interrupts() {}
@@ -28,4 +35,7 @@ rl::TimePoint Board::get_now() { return get_current_time(); }
 
 void Board::toggle_led() { LL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin); }
 
-void Board::delay() {}
+void Board::delay() {
+    auto end = get_current_time() + 1000;
+    while (get_current_time() < end);
+}

+ 1 - 1
examples/NUCLEO-H743ZI2/ping-pong-poll.cpp

@@ -39,7 +39,7 @@ struct Pinger : rl::Actor<2> {
 
   void on_pong(message::Pong &) {
     add_event(
-        500000, [](void *data) { static_cast<Pinger *>(data)->ping(); }, this);
+        500, [](void *data) { static_cast<Pinger *>(data)->ping(); }, this);
   }
 
   rl::ActorId ponger_id;

+ 5 - 7
examples/mb/CMakeLists.txt

@@ -20,16 +20,14 @@ if (NOT ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "MICROBLAZE" ))
 endif()
 
 message(STATUS "will use stdlib++ from '${LIBSTDCPP_HOME}'")
-add_library(microblaze common.cpp)
+add_library(board board.cpp)
 
 target_include_directories(rotor_light PUBLIC "${LIBSTDCPP_HOME}/include")
-
-target_include_directories(microblaze PUBLIC "${LIBSTDCPP_HOME}/include")
-target_link_libraries(microblaze rotor_light)
-
+target_include_directories(board PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
+target_link_libraries(board rotor_light)
 
 add_executable(blink-led blink-led.cpp)
-target_link_libraries(blink-led microblaze)
+target_link_libraries(blink-led board)
 
 add_executable(ping-pong-poll ping-pong-poll.cpp)
-target_link_libraries(ping-pong-poll microblaze)
+target_link_libraries(ping-pong-poll board)

+ 25 - 39
examples/mb/blink-led.cpp

@@ -1,20 +1,14 @@
 // 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
+#include "board.h"
+#include <rotor-light.hpp>
 
 namespace rl = rotor_light;
 
 namespace message {
 
-struct BlinkCommand: rl::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; }
@@ -22,9 +16,6 @@ struct BlinkCommand: rl::Message {
 
 } // namespace message
 
-XGpio xil_gpio;
-uint32_t gpio_flag = 0xFFFF;
-
 struct Blinker : rl::Actor<2> {
   using Parent = Actor<2>;
 
@@ -35,43 +26,46 @@ struct Blinker : rl::Actor<2> {
 
   void advance_start() override {
     Parent::advance_start();
-    add_event(delay, [](void *data) { static_cast<Blinker *>(data)->blink(); }, this);
+    blink();
   }
 
   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);
+    Board::toggle_led();
+    add_event(
+        delay,
+        [](void *data) {
+          auto self = static_cast<Blinker *>(data);
+          self->send<message::BlinkCommand>(0, self->id);
+        },
+        this);
   }
 
-  void on_blink_command(message::BlinkCommand &msg) {
-    blink();
-  }
+  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 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 */
+using Supervisor =
+    rl::Supervisor<rl::SupervisorBase::min_handlers_amount, Blinker>;
 
-Queue queue;
-Planner planner;
-rl::Context context{&queue, &planner, &get_now};
 Supervisor sup;
 
 int main(int, char **) {
-  app_hw_init();
+  Board::init_start();
+  Board::enable_timer();
+  Board::enable_interrupts();
 
   /* setup */
+  Queue queue;
+  Planner planner;
+  rl::Context context{&queue, &planner, &Board::get_now};
   sup.bind(context);
+
   auto blinker = sup.get_child<0>();
   blinker->delay = rl::Duration{1};
   /* let it polls timer */
@@ -81,11 +75,3 @@ int main(int, char **) {
   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();
-}

+ 46 - 20
examples/mb/common.cpp

@@ -1,52 +1,53 @@
-#include "common.h"
+#include "board.h"
+#include <string.h>
 
 #include "xparameters.h"
 #include "xtmrctr.h"
 #include "xintc.h"
+#include "xgpio.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
+#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
+#define GPIO_OUTPUT_DEVICE_ID	XPAR_GPIO_0_DEVICE_ID
+#define LED_CHANNEL           1
 
 // reset after 1 sec
-#define RESET_VALUE	        (0xFFFFFFFF - XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ)
+#define RESET_VALUE	          (0xFFFFFFFF - XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ)
 
 XIntc InterruptController;
 XTmrCtr xil_timer;
+XGpio GpioOutput;
 
 void TimerCounterHandler(void *CallBackRef, u8 TmrCtrNumber);
 
+static uint32_t gpio_flag = 0xFFFF;
 std::uint64_t gpt_system_tick = 0;
 
-void adjust_timer(const rotor_light::Duration &value) {
-  gpt_system_tick += value;
+void Board::toggle_led() {
+  XGpio_Out32(GpioOutput.BaseAddress + XGPIO_DATA_OFFSET, gpio_flag);
+  gpio_flag ^= 0xFFFF;
 }
 
-// return seconds from the Big Start
-rl::TimePoint get_now() {
-  return gpt_system_tick;
-}
+void Board::init_start() {
+  XGpio_Initialize(&GpioOutput, GPIO_OUTPUT_DEVICE_ID);
+  XGpio_SetDataDirection(&GpioOutput, LED_CHANNEL, 0x0);
 
-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,
@@ -55,14 +56,39 @@ void enable_timer() {
                       TIMER_CNTR_0,
                       XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION);
   XTmrCtr_SetResetValue(&xil_timer, TIMER_CNTR_0, RESET_VALUE);
+}
+
+void Board::enable_interrupts() {
+	microblaze_enable_interrupts();
+
+  XIntc_Start(&InterruptController, XIN_REAL_MODE);
+  XIntc_Enable(&InterruptController, TMRCTR_INTERRUPT_ID);
+  Xil_ExceptionEnable();
+}
+
+void Board::disable_interrupts() {
+	microblaze_disable_interrupts();
+}
+
+void Board::enable_timer() {
   XTmrCtr_Start(&xil_timer, TIMER_CNTR_0);
 }
 
-void disable_timer() {
+void Board::disable_timer() {
   XTmrCtr_Stop(&xil_timer, TIMER_CNTR_0);
   XIntc_Disable(&InterruptController, TMRCTR_INTERRUPT_ID);
 }
 
+rl::TimePoint Board::get_now() {
+  return gpt_system_tick;
+}
+
+void adjust_timer(const rotor_light::Duration &value) {
+  gpt_system_tick += value;
+}
+
+void Board::delay() {}
+
 // on interrupt add 1 second
 void TimerCounterHandler(void *CallBackRef, u8 TmrCtrNumber)
 {

+ 25 - 0
examples/mb/board.h

@@ -0,0 +1,25 @@
+#pragma once
+
+#include "rotor-light.hpp"
+
+namespace rl = rotor_light;
+
+struct Board {
+  static constexpr uint32_t samples = 10;
+
+  static void init_start();
+
+  static void disable_interrupts();
+
+  static void enable_interrupts();
+
+  static void enable_timer();
+
+  static void disable_timer();
+
+  static rl::TimePoint get_now();
+
+  static void toggle_led();
+
+  static void delay();
+};

+ 10 - 34
examples/mb/ping-pong-poll.cpp

@@ -1,14 +1,7 @@
 // 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
+#include "board.h"
 
 namespace rl = rotor_light;
 
@@ -26,9 +19,6 @@ struct Pong : rl::Message {
 };
 } // namespace message
 
-XGpio xil_gpio;
-uint32_t gpio_flag = 0xFFFF;
-
 struct Pinger : rl::Actor<2> {
   using Parent = Actor<2>;
 
@@ -43,9 +33,7 @@ struct Pinger : rl::Actor<2> {
   }
 
   void ping() {
-    /* toggle led */
-    XGpio_Out32(xil_gpio.BaseAddress + XGPIO_DATA_OFFSET, gpio_flag);
-    gpio_flag ^= 0xFFFF;
+    Board::toggle_led();
     send<message::Ping>(0, ponger_id);
   }
 
@@ -64,10 +52,7 @@ struct Ponger : rl::Actor<2> {
     subscribe(&Ponger::on_ping);
     Parent::initialize();
   }
-  void on_ping(message::Ping &) {
-    //
-    send<message::Pong>(0, pinger_id);
-  }
+  void on_ping(message::Ping &) { send<message::Pong>(0, pinger_id); }
   rl::ActorId pinger_id;
 };
 
@@ -79,20 +64,19 @@ using Storage = rl::traits::MessageStorage<rl::message::ChangeState,
 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();
+  Board::init_start();
+  Board::enable_timer();
+  Board::enable_interrupts();
 
   /* setup */
+  Queue queue;
+  Planner planner;
+  rl::Context context{&queue, &planner, &Board::get_now};
   sup.bind(context);
+
   auto pinger = sup.get_child<0>();
   auto ponger = sup.get_child<1>();
   pinger->ponger_id = ponger->get_id();
@@ -104,11 +88,3 @@ int main(int, char **) {
   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();
-}

+ 0 - 0
examples/mb/toolchain.cmake


部分文件因文件數量過多而無法顯示