Browse Source

FreeRTOS + lwIP + MQTTCilent - initial working setup

Bartosz Jakubski 9 months ago
parent
commit
083ed08535
100 changed files with 104346 additions and 0 deletions
  1. 4 0
      .gitignore
  2. 107 0
      .mxproject
  3. 76 0
      CM4/Core/Inc/main.h
  4. 510 0
      CM4/Core/Inc/stm32h7xx_hal_conf.h
  5. 66 0
      CM4/Core/Inc/stm32h7xx_it.h
  6. 166 0
      CM4/Core/Src/main.c
  7. 80 0
      CM4/Core/Src/stm32h7xx_hal_msp.c
  8. 203 0
      CM4/Core/Src/stm32h7xx_it.c
  9. 155 0
      CM4/Core/Src/syscalls.c
  10. 79 0
      CM4/Core/Src/sysmem.c
  11. 764 0
      CM4/Core/Startup/startup_stm32h745xihx.s
  12. 27 0
      CM4/Debug/Common/Src/subdir.mk
  13. 39 0
      CM4/Debug/Core/Src/subdir.mk
  14. 27 0
      CM4/Debug/Core/Startup/subdir.mk
  15. 112 0
      CM4/Debug/Drivers/STM32H7xx_HAL_Driver/subdir.mk
  16. 2014 0
      CM4/Debug/STM32H7-node-red-CM4.list
  17. 4611 0
      CM4/Debug/STM32H7-node-red-CM4.map
  18. 95 0
      CM4/Debug/makefile
  19. 25 0
      CM4/Debug/objects.list
  20. 9 0
      CM4/Debug/objects.mk
  21. 29 0
      CM4/Debug/sources.mk
  22. 174 0
      CM4/STM32H745XIHX_FLASH.ld
  23. 173 0
      CM4/STM32H745XIHX_RAM.ld
  24. 173 0
      CM7/Core/Inc/FreeRTOSConfig.h
  25. 13 0
      CM7/Core/Inc/echo_server.h
  26. 106 0
      CM7/Core/Inc/main.h
  27. 14 0
      CM7/Core/Inc/mqtt_client.h
  28. 26 0
      CM7/Core/Inc/node-red-config.h
  29. 510 0
      CM7/Core/Inc/stm32h7xx_hal_conf.h
  30. 65 0
      CM7/Core/Inc/stm32h7xx_it.h
  31. 74 0
      CM7/Core/Src/echo_server.c
  32. 72 0
      CM7/Core/Src/freertos.c
  33. 841 0
      CM7/Core/Src/lwiperf.c
  34. 416 0
      CM7/Core/Src/main.c
  35. 259 0
      CM7/Core/Src/mqtt_client.c
  36. 82 0
      CM7/Core/Src/stm32h7xx_hal_msp.c
  37. 130 0
      CM7/Core/Src/stm32h7xx_hal_timebase_tim.c
  38. 193 0
      CM7/Core/Src/stm32h7xx_it.c
  39. 156 0
      CM7/Core/Src/syscalls.c
  40. 79 0
      CM7/Core/Src/sysmem.c
  41. 764 0
      CM7/Core/Startup/startup_stm32h745xihx.s
  42. 27 0
      CM7/Debug/Common/Src/subdir.mk
  43. 54 0
      CM7/Debug/Core/Src/subdir.mk
  44. 27 0
      CM7/Debug/Core/Startup/subdir.mk
  45. 27 0
      CM7/Debug/Drivers/BSP/Components/subdir.mk
  46. 122 0
      CM7/Debug/Drivers/STM32H7xx_HAL_Driver/subdir.mk
  47. 27 0
      CM7/Debug/LWIP/App/subdir.mk
  48. 27 0
      CM7/Debug/LWIP/Target/subdir.mk
  49. 72 0
      CM7/Debug/Middlewares/Third_Party/FreeRTOS/subdir.mk
  50. 429 0
      CM7/Debug/Middlewares/Third_Party/LwIP/subdir.mk
  51. 54 0
      CM7/Debug/Middlewares/Third_Party/MQTT/MQTTPacket/subdir.mk
  52. 30 0
      CM7/Debug/Middlewares/Third_Party/MQTT/subdir.mk
  53. 48811 0
      CM7/Debug/STM32H7-node-red-CM7.list
  54. 34338 0
      CM7/Debug/STM32H7-node-red-CM7.map
  55. 102 0
      CM7/Debug/makefile
  56. 138 0
      CM7/Debug/objects.list
  57. 9 0
      CM7/Debug/objects.mk
  58. 36 0
      CM7/Debug/sources.mk
  59. 251 0
      CM7/LWIP/App/lwip.c
  60. 76 0
      CM7/LWIP/App/lwip.h
  61. 1143 0
      CM7/LWIP/Target/ethernetif.c
  62. 47 0
      CM7/LWIP/Target/ethernetif.h
  63. 164 0
      CM7/LWIP/Target/lwipopts.h
  64. 719 0
      CM7/Middlewares/Third_Party/MQTT/MQTTClient.c
  65. 234 0
      CM7/Middlewares/Third_Party/MQTT/MQTTClient.h
  66. 189 0
      CM7/Middlewares/Third_Party/MQTT/MQTTInterface.c
  67. 50 0
      CM7/Middlewares/Third_Party/MQTT/MQTTInterface.h
  68. 148 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTConnect.h
  69. 213 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTConnectClient.c
  70. 148 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTConnectServer.c
  71. 107 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTDeserializePublish.c
  72. 261 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTFormat.c
  73. 37 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTFormat.h
  74. 411 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTPacket.c
  75. 133 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTPacket.h
  76. 38 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTPublish.h
  77. 168 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSerializePublish.c
  78. 39 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSubscribe.h
  79. 136 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSubscribeClient.c
  80. 111 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSubscribeServer.c
  81. 38 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTUnsubscribe.h
  82. 105 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTUnsubscribeClient.c
  83. 101 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTUnsubscribeServer.c
  84. 78 0
      CM7/Middlewares/Third_Party/MQTT/MQTTPacket/StackTrace.h
  85. 54 0
      CM7/Release/Core/Src/subdir.mk
  86. 27 0
      CM7/Release/Core/Startup/subdir.mk
  87. 27 0
      CM7/Release/Drivers/BSP/Components/subdir.mk
  88. 122 0
      CM7/Release/Drivers/STM32H7xx_HAL_Driver/subdir.mk
  89. 27 0
      CM7/Release/LWIP/App/subdir.mk
  90. 27 0
      CM7/Release/LWIP/Target/subdir.mk
  91. 72 0
      CM7/Release/Middlewares/Third_Party/FreeRTOS/subdir.mk
  92. 429 0
      CM7/Release/Middlewares/Third_Party/LwIP/subdir.mk
  93. 54 0
      CM7/Release/Middlewares/Third_Party/MQTT/MQTTPacket/subdir.mk
  94. 30 0
      CM7/Release/Middlewares/Third_Party/MQTT/subdir.mk
  95. 101 0
      CM7/Release/makefile
  96. 137 0
      CM7/Release/objects.list
  97. 9 0
      CM7/Release/objects.mk
  98. 35 0
      CM7/Release/sources.mk
  99. 202 0
      CM7/STM32H745XIHX_FLASH.ld
  100. 0 0
      CM7/STM32H745XIHX_RAM.ld

+ 4 - 0
.gitignore

@@ -55,6 +55,10 @@ local.properties
 *.a
 *.la
 *.lo
+*.d
+*.o
+*.cyclo
+*.su
 
 # Shared objects (inc. Windows DLLs)
 *.dll

File diff suppressed because it is too large
+ 107 - 0
.mxproject


+ 76 - 0
CM4/Core/Inc/main.h

@@ -0,0 +1,76 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file           : main.h
+  * @brief          : Header for main.c file.
+  *                   This file contains the common defines of the application.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MAIN_H
+#define __MAIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void Error_Handler(void);
+
+/* USER CODE BEGIN EFP */
+
+/* USER CODE END EFP */
+
+/* Private defines -----------------------------------------------------------*/
+#define OSC32_OUT_Pin GPIO_PIN_15
+#define OSC32_OUT_GPIO_Port GPIOC
+#define OSC32_IN_Pin GPIO_PIN_14
+#define OSC32_IN_GPIO_Port GPIOC
+#define OSC_OUT_Pin GPIO_PIN_1
+#define OSC_OUT_GPIO_Port GPIOH
+#define OSC_IN_Pin GPIO_PIN_0
+#define OSC_IN_GPIO_Port GPIOH
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MAIN_H */

+ 510 - 0
CM4/Core/Inc/stm32h7xx_hal_conf.h

@@ -0,0 +1,510 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_hal_conf.h
+  * @author  MCD Application Team
+  * @brief   HAL configuration file.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32H7xx_HAL_CONF_H
+#define STM32H7xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+  * @brief This is the list of modules to be used in the HAL driver
+  */
+#define HAL_MODULE_ENABLED
+
+  /* #define HAL_ADC_MODULE_ENABLED   */
+/* #define HAL_FDCAN_MODULE_ENABLED   */
+/* #define HAL_FMAC_MODULE_ENABLED   */
+/* #define HAL_CEC_MODULE_ENABLED   */
+/* #define HAL_COMP_MODULE_ENABLED   */
+/* #define HAL_CORDIC_MODULE_ENABLED   */
+/* #define HAL_CRC_MODULE_ENABLED   */
+/* #define HAL_CRYP_MODULE_ENABLED   */
+/* #define HAL_DAC_MODULE_ENABLED   */
+/* #define HAL_DCMI_MODULE_ENABLED   */
+/* #define HAL_DMA2D_MODULE_ENABLED   */
+/* #define HAL_ETH_MODULE_ENABLED   */
+/* #define HAL_NAND_MODULE_ENABLED   */
+/* #define HAL_NOR_MODULE_ENABLED   */
+/* #define HAL_OTFDEC_MODULE_ENABLED   */
+/* #define HAL_SRAM_MODULE_ENABLED   */
+/* #define HAL_SDRAM_MODULE_ENABLED   */
+/* #define HAL_HASH_MODULE_ENABLED   */
+/* #define HAL_HRTIM_MODULE_ENABLED   */
+/* #define HAL_HSEM_MODULE_ENABLED   */
+/* #define HAL_GFXMMU_MODULE_ENABLED   */
+/* #define HAL_JPEG_MODULE_ENABLED   */
+/* #define HAL_OPAMP_MODULE_ENABLED   */
+/* #define HAL_OSPI_MODULE_ENABLED   */
+/* #define HAL_OSPI_MODULE_ENABLED   */
+/* #define HAL_I2S_MODULE_ENABLED   */
+/* #define HAL_SMBUS_MODULE_ENABLED   */
+/* #define HAL_IWDG_MODULE_ENABLED   */
+/* #define HAL_LPTIM_MODULE_ENABLED   */
+/* #define HAL_LTDC_MODULE_ENABLED   */
+/* #define HAL_QSPI_MODULE_ENABLED   */
+/* #define HAL_RAMECC_MODULE_ENABLED   */
+/* #define HAL_RNG_MODULE_ENABLED   */
+/* #define HAL_RTC_MODULE_ENABLED   */
+/* #define HAL_SAI_MODULE_ENABLED   */
+/* #define HAL_SD_MODULE_ENABLED   */
+/* #define HAL_MMC_MODULE_ENABLED   */
+/* #define HAL_SPDIFRX_MODULE_ENABLED   */
+/* #define HAL_SPI_MODULE_ENABLED   */
+/* #define HAL_SWPMI_MODULE_ENABLED   */
+/* #define HAL_TIM_MODULE_ENABLED   */
+/* #define HAL_UART_MODULE_ENABLED   */
+/* #define HAL_USART_MODULE_ENABLED   */
+/* #define HAL_IRDA_MODULE_ENABLED   */
+/* #define HAL_SMARTCARD_MODULE_ENABLED   */
+/* #define HAL_WWDG_MODULE_ENABLED   */
+/* #define HAL_PCD_MODULE_ENABLED   */
+/* #define HAL_HCD_MODULE_ENABLED   */
+/* #define HAL_DFSDM_MODULE_ENABLED   */
+/* #define HAL_DSI_MODULE_ENABLED   */
+/* #define HAL_JPEG_MODULE_ENABLED   */
+/* #define HAL_MDIOS_MODULE_ENABLED   */
+/* #define HAL_PSSI_MODULE_ENABLED   */
+/* #define HAL_DTS_MODULE_ENABLED   */
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_MDMA_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+#define HAL_HSEM_MODULE_ENABLED
+
+/* ########################## Oscillator Values adaptation ####################*/
+/**
+  * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+  *        This value is used by the RCC HAL module to compute the system frequency
+  *        (when HSE is used as system clock source, directly or through the PLL).
+  */
+#if !defined  (HSE_VALUE)
+#define HSE_VALUE    (25000000UL) /*!< Value of the External oscillator in Hz : FPGA case fixed to 60MHZ */
+#endif /* HSE_VALUE */
+
+#if !defined  (HSE_STARTUP_TIMEOUT)
+  #define HSE_STARTUP_TIMEOUT    (100UL)   /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+  * @brief Internal  oscillator (CSI) default value.
+  *        This value is the default CSI value after Reset.
+  */
+#if !defined  (CSI_VALUE)
+  #define CSI_VALUE    (4000000UL) /*!< Value of the Internal oscillator in Hz*/
+#endif /* CSI_VALUE */
+
+/**
+  * @brief Internal High Speed oscillator (HSI) value.
+  *        This value is used by the RCC HAL module to compute the system frequency
+  *        (when HSI is used as system clock source, directly or through the PLL).
+  */
+#if !defined  (HSI_VALUE)
+  #define HSI_VALUE    (64000000UL) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+  * @brief External Low Speed oscillator (LSE) value.
+  *        This value is used by the UART, RTC HAL module to compute the system frequency
+  */
+#if !defined  (LSE_VALUE)
+  #define LSE_VALUE    (32768UL) /*!< Value of the External oscillator in Hz*/
+#endif /* LSE_VALUE */
+
+#if !defined  (LSE_STARTUP_TIMEOUT)
+  #define LSE_STARTUP_TIMEOUT    (5000UL)   /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+#if !defined  (LSI_VALUE)
+  #define LSI_VALUE  (32000UL)              /*!< LSI Typical Value in Hz*/
+#endif /* LSI_VALUE */                      /*!< Value of the Internal Low Speed oscillator in Hz
+                                              The real value may vary depending on the variations
+                                              in voltage and temperature.*/
+
+/**
+  * @brief External clock source for I2S peripheral
+  *        This value is used by the I2S HAL module to compute the I2S clock source
+  *        frequency, this source is inserted directly through I2S_CKIN pad.
+  */
+#if !defined  (EXTERNAL_CLOCK_VALUE)
+  #define EXTERNAL_CLOCK_VALUE    12288000UL /*!< Value of the External clock in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+   ===  you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+  * @brief This is the HAL system configuration section
+  */
+#define  VDD_VALUE                    (3300UL) /*!< Value of VDD in mv */
+#define  TICK_INT_PRIORITY            (0UL) /*!< tick interrupt priority */
+#define  USE_RTOS                     0
+#define  USE_SD_TRANSCEIVER           0U               /*!< use uSD Transceiver */
+#define  USE_SPI_CRC	              0U               /*!< use CRC in SPI */
+
+#define  USE_HAL_ADC_REGISTER_CALLBACKS     0U /* ADC register callback disabled     */
+#define  USE_HAL_CEC_REGISTER_CALLBACKS     0U /* CEC register callback disabled     */
+#define  USE_HAL_COMP_REGISTER_CALLBACKS    0U /* COMP register callback disabled    */
+#define  USE_HAL_CORDIC_REGISTER_CALLBACKS  0U /* CORDIC register callback disabled  */
+#define  USE_HAL_CRYP_REGISTER_CALLBACKS    0U /* CRYP register callback disabled    */
+#define  USE_HAL_DAC_REGISTER_CALLBACKS     0U /* DAC register callback disabled     */
+#define  USE_HAL_DCMI_REGISTER_CALLBACKS    0U /* DCMI register callback disabled    */
+#define  USE_HAL_DFSDM_REGISTER_CALLBACKS   0U /* DFSDM register callback disabled   */
+#define  USE_HAL_DMA2D_REGISTER_CALLBACKS   0U /* DMA2D register callback disabled   */
+#define  USE_HAL_DSI_REGISTER_CALLBACKS     0U /* DSI register callback disabled     */
+#define  USE_HAL_DTS_REGISTER_CALLBACKS     0U /* DTS register callback disabled     */
+#define  USE_HAL_ETH_REGISTER_CALLBACKS     0U /* ETH register callback disabled     */
+#define  USE_HAL_FDCAN_REGISTER_CALLBACKS   0U /* FDCAN register callback disabled   */
+#define  USE_HAL_FMAC_REGISTER_CALLBACKS    0U /* FMAC register callback disabled  */
+#define  USE_HAL_NAND_REGISTER_CALLBACKS    0U /* NAND register callback disabled    */
+#define  USE_HAL_NOR_REGISTER_CALLBACKS     0U /* NOR register callback disabled     */
+#define  USE_HAL_SDRAM_REGISTER_CALLBACKS   0U /* SDRAM register callback disabled   */
+#define  USE_HAL_SRAM_REGISTER_CALLBACKS    0U /* SRAM register callback disabled    */
+#define  USE_HAL_HASH_REGISTER_CALLBACKS    0U /* HASH register callback disabled    */
+#define  USE_HAL_HCD_REGISTER_CALLBACKS     0U /* HCD register callback disabled     */
+#define  USE_HAL_GFXMMU_REGISTER_CALLBACKS  0U /* GFXMMU register callback disabled  */
+#define  USE_HAL_HRTIM_REGISTER_CALLBACKS   0U /* HRTIM register callback disabled   */
+#define  USE_HAL_I2C_REGISTER_CALLBACKS     0U /* I2C register callback disabled     */
+#define  USE_HAL_I2S_REGISTER_CALLBACKS     0U /* I2S register callback disabled     */
+#define  USE_HAL_IRDA_REGISTER_CALLBACKS    0U /* IRDA register callback disabled    */
+#define  USE_HAL_JPEG_REGISTER_CALLBACKS    0U /* JPEG register callback disabled    */
+#define  USE_HAL_LPTIM_REGISTER_CALLBACKS   0U /* LPTIM register callback disabled   */
+#define  USE_HAL_LTDC_REGISTER_CALLBACKS    0U /* LTDC register callback disabled    */
+#define  USE_HAL_MDIOS_REGISTER_CALLBACKS   0U /* MDIO register callback disabled    */
+#define  USE_HAL_MMC_REGISTER_CALLBACKS     0U /* MMC register callback disabled     */
+#define  USE_HAL_OPAMP_REGISTER_CALLBACKS   0U /* MDIO register callback disabled    */
+#define  USE_HAL_OSPI_REGISTER_CALLBACKS    0U /* OSPI register callback disabled    */
+#define  USE_HAL_OTFDEC_REGISTER_CALLBACKS  0U /* OTFDEC register callback disabled  */
+#define  USE_HAL_PCD_REGISTER_CALLBACKS     0U /* PCD register callback disabled     */
+#define  USE_HAL_QSPI_REGISTER_CALLBACKS    0U /* QSPI register callback disabled    */
+#define  USE_HAL_RNG_REGISTER_CALLBACKS     0U /* RNG register callback disabled     */
+#define  USE_HAL_RTC_REGISTER_CALLBACKS     0U /* RTC register callback disabled     */
+#define  USE_HAL_SAI_REGISTER_CALLBACKS     0U /* SAI register callback disabled     */
+#define  USE_HAL_SD_REGISTER_CALLBACKS      0U /* SD register callback disabled      */
+#define  USE_HAL_SMARTCARD_REGISTER_CALLBACKS  0U /* SMARTCARD register callback disabled */
+#define  USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
+#define  USE_HAL_SMBUS_REGISTER_CALLBACKS   0U /* SMBUS register callback disabled   */
+#define  USE_HAL_SPI_REGISTER_CALLBACKS     0U /* SPI register callback disabled     */
+#define  USE_HAL_SWPMI_REGISTER_CALLBACKS   0U /* SWPMI register callback disabled   */
+#define  USE_HAL_TIM_REGISTER_CALLBACKS     0U /* TIM register callback disabled     */
+#define  USE_HAL_UART_REGISTER_CALLBACKS    0U /* UART register callback disabled    */
+#define  USE_HAL_USART_REGISTER_CALLBACKS   0U /* USART register callback disabled   */
+#define  USE_HAL_WWDG_REGISTER_CALLBACKS    0U /* WWDG register callback disabled    */
+
+/* ########################### Ethernet Configuration ######################### */
+#define ETH_TX_DESC_CNT         4  /* number of Ethernet Tx DMA descriptors */
+#define ETH_RX_DESC_CNT         4  /* number of Ethernet Rx DMA descriptors */
+
+#define ETH_MAC_ADDR0    (0x02UL)
+#define ETH_MAC_ADDR1    (0x00UL)
+#define ETH_MAC_ADDR2    (0x00UL)
+#define ETH_MAC_ADDR3    (0x00UL)
+#define ETH_MAC_ADDR4    (0x00UL)
+#define ETH_MAC_ADDR5    (0x00UL)
+
+/* ########################## Assert Selection ############################## */
+/**
+  * @brief Uncomment the line below to expanse the "assert_param" macro in the
+  *        HAL drivers code
+  */
+/* #define USE_FULL_ASSERT    1U */
+
+/* Includes ------------------------------------------------------------------*/
+/**
+  * @brief Include module's header file
+  */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+  #include "stm32h7xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+  #include "stm32h7xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+  #include "stm32h7xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_MDMA_MODULE_ENABLED
+ #include "stm32h7xx_hal_mdma.h"
+#endif /* HAL_MDMA_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+  #include "stm32h7xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+  #include "stm32h7xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+  #include "stm32h7xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DSI_MODULE_ENABLED
+  #include "stm32h7xx_hal_dsi.h"
+#endif /* HAL_DSI_MODULE_ENABLED */
+
+#ifdef HAL_DFSDM_MODULE_ENABLED
+  #include "stm32h7xx_hal_dfsdm.h"
+#endif /* HAL_DFSDM_MODULE_ENABLED */
+
+#ifdef HAL_DTS_MODULE_ENABLED
+ #include "stm32h7xx_hal_dts.h"
+#endif /* HAL_DTS_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+  #include "stm32h7xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_EXTI_MODULE_ENABLED
+  #include "stm32h7xx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+  #include "stm32h7xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+  #include "stm32h7xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_FDCAN_MODULE_ENABLED
+  #include "stm32h7xx_hal_fdcan.h"
+#endif /* HAL_FDCAN_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+  #include "stm32h7xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_COMP_MODULE_ENABLED
+  #include "stm32h7xx_hal_comp.h"
+#endif /* HAL_COMP_MODULE_ENABLED */
+
+#ifdef HAL_CORDIC_MODULE_ENABLED
+  #include "stm32h7xx_hal_cordic.h"
+#endif /* HAL_CORDIC_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+  #include "stm32h7xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+  #include "stm32h7xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+  #include "stm32h7xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+  #include "stm32h7xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_GFXMMU_MODULE_ENABLED
+  #include "stm32h7xx_hal_gfxmmu.h"
+#endif /* HAL_GFXMMU_MODULE_ENABLED */
+
+#ifdef HAL_FMAC_MODULE_ENABLED
+  #include "stm32h7xx_hal_fmac.h"
+#endif /* HAL_FMAC_MODULE_ENABLED */
+
+#ifdef HAL_HRTIM_MODULE_ENABLED
+  #include "stm32h7xx_hal_hrtim.h"
+#endif /* HAL_HRTIM_MODULE_ENABLED */
+
+#ifdef HAL_HSEM_MODULE_ENABLED
+  #include "stm32h7xx_hal_hsem.h"
+#endif /* HAL_HSEM_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+  #include "stm32h7xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+  #include "stm32h7xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+  #include "stm32h7xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32h7xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32h7xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32h7xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_JPEG_MODULE_ENABLED
+ #include "stm32h7xx_hal_jpeg.h"
+#endif /* HAL_JPEG_MODULE_ENABLED */
+
+#ifdef HAL_MDIOS_MODULE_ENABLED
+ #include "stm32h7xx_hal_mdios.h"
+#endif /* HAL_MDIOS_MODULE_ENABLED */
+
+#ifdef HAL_MMC_MODULE_ENABLED
+ #include "stm32h7xx_hal_mmc.h"
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+#ifdef HAL_LPTIM_MODULE_ENABLED
+#include "stm32h7xx_hal_lptim.h"
+#endif /* HAL_LPTIM_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+#include "stm32h7xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_OPAMP_MODULE_ENABLED
+#include "stm32h7xx_hal_opamp.h"
+#endif /* HAL_OPAMP_MODULE_ENABLED */
+
+#ifdef HAL_OSPI_MODULE_ENABLED
+ #include "stm32h7xx_hal_ospi.h"
+#endif /* HAL_OSPI_MODULE_ENABLED */
+
+#ifdef HAL_OTFDEC_MODULE_ENABLED
+#include "stm32h7xx_hal_otfdec.h"
+#endif /* HAL_OTFDEC_MODULE_ENABLED */
+
+#ifdef HAL_PSSI_MODULE_ENABLED
+ #include "stm32h7xx_hal_pssi.h"
+#endif /* HAL_PSSI_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32h7xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_QSPI_MODULE_ENABLED
+ #include "stm32h7xx_hal_qspi.h"
+#endif /* HAL_QSPI_MODULE_ENABLED */
+
+#ifdef HAL_RAMECC_MODULE_ENABLED
+ #include "stm32h7xx_hal_ramecc.h"
+#endif /* HAL_RAMECC_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32h7xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32h7xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32h7xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32h7xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32h7xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32h7xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_SPDIFRX_MODULE_ENABLED
+ #include "stm32h7xx_hal_spdifrx.h"
+#endif /* HAL_SPDIFRX_MODULE_ENABLED */
+
+#ifdef HAL_SWPMI_MODULE_ENABLED
+ #include "stm32h7xx_hal_swpmi.h"
+#endif /* HAL_SWPMI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32h7xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32h7xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32h7xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32h7xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32h7xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_SMBUS_MODULE_ENABLED
+ #include "stm32h7xx_hal_smbus.h"
+#endif /* HAL_SMBUS_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32h7xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32h7xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32h7xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef  USE_FULL_ASSERT
+/**
+  * @brief  The assert_param macro is used for function's parameters check.
+  * @param  expr: If expr is false, it calls assert_failed function
+  *         which reports the name of the source file and the source
+  *         line number of the call that failed.
+  *         If expr is true, it returns no value.
+  * @retval None
+  */
+  #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+  void assert_failed(uint8_t *file, uint32_t line);
+#else
+  #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32H7xx_HAL_CONF_H */

+ 66 - 0
CM4/Core/Inc/stm32h7xx_it.h

@@ -0,0 +1,66 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_it.h
+  * @brief   This file contains the headers of the interrupt handlers.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+ ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32H7xx_IT_H
+#define __STM32H7xx_IT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+/* USER CODE BEGIN EFP */
+
+/* USER CODE END EFP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32H7xx_IT_H */

+ 166 - 0
CM4/Core/Src/main.c

@@ -0,0 +1,166 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file           : main.c
+  * @brief          : Main program body
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN PTD */
+
+/* USER CODE END PTD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+#ifndef HSEM_ID_0
+#define HSEM_ID_0 (0U) /* HW semaphore 0*/
+#endif
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+static void MX_GPIO_Init(void);
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/**
+  * @brief  The application entry point.
+  * @retval int
+  */
+int main(void)
+{
+  /* USER CODE BEGIN 1 */
+
+  /* USER CODE END 1 */
+
+/* USER CODE BEGIN Boot_Mode_Sequence_1 */
+	/* ETH_CODE: fixed core synchronization
+	 * Busy wait, since entering STOP mode breaks debug session.
+	 */
+	__HAL_RCC_HSEM_CLK_ENABLE();
+	while((__HAL_HSEM_GET_FLAG(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0))) == 0);
+	__HAL_HSEM_CLEAR_FLAG(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0));
+/* USER CODE END Boot_Mode_Sequence_1 */
+  /* MCU Configuration--------------------------------------------------------*/
+
+  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+  HAL_Init();
+
+  /* USER CODE BEGIN Init */
+
+  /* USER CODE END Init */
+
+  /* USER CODE BEGIN SysInit */
+
+  /* USER CODE END SysInit */
+
+  /* Initialize all configured peripherals */
+  MX_GPIO_Init();
+  /* USER CODE BEGIN 2 */
+
+  /* USER CODE END 2 */
+
+  /* Infinite loop */
+  /* USER CODE BEGIN WHILE */
+  while (1)
+  {
+    /* USER CODE END WHILE */
+
+    /* USER CODE BEGIN 3 */
+  }
+  /* USER CODE END 3 */
+}
+
+/**
+  * @brief GPIO Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_GPIO_Init(void)
+{
+  GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+  /* GPIO Ports Clock Enable */
+  __HAL_RCC_GPIOE_CLK_ENABLE();
+
+  /*Configure GPIO pins : PE5 PE4 */
+  GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_4;
+  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+  GPIO_InitStruct.Alternate = GPIO_AF10_SAI4;
+  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+}
+
+/* USER CODE BEGIN 4 */
+
+/* USER CODE END 4 */
+
+/**
+  * @brief  This function is executed in case of error occurrence.
+  * @retval None
+  */
+void Error_Handler(void)
+{
+  /* USER CODE BEGIN Error_Handler_Debug */
+  /* User can add his own implementation to report the HAL error return state */
+  __disable_irq();
+  while (1)
+  {
+  }
+  /* USER CODE END Error_Handler_Debug */
+}
+
+#ifdef  USE_FULL_ASSERT
+/**
+  * @brief  Reports the name of the source file and the source line number
+  *         where the assert_param error has occurred.
+  * @param  file: pointer to the source file name
+  * @param  line: assert_param error line source number
+  * @retval None
+  */
+void assert_failed(uint8_t *file, uint32_t line)
+{
+  /* USER CODE BEGIN 6 */
+  /* User can add his own implementation to report the file name and line number,
+     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+  /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */

+ 80 - 0
CM4/Core/Src/stm32h7xx_hal_msp.c

@@ -0,0 +1,80 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file         stm32h7xx_hal_msp.c
+  * @brief        This file provides code for the MSP Initialization
+  *               and de-Initialization codes.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN Define */
+
+/* USER CODE END Define */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN Macro */
+
+/* USER CODE END Macro */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* External functions --------------------------------------------------------*/
+/* USER CODE BEGIN ExternalFunctions */
+
+/* USER CODE END ExternalFunctions */
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+/**
+  * Initializes the Global MSP.
+  */
+void HAL_MspInit(void)
+{
+  /* USER CODE BEGIN MspInit 0 */
+
+  /* USER CODE END MspInit 0 */
+
+  __HAL_RCC_SYSCFG_CLK_ENABLE();
+
+  /* System interrupt init*/
+
+  /* USER CODE BEGIN MspInit 1 */
+
+  /* USER CODE END MspInit 1 */
+}
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */

+ 203 - 0
CM4/Core/Src/stm32h7xx_it.c

@@ -0,0 +1,203 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_it.c
+  * @brief   Interrupt Service Routines.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "stm32h7xx_it.h"
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/* External variables --------------------------------------------------------*/
+
+/* USER CODE BEGIN EV */
+
+/* USER CODE END EV */
+
+/******************************************************************************/
+/*           Cortex Processor Interruption and Exception Handlers          */
+/******************************************************************************/
+/**
+  * @brief This function handles Non maskable interrupt.
+  */
+void NMI_Handler(void)
+{
+  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
+
+  /* USER CODE END NonMaskableInt_IRQn 0 */
+  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
+  while (1)
+  {
+  }
+  /* USER CODE END NonMaskableInt_IRQn 1 */
+}
+
+/**
+  * @brief This function handles Hard fault interrupt.
+  */
+void HardFault_Handler(void)
+{
+  /* USER CODE BEGIN HardFault_IRQn 0 */
+
+  /* USER CODE END HardFault_IRQn 0 */
+  while (1)
+  {
+    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
+    /* USER CODE END W1_HardFault_IRQn 0 */
+  }
+}
+
+/**
+  * @brief This function handles Memory management fault.
+  */
+void MemManage_Handler(void)
+{
+  /* USER CODE BEGIN MemoryManagement_IRQn 0 */
+
+  /* USER CODE END MemoryManagement_IRQn 0 */
+  while (1)
+  {
+    /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
+    /* USER CODE END W1_MemoryManagement_IRQn 0 */
+  }
+}
+
+/**
+  * @brief This function handles Pre-fetch fault, memory access fault.
+  */
+void BusFault_Handler(void)
+{
+  /* USER CODE BEGIN BusFault_IRQn 0 */
+
+  /* USER CODE END BusFault_IRQn 0 */
+  while (1)
+  {
+    /* USER CODE BEGIN W1_BusFault_IRQn 0 */
+    /* USER CODE END W1_BusFault_IRQn 0 */
+  }
+}
+
+/**
+  * @brief This function handles Undefined instruction or illegal state.
+  */
+void UsageFault_Handler(void)
+{
+  /* USER CODE BEGIN UsageFault_IRQn 0 */
+
+  /* USER CODE END UsageFault_IRQn 0 */
+  while (1)
+  {
+    /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
+    /* USER CODE END W1_UsageFault_IRQn 0 */
+  }
+}
+
+/**
+  * @brief This function handles System service call via SWI instruction.
+  */
+void SVC_Handler(void)
+{
+  /* USER CODE BEGIN SVCall_IRQn 0 */
+
+  /* USER CODE END SVCall_IRQn 0 */
+  /* USER CODE BEGIN SVCall_IRQn 1 */
+
+  /* USER CODE END SVCall_IRQn 1 */
+}
+
+/**
+  * @brief This function handles Debug monitor.
+  */
+void DebugMon_Handler(void)
+{
+  /* USER CODE BEGIN DebugMonitor_IRQn 0 */
+
+  /* USER CODE END DebugMonitor_IRQn 0 */
+  /* USER CODE BEGIN DebugMonitor_IRQn 1 */
+
+  /* USER CODE END DebugMonitor_IRQn 1 */
+}
+
+/**
+  * @brief This function handles Pendable request for system service.
+  */
+void PendSV_Handler(void)
+{
+  /* USER CODE BEGIN PendSV_IRQn 0 */
+
+  /* USER CODE END PendSV_IRQn 0 */
+  /* USER CODE BEGIN PendSV_IRQn 1 */
+
+  /* USER CODE END PendSV_IRQn 1 */
+}
+
+/**
+  * @brief This function handles System tick timer.
+  */
+void SysTick_Handler(void)
+{
+  /* USER CODE BEGIN SysTick_IRQn 0 */
+
+  /* USER CODE END SysTick_IRQn 0 */
+  HAL_IncTick();
+  /* USER CODE BEGIN SysTick_IRQn 1 */
+
+  /* USER CODE END SysTick_IRQn 1 */
+}
+
+/******************************************************************************/
+/* STM32H7xx Peripheral Interrupt Handlers                                    */
+/* Add here the Interrupt Handlers for the used peripherals.                  */
+/* For the available peripheral interrupt handler names,                      */
+/* please refer to the startup file (startup_stm32h7xx.s).                    */
+/******************************************************************************/
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */

+ 155 - 0
CM4/Core/Src/syscalls.c

@@ -0,0 +1,155 @@
+/**
+ ******************************************************************************
+ * @file      syscalls.c
+ * @author    Auto-generated by STM32CubeIDE
+ * @brief     STM32CubeIDE Minimal System calls file
+ *
+ *            For more information about which c-functions
+ *            need which of these lowlevel functions
+ *            please consult the Newlib libc-manual
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2022 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Includes */
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/times.h>
+
+
+/* Variables */
+extern int __io_putchar(int ch) __attribute__((weak));
+extern int __io_getchar(void) __attribute__((weak));
+
+
+char *__env[1] = { 0 };
+char **environ = __env;
+
+
+/* Functions */
+void initialise_monitor_handles()
+{
+}
+
+int _getpid(void)
+{
+	return 1;
+}
+
+int _kill(int pid, int sig)
+{
+	errno = EINVAL;
+	return -1;
+}
+
+void _exit (int status)
+{
+	_kill(status, -1);
+	while (1) {}		/* Make sure we hang here */
+}
+
+__attribute__((weak)) int _read(int file, char *ptr, int len)
+{
+	int DataIdx;
+
+	for (DataIdx = 0; DataIdx < len; DataIdx++)
+	{
+		*ptr++ = __io_getchar();
+	}
+
+return len;
+}
+
+__attribute__((weak)) int _write(int file, char *ptr, int len)
+{
+	int DataIdx;
+
+	for (DataIdx = 0; DataIdx < len; DataIdx++)
+	{
+		__io_putchar(*ptr++);
+	}
+	return len;
+}
+
+int _close(int file)
+{
+	return -1;
+}
+
+
+int _fstat(int file, struct stat *st)
+{
+	st->st_mode = S_IFCHR;
+	return 0;
+}
+
+int _isatty(int file)
+{
+	return 1;
+}
+
+int _lseek(int file, int ptr, int dir)
+{
+	return 0;
+}
+
+int _open(char *path, int flags, ...)
+{
+	/* Pretend like we always fail */
+	return -1;
+}
+
+int _wait(int *status)
+{
+	errno = ECHILD;
+	return -1;
+}
+
+int _unlink(char *name)
+{
+	errno = ENOENT;
+	return -1;
+}
+
+int _times(struct tms *buf)
+{
+	return -1;
+}
+
+int _stat(char *file, struct stat *st)
+{
+	st->st_mode = S_IFCHR;
+	return 0;
+}
+
+int _link(char *old, char *new)
+{
+	errno = EMLINK;
+	return -1;
+}
+
+int _fork(void)
+{
+	errno = EAGAIN;
+	return -1;
+}
+
+int _execve(char *name, char **argv, char **env)
+{
+	errno = ENOMEM;
+	return -1;
+}

+ 79 - 0
CM4/Core/Src/sysmem.c

@@ -0,0 +1,79 @@
+/**
+ ******************************************************************************
+ * @file      sysmem.c
+ * @author    Generated by STM32CubeIDE
+ * @brief     STM32CubeIDE System Memory calls file
+ *
+ *            For more information about which C functions
+ *            need which of these lowlevel functions
+ *            please consult the newlib libc manual
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2022 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Includes */
+#include <errno.h>
+#include <stdint.h>
+
+/**
+ * Pointer to the current high watermark of the heap usage
+ */
+static uint8_t *__sbrk_heap_end = NULL;
+
+/**
+ * @brief _sbrk() allocates memory to the newlib heap and is used by malloc
+ *        and others from the C library
+ *
+ * @verbatim
+ * ############################################################################
+ * #  .data  #  .bss  #       newlib heap       #          MSP stack          #
+ * #         #        #                         # Reserved by _Min_Stack_Size #
+ * ############################################################################
+ * ^-- RAM start      ^-- _end                             _estack, RAM end --^
+ * @endverbatim
+ *
+ * This implementation starts allocating at the '_end' linker symbol
+ * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
+ * The implementation considers '_estack' linker symbol to be RAM end
+ * NOTE: If the MSP stack, at any point during execution, grows larger than the
+ * reserved size, please increase the '_Min_Stack_Size'.
+ *
+ * @param incr Memory size
+ * @return Pointer to allocated memory
+ */
+void *_sbrk(ptrdiff_t incr)
+{
+  extern uint8_t _end; /* Symbol defined in the linker script */
+  extern uint8_t _estack; /* Symbol defined in the linker script */
+  extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
+  const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
+  const uint8_t *max_heap = (uint8_t *)stack_limit;
+  uint8_t *prev_heap_end;
+
+  /* Initialize heap end at first call */
+  if (NULL == __sbrk_heap_end)
+  {
+    __sbrk_heap_end = &_end;
+  }
+
+  /* Protect heap from growing into the reserved MSP stack */
+  if (__sbrk_heap_end + incr > max_heap)
+  {
+    errno = ENOMEM;
+    return (void *)-1;
+  }
+
+  prev_heap_end = __sbrk_heap_end;
+  __sbrk_heap_end += incr;
+
+  return (void *)prev_heap_end;
+}

+ 764 - 0
CM4/Core/Startup/startup_stm32h745xihx.s

@@ -0,0 +1,764 @@
+/**
+  ******************************************************************************
+  * @file      startup_stm32h745xx.s
+  * @author    MCD Application Team
+  * @brief     STM32H745xx Devices vector table for GCC based toolchain.
+  *            This module performs:
+  *                - Set the initial SP
+  *                - Set the initial PC == Reset_Handler,
+  *                - Set the vector table entries with the exceptions ISR address
+  *                - Branches to main in the C library (which eventually
+  *                  calls main()).
+  *            After Reset the Cortex-M processor is in Thread mode,
+  *            priority is Privileged, and the Stack is set to Main.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+  .syntax unified
+  .cpu cortex-m7
+  .fpu softvfp
+  .thumb
+
+.global  g_pfnVectors
+.global  Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word  _sidata
+/* start address for the .data section. defined in linker script */
+.word  _sdata
+/* end address for the .data section. defined in linker script */
+.word  _edata
+/* start address for the .bss section. defined in linker script */
+.word  _sbss
+/* end address for the .bss section. defined in linker script */
+.word  _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+/**
+ * @brief  This is the code that gets called when the processor first
+ *          starts execution following a reset event. Only the absolutely
+ *          necessary set is performed, after which the application
+ *          supplied main() routine is called.
+ * @param  None
+ * @retval : None
+*/
+
+    .section  .text.Reset_Handler
+  .weak  Reset_Handler
+  .type  Reset_Handler, %function
+Reset_Handler:
+  ldr   sp, =_estack      /* set stack pointer */
+
+/* Call the clock system initialization function.*/
+  bl  SystemInit
+
+/* Copy the data segment initializers from flash to SRAM */
+  ldr r0, =_sdata
+  ldr r1, =_edata
+  ldr r2, =_sidata
+  movs r3, #0
+  b LoopCopyDataInit
+
+CopyDataInit:
+  ldr r4, [r2, r3]
+  str r4, [r0, r3]
+  adds r3, r3, #4
+
+LoopCopyDataInit:
+  adds r4, r0, r3
+  cmp r4, r1
+  bcc CopyDataInit
+/* Zero fill the bss segment. */
+  ldr r2, =_sbss
+  ldr r4, =_ebss
+  movs r3, #0
+  b LoopFillZerobss
+
+FillZerobss:
+  str  r3, [r2]
+  adds r2, r2, #4
+
+LoopFillZerobss:
+  cmp r2, r4
+  bcc FillZerobss
+
+/* Call static constructors */
+    bl __libc_init_array
+/* Call the application's entry point.*/
+  bl  main
+  bx  lr
+.size  Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief  This is the code that gets called when the processor receives an
+ *         unexpected interrupt.  This simply enters an infinite loop, preserving
+ *         the system state for examination by a debugger.
+ * @param  None
+ * @retval None
+*/
+    .section  .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+  b  Infinite_Loop
+  .size  Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+   .section  .isr_vector,"a",%progbits
+  .type  g_pfnVectors, %object
+  .size  g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+  .word  _estack
+  .word  Reset_Handler
+
+  .word  NMI_Handler
+  .word  HardFault_Handler
+  .word  MemManage_Handler
+  .word  BusFault_Handler
+  .word  UsageFault_Handler
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  SVC_Handler
+  .word  DebugMon_Handler
+  .word  0
+  .word  PendSV_Handler
+  .word  SysTick_Handler
+
+  /* External Interrupts */
+  .word     WWDG_IRQHandler                   /* Window WatchDog Interrupt ( wwdg1_it, wwdg2_it) */
+  .word     PVD_AVD_IRQHandler                /* PVD/AVD through EXTI Line detection */
+  .word     TAMP_STAMP_IRQHandler             /* Tamper and TimeStamps through the EXTI line */
+  .word     RTC_WKUP_IRQHandler               /* RTC Wakeup through the EXTI line */
+  .word     FLASH_IRQHandler                  /* FLASH                        */
+  .word     RCC_IRQHandler                    /* RCC                          */
+  .word     EXTI0_IRQHandler                  /* EXTI Line0                   */
+  .word     EXTI1_IRQHandler                  /* EXTI Line1                   */
+  .word     EXTI2_IRQHandler                  /* EXTI Line2                   */
+  .word     EXTI3_IRQHandler                  /* EXTI Line3                   */
+  .word     EXTI4_IRQHandler                  /* EXTI Line4                   */
+  .word     DMA1_Stream0_IRQHandler           /* DMA1 Stream 0                */
+  .word     DMA1_Stream1_IRQHandler           /* DMA1 Stream 1                */
+  .word     DMA1_Stream2_IRQHandler           /* DMA1 Stream 2                */
+  .word     DMA1_Stream3_IRQHandler           /* DMA1 Stream 3                */
+  .word     DMA1_Stream4_IRQHandler           /* DMA1 Stream 4                */
+  .word     DMA1_Stream5_IRQHandler           /* DMA1 Stream 5                */
+  .word     DMA1_Stream6_IRQHandler           /* DMA1 Stream 6                */
+  .word     ADC_IRQHandler                    /* ADC1, ADC2 and ADC3s         */
+  .word     FDCAN1_IT0_IRQHandler             /* FDCAN1 interrupt line 0      */
+  .word     FDCAN2_IT0_IRQHandler             /* FDCAN2 interrupt line 0      */
+  .word     FDCAN1_IT1_IRQHandler             /* FDCAN1 interrupt line 1      */
+  .word     FDCAN2_IT1_IRQHandler             /* FDCAN2 interrupt line 1      */
+  .word     EXTI9_5_IRQHandler                /* External Line[9:5]s          */
+  .word     TIM1_BRK_IRQHandler               /* TIM1 Break interrupt         */
+  .word     TIM1_UP_IRQHandler                /* TIM1 Update interrupt        */
+  .word     TIM1_TRG_COM_IRQHandler           /* TIM1 Trigger and Commutation interrupt */
+  .word     TIM1_CC_IRQHandler                /* TIM1 Capture Compare         */
+  .word     TIM2_IRQHandler                   /* TIM2                         */
+  .word     TIM3_IRQHandler                   /* TIM3                         */
+  .word     TIM4_IRQHandler                   /* TIM4                         */
+  .word     I2C1_EV_IRQHandler                /* I2C1 Event                   */
+  .word     I2C1_ER_IRQHandler                /* I2C1 Error                   */
+  .word     I2C2_EV_IRQHandler                /* I2C2 Event                   */
+  .word     I2C2_ER_IRQHandler                /* I2C2 Error                   */
+  .word     SPI1_IRQHandler                   /* SPI1                         */
+  .word     SPI2_IRQHandler                   /* SPI2                         */
+  .word     USART1_IRQHandler                 /* USART1                       */
+  .word     USART2_IRQHandler                 /* USART2                       */
+  .word     USART3_IRQHandler                 /* USART3                       */
+  .word     EXTI15_10_IRQHandler              /* External Line[15:10]s        */
+  .word     RTC_Alarm_IRQHandler              /* RTC Alarm (A and B) through EXTI Line */
+  .word     0                                 /* Reserved                     */
+  .word     TIM8_BRK_TIM12_IRQHandler         /* TIM8 Break and TIM12         */
+  .word     TIM8_UP_TIM13_IRQHandler          /* TIM8 Update and TIM13        */
+  .word     TIM8_TRG_COM_TIM14_IRQHandler     /* TIM8 Trigger and Commutation and TIM14 */
+  .word     TIM8_CC_IRQHandler                /* TIM8 Capture Compare         */
+  .word     DMA1_Stream7_IRQHandler           /* DMA1 Stream7                 */
+  .word     FMC_IRQHandler                    /* FMC                          */
+  .word     SDMMC1_IRQHandler                 /* SDMMC1                       */
+  .word     TIM5_IRQHandler                   /* TIM5                         */
+  .word     SPI3_IRQHandler                   /* SPI3                         */
+  .word     UART4_IRQHandler                  /* UART4                        */
+  .word     UART5_IRQHandler                  /* UART5                        */
+  .word     TIM6_DAC_IRQHandler               /* TIM6 and DAC1&2 underrun errors */
+  .word     TIM7_IRQHandler                   /* TIM7                         */
+  .word     DMA2_Stream0_IRQHandler           /* DMA2 Stream 0                */
+  .word     DMA2_Stream1_IRQHandler           /* DMA2 Stream 1                */
+  .word     DMA2_Stream2_IRQHandler           /* DMA2 Stream 2                */
+  .word     DMA2_Stream3_IRQHandler           /* DMA2 Stream 3                */
+  .word     DMA2_Stream4_IRQHandler           /* DMA2 Stream 4                */
+  .word     ETH_IRQHandler                    /* Ethernet                     */
+  .word     ETH_WKUP_IRQHandler               /* Ethernet Wakeup through EXTI line */
+  .word     FDCAN_CAL_IRQHandler              /* FDCAN calibration unit interrupt  */
+  .word     CM7_SEV_IRQHandler                /* CM7 Send event interrupt for CM4  */
+  .word     CM4_SEV_IRQHandler                /* CM4 Send event interrupt for CM7  */
+  .word     0                                 /* Reserved                     */
+  .word     0                                 /* Reserved                     */
+  .word     DMA2_Stream5_IRQHandler           /* DMA2 Stream 5                */
+  .word     DMA2_Stream6_IRQHandler           /* DMA2 Stream 6                */
+  .word     DMA2_Stream7_IRQHandler           /* DMA2 Stream 7                */
+  .word     USART6_IRQHandler                 /* USART6                       */
+  .word     I2C3_EV_IRQHandler                /* I2C3 event                   */
+  .word     I2C3_ER_IRQHandler                /* I2C3 error                   */
+  .word     OTG_HS_EP1_OUT_IRQHandler         /* USB OTG HS End Point 1 Out   */
+  .word     OTG_HS_EP1_IN_IRQHandler          /* USB OTG HS End Point 1 In    */
+  .word     OTG_HS_WKUP_IRQHandler            /* USB OTG HS Wakeup through EXTI */
+  .word     OTG_HS_IRQHandler                 /* USB OTG HS                   */
+  .word     DCMI_IRQHandler                   /* DCMI                         */
+  .word     0                                 /* Reserved                     */
+  .word     RNG_IRQHandler                    /* Rng                          */
+  .word     FPU_IRQHandler                    /* FPU                          */
+  .word     UART7_IRQHandler                  /* UART7                        */
+  .word     UART8_IRQHandler                  /* UART8                        */
+  .word     SPI4_IRQHandler                   /* SPI4                         */
+  .word     SPI5_IRQHandler                   /* SPI5                         */
+  .word     SPI6_IRQHandler                   /* SPI6                         */
+  .word     SAI1_IRQHandler                   /* SAI1                         */
+  .word     LTDC_IRQHandler                   /* LTDC                         */
+  .word     LTDC_ER_IRQHandler                /* LTDC error                   */
+  .word     DMA2D_IRQHandler                  /* DMA2D                        */
+  .word     SAI2_IRQHandler                   /* SAI2                         */
+  .word     QUADSPI_IRQHandler                /* QUADSPI                      */
+  .word     LPTIM1_IRQHandler                 /* LPTIM1                       */
+  .word     CEC_IRQHandler                    /* HDMI_CEC                     */
+  .word     I2C4_EV_IRQHandler                /* I2C4 Event                   */
+  .word     I2C4_ER_IRQHandler                /* I2C4 Error                   */
+  .word     SPDIF_RX_IRQHandler               /* SPDIF_RX                     */
+  .word     OTG_FS_EP1_OUT_IRQHandler         /* USB OTG FS End Point 1 Out   */
+  .word     OTG_FS_EP1_IN_IRQHandler          /* USB OTG FS End Point 1 In    */
+  .word     OTG_FS_WKUP_IRQHandler            /* USB OTG FS Wakeup through EXTI */
+  .word     OTG_FS_IRQHandler                 /* USB OTG FS                   */
+  .word     DMAMUX1_OVR_IRQHandler            /* DMAMUX1 Overrun interrupt    */
+  .word     HRTIM1_Master_IRQHandler          /* HRTIM Master Timer global Interrupt */
+  .word     HRTIM1_TIMA_IRQHandler            /* HRTIM Timer A global Interrupt */
+  .word     HRTIM1_TIMB_IRQHandler            /* HRTIM Timer B global Interrupt */
+  .word     HRTIM1_TIMC_IRQHandler            /* HRTIM Timer C global Interrupt */
+  .word     HRTIM1_TIMD_IRQHandler            /* HRTIM Timer D global Interrupt */
+  .word     HRTIM1_TIME_IRQHandler            /* HRTIM Timer E global Interrupt */
+  .word     HRTIM1_FLT_IRQHandler             /* HRTIM Fault global Interrupt   */
+  .word     DFSDM1_FLT0_IRQHandler            /* DFSDM Filter0 Interrupt        */
+  .word     DFSDM1_FLT1_IRQHandler            /* DFSDM Filter1 Interrupt        */
+  .word     DFSDM1_FLT2_IRQHandler            /* DFSDM Filter2 Interrupt        */
+  .word     DFSDM1_FLT3_IRQHandler            /* DFSDM Filter3 Interrupt        */
+  .word     SAI3_IRQHandler                   /* SAI3 global Interrupt          */
+  .word     SWPMI1_IRQHandler                 /* Serial Wire Interface 1 global interrupt */
+  .word     TIM15_IRQHandler                  /* TIM15 global Interrupt      */
+  .word     TIM16_IRQHandler                  /* TIM16 global Interrupt      */
+  .word     TIM17_IRQHandler                  /* TIM17 global Interrupt      */
+  .word     MDIOS_WKUP_IRQHandler             /* MDIOS Wakeup  Interrupt     */
+  .word     MDIOS_IRQHandler                  /* MDIOS global Interrupt      */
+  .word     JPEG_IRQHandler                   /* JPEG global Interrupt       */
+  .word     MDMA_IRQHandler                   /* MDMA global Interrupt       */
+  .word     0                                 /* Reserved                   */
+  .word     SDMMC2_IRQHandler                 /* SDMMC2 global Interrupt     */
+  .word     HSEM1_IRQHandler                  /* HSEM1 global Interrupt      */
+  .word     HSEM2_IRQHandler                  /* HSEM1 global Interrupt      */
+  .word     ADC3_IRQHandler                   /* ADC3 global Interrupt       */
+  .word     DMAMUX2_OVR_IRQHandler            /* DMAMUX Overrun interrupt    */
+  .word     BDMA_Channel0_IRQHandler          /* BDMA Channel 0 global Interrupt */
+  .word     BDMA_Channel1_IRQHandler          /* BDMA Channel 1 global Interrupt */
+  .word     BDMA_Channel2_IRQHandler          /* BDMA Channel 2 global Interrupt */
+  .word     BDMA_Channel3_IRQHandler          /* BDMA Channel 3 global Interrupt */
+  .word     BDMA_Channel4_IRQHandler          /* BDMA Channel 4 global Interrupt */
+  .word     BDMA_Channel5_IRQHandler          /* BDMA Channel 5 global Interrupt */
+  .word     BDMA_Channel6_IRQHandler          /* BDMA Channel 6 global Interrupt */
+  .word     BDMA_Channel7_IRQHandler          /* BDMA Channel 7 global Interrupt */
+  .word     COMP1_IRQHandler                  /* COMP1 global Interrupt     */
+  .word     LPTIM2_IRQHandler                 /* LP TIM2 global interrupt   */
+  .word     LPTIM3_IRQHandler                 /* LP TIM3 global interrupt   */
+  .word     LPTIM4_IRQHandler                 /* LP TIM4 global interrupt   */
+  .word     LPTIM5_IRQHandler                 /* LP TIM5 global interrupt   */
+  .word     LPUART1_IRQHandler                /* LP UART1 interrupt         */
+  .word     WWDG_RST_IRQHandler               /* Window Watchdog reset interrupt (exti_d2_wwdg_it, exti_d1_wwdg_it) */
+  .word     CRS_IRQHandler                    /* Clock Recovery Global Interrupt */
+  .word     ECC_IRQHandler                    /* ECC diagnostic Global Interrupt */
+  .word     SAI4_IRQHandler                   /* SAI4 global interrupt      */
+  .word     0                                 /* Reserved                   */
+  .word     HOLD_CORE_IRQHandler              /* Hold core interrupt        */
+  .word     WAKEUP_PIN_IRQHandler             /* Interrupt for all 6 wake-up pins */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+   .weak      NMI_Handler
+   .thumb_set NMI_Handler,Default_Handler
+
+   .weak      HardFault_Handler
+   .thumb_set HardFault_Handler,Default_Handler
+
+   .weak      MemManage_Handler
+   .thumb_set MemManage_Handler,Default_Handler
+
+   .weak      BusFault_Handler
+   .thumb_set BusFault_Handler,Default_Handler
+
+   .weak      UsageFault_Handler
+   .thumb_set UsageFault_Handler,Default_Handler
+
+   .weak      SVC_Handler
+   .thumb_set SVC_Handler,Default_Handler
+
+   .weak      DebugMon_Handler
+   .thumb_set DebugMon_Handler,Default_Handler
+
+   .weak      PendSV_Handler
+   .thumb_set PendSV_Handler,Default_Handler
+
+   .weak      SysTick_Handler
+   .thumb_set SysTick_Handler,Default_Handler
+
+   .weak      WWDG_IRQHandler
+   .thumb_set WWDG_IRQHandler,Default_Handler
+
+   .weak      PVD_AVD_IRQHandler
+   .thumb_set PVD_AVD_IRQHandler,Default_Handler
+
+   .weak      TAMP_STAMP_IRQHandler
+   .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+   .weak      RTC_WKUP_IRQHandler
+   .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+   .weak      FLASH_IRQHandler
+   .thumb_set FLASH_IRQHandler,Default_Handler
+
+   .weak      RCC_IRQHandler
+   .thumb_set RCC_IRQHandler,Default_Handler
+
+   .weak      EXTI0_IRQHandler
+   .thumb_set EXTI0_IRQHandler,Default_Handler
+
+   .weak      EXTI1_IRQHandler
+   .thumb_set EXTI1_IRQHandler,Default_Handler
+
+   .weak      EXTI2_IRQHandler
+   .thumb_set EXTI2_IRQHandler,Default_Handler
+
+   .weak      EXTI3_IRQHandler
+   .thumb_set EXTI3_IRQHandler,Default_Handler
+
+   .weak      EXTI4_IRQHandler
+   .thumb_set EXTI4_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream0_IRQHandler
+   .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream1_IRQHandler
+   .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream2_IRQHandler
+   .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream3_IRQHandler
+   .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream4_IRQHandler
+   .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream5_IRQHandler
+   .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream6_IRQHandler
+   .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
+
+   .weak      ADC_IRQHandler
+   .thumb_set ADC_IRQHandler,Default_Handler
+
+   .weak      FDCAN1_IT0_IRQHandler
+   .thumb_set FDCAN1_IT0_IRQHandler,Default_Handler
+
+   .weak      FDCAN2_IT0_IRQHandler
+   .thumb_set FDCAN2_IT0_IRQHandler,Default_Handler
+
+   .weak      FDCAN1_IT1_IRQHandler
+   .thumb_set FDCAN1_IT1_IRQHandler,Default_Handler
+
+   .weak      FDCAN2_IT1_IRQHandler
+   .thumb_set FDCAN2_IT1_IRQHandler,Default_Handler
+
+   .weak      EXTI9_5_IRQHandler
+   .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+   .weak      TIM1_BRK_IRQHandler
+   .thumb_set TIM1_BRK_IRQHandler,Default_Handler
+
+   .weak      TIM1_UP_IRQHandler
+   .thumb_set TIM1_UP_IRQHandler,Default_Handler
+
+   .weak      TIM1_TRG_COM_IRQHandler
+   .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
+
+   .weak      TIM1_CC_IRQHandler
+   .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+   .weak      TIM2_IRQHandler
+   .thumb_set TIM2_IRQHandler,Default_Handler
+
+   .weak      TIM3_IRQHandler
+   .thumb_set TIM3_IRQHandler,Default_Handler
+
+   .weak      TIM4_IRQHandler
+   .thumb_set TIM4_IRQHandler,Default_Handler
+
+   .weak      I2C1_EV_IRQHandler
+   .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+   .weak      I2C1_ER_IRQHandler
+   .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+   .weak      I2C2_EV_IRQHandler
+   .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+   .weak      I2C2_ER_IRQHandler
+   .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+   .weak      SPI1_IRQHandler
+   .thumb_set SPI1_IRQHandler,Default_Handler
+
+   .weak      SPI2_IRQHandler
+   .thumb_set SPI2_IRQHandler,Default_Handler
+
+   .weak      USART1_IRQHandler
+   .thumb_set USART1_IRQHandler,Default_Handler
+
+   .weak      USART2_IRQHandler
+   .thumb_set USART2_IRQHandler,Default_Handler
+
+   .weak      USART3_IRQHandler
+   .thumb_set USART3_IRQHandler,Default_Handler
+
+   .weak      EXTI15_10_IRQHandler
+   .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+   .weak      RTC_Alarm_IRQHandler
+   .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+   .weak      TIM8_BRK_TIM12_IRQHandler
+   .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
+
+   .weak      TIM8_UP_TIM13_IRQHandler
+   .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
+
+   .weak      TIM8_TRG_COM_TIM14_IRQHandler
+   .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
+
+   .weak      TIM8_CC_IRQHandler
+   .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream7_IRQHandler
+   .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
+
+   .weak      FMC_IRQHandler
+   .thumb_set FMC_IRQHandler,Default_Handler
+
+   .weak      SDMMC1_IRQHandler
+   .thumb_set SDMMC1_IRQHandler,Default_Handler
+
+   .weak      TIM5_IRQHandler
+   .thumb_set TIM5_IRQHandler,Default_Handler
+
+   .weak      SPI3_IRQHandler
+   .thumb_set SPI3_IRQHandler,Default_Handler
+
+   .weak      UART4_IRQHandler
+   .thumb_set UART4_IRQHandler,Default_Handler
+
+   .weak      UART5_IRQHandler
+   .thumb_set UART5_IRQHandler,Default_Handler
+
+   .weak      TIM6_DAC_IRQHandler
+   .thumb_set TIM6_DAC_IRQHandler,Default_Handler
+
+   .weak      TIM7_IRQHandler
+   .thumb_set TIM7_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream0_IRQHandler
+   .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream1_IRQHandler
+   .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream2_IRQHandler
+   .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream3_IRQHandler
+   .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream4_IRQHandler
+   .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
+
+   .weak      ETH_IRQHandler
+   .thumb_set ETH_IRQHandler,Default_Handler
+
+   .weak      ETH_WKUP_IRQHandler
+   .thumb_set ETH_WKUP_IRQHandler,Default_Handler
+
+   .weak      FDCAN_CAL_IRQHandler
+   .thumb_set FDCAN_CAL_IRQHandler,Default_Handler
+
+   .weak      CM7_SEV_IRQHandler
+   .thumb_set CM7_SEV_IRQHandler,Default_Handler
+
+   .weak      CM4_SEV_IRQHandler
+   .thumb_set CM4_SEV_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream5_IRQHandler
+   .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream6_IRQHandler
+   .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream7_IRQHandler
+   .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
+
+   .weak      USART6_IRQHandler
+   .thumb_set USART6_IRQHandler,Default_Handler
+
+   .weak      I2C3_EV_IRQHandler
+   .thumb_set I2C3_EV_IRQHandler,Default_Handler
+
+   .weak      I2C3_ER_IRQHandler
+   .thumb_set I2C3_ER_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_EP1_OUT_IRQHandler
+   .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_EP1_IN_IRQHandler
+   .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_WKUP_IRQHandler
+   .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_IRQHandler
+   .thumb_set OTG_HS_IRQHandler,Default_Handler
+
+   .weak      DCMI_IRQHandler
+   .thumb_set DCMI_IRQHandler,Default_Handler
+
+   .weak      RNG_IRQHandler
+   .thumb_set RNG_IRQHandler,Default_Handler
+
+   .weak      FPU_IRQHandler
+   .thumb_set FPU_IRQHandler,Default_Handler
+
+   .weak      UART7_IRQHandler
+   .thumb_set UART7_IRQHandler,Default_Handler
+
+   .weak      UART8_IRQHandler
+   .thumb_set UART8_IRQHandler,Default_Handler
+
+   .weak      SPI4_IRQHandler
+   .thumb_set SPI4_IRQHandler,Default_Handler
+
+   .weak      SPI5_IRQHandler
+   .thumb_set SPI5_IRQHandler,Default_Handler
+
+   .weak      SPI6_IRQHandler
+   .thumb_set SPI6_IRQHandler,Default_Handler
+
+   .weak      SAI1_IRQHandler
+   .thumb_set SAI1_IRQHandler,Default_Handler
+
+   .weak      LTDC_IRQHandler
+   .thumb_set LTDC_IRQHandler,Default_Handler
+
+   .weak      LTDC_ER_IRQHandler
+   .thumb_set LTDC_ER_IRQHandler,Default_Handler
+
+   .weak      DMA2D_IRQHandler
+   .thumb_set DMA2D_IRQHandler,Default_Handler
+
+   .weak      SAI2_IRQHandler
+   .thumb_set SAI2_IRQHandler,Default_Handler
+
+   .weak      QUADSPI_IRQHandler
+   .thumb_set QUADSPI_IRQHandler,Default_Handler
+
+   .weak      LPTIM1_IRQHandler
+   .thumb_set LPTIM1_IRQHandler,Default_Handler
+
+   .weak      CEC_IRQHandler
+   .thumb_set CEC_IRQHandler,Default_Handler
+
+   .weak      I2C4_EV_IRQHandler
+   .thumb_set I2C4_EV_IRQHandler,Default_Handler
+
+   .weak      I2C4_ER_IRQHandler
+   .thumb_set I2C4_ER_IRQHandler,Default_Handler
+
+   .weak      SPDIF_RX_IRQHandler
+   .thumb_set SPDIF_RX_IRQHandler,Default_Handler
+
+   .weak      OTG_FS_EP1_OUT_IRQHandler
+   .thumb_set OTG_FS_EP1_OUT_IRQHandler,Default_Handler
+
+   .weak      OTG_FS_EP1_IN_IRQHandler
+   .thumb_set OTG_FS_EP1_IN_IRQHandler,Default_Handler
+
+   .weak      OTG_FS_WKUP_IRQHandler
+   .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+   .weak      OTG_FS_IRQHandler
+   .thumb_set OTG_FS_IRQHandler,Default_Handler
+
+   .weak      DMAMUX1_OVR_IRQHandler
+   .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_Master_IRQHandler
+   .thumb_set HRTIM1_Master_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_TIMA_IRQHandler
+   .thumb_set HRTIM1_TIMA_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_TIMB_IRQHandler
+   .thumb_set HRTIM1_TIMB_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_TIMC_IRQHandler
+   .thumb_set HRTIM1_TIMC_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_TIMD_IRQHandler
+   .thumb_set HRTIM1_TIMD_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_TIME_IRQHandler
+   .thumb_set HRTIM1_TIME_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_FLT_IRQHandler
+   .thumb_set HRTIM1_FLT_IRQHandler,Default_Handler
+
+   .weak      DFSDM1_FLT0_IRQHandler
+   .thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler
+
+   .weak      DFSDM1_FLT1_IRQHandler
+   .thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler
+
+   .weak      DFSDM1_FLT2_IRQHandler
+   .thumb_set DFSDM1_FLT2_IRQHandler,Default_Handler
+
+   .weak      DFSDM1_FLT3_IRQHandler
+   .thumb_set DFSDM1_FLT3_IRQHandler,Default_Handler
+
+   .weak      SAI3_IRQHandler
+   .thumb_set SAI3_IRQHandler,Default_Handler
+
+   .weak      SWPMI1_IRQHandler
+   .thumb_set SWPMI1_IRQHandler,Default_Handler
+
+   .weak      TIM15_IRQHandler
+   .thumb_set TIM15_IRQHandler,Default_Handler
+
+   .weak      TIM16_IRQHandler
+   .thumb_set TIM16_IRQHandler,Default_Handler
+
+   .weak      TIM17_IRQHandler
+   .thumb_set TIM17_IRQHandler,Default_Handler
+
+   .weak      MDIOS_WKUP_IRQHandler
+   .thumb_set MDIOS_WKUP_IRQHandler,Default_Handler
+
+   .weak      MDIOS_IRQHandler
+   .thumb_set MDIOS_IRQHandler,Default_Handler
+
+   .weak      JPEG_IRQHandler
+   .thumb_set JPEG_IRQHandler,Default_Handler
+
+   .weak      MDMA_IRQHandler
+   .thumb_set MDMA_IRQHandler,Default_Handler
+
+   .weak      SDMMC2_IRQHandler
+   .thumb_set SDMMC2_IRQHandler,Default_Handler
+
+   .weak      HSEM1_IRQHandler
+   .thumb_set HSEM1_IRQHandler,Default_Handler
+
+   .weak      HSEM2_IRQHandler
+   .thumb_set HSEM2_IRQHandler,Default_Handler
+
+   .weak      ADC3_IRQHandler
+   .thumb_set ADC3_IRQHandler,Default_Handler
+
+   .weak      DMAMUX2_OVR_IRQHandler
+   .thumb_set DMAMUX2_OVR_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel0_IRQHandler
+   .thumb_set BDMA_Channel0_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel1_IRQHandler
+   .thumb_set BDMA_Channel1_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel2_IRQHandler
+   .thumb_set BDMA_Channel2_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel3_IRQHandler
+   .thumb_set BDMA_Channel3_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel4_IRQHandler
+   .thumb_set BDMA_Channel4_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel5_IRQHandler
+   .thumb_set BDMA_Channel5_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel6_IRQHandler
+   .thumb_set BDMA_Channel6_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel7_IRQHandler
+   .thumb_set BDMA_Channel7_IRQHandler,Default_Handler
+
+   .weak      COMP1_IRQHandler
+   .thumb_set COMP1_IRQHandler,Default_Handler
+
+   .weak      LPTIM2_IRQHandler
+   .thumb_set LPTIM2_IRQHandler,Default_Handler
+
+   .weak      LPTIM3_IRQHandler
+   .thumb_set LPTIM3_IRQHandler,Default_Handler
+
+   .weak      LPTIM4_IRQHandler
+   .thumb_set LPTIM4_IRQHandler,Default_Handler
+
+   .weak      LPTIM5_IRQHandler
+   .thumb_set LPTIM5_IRQHandler,Default_Handler
+
+   .weak      LPUART1_IRQHandler
+   .thumb_set LPUART1_IRQHandler,Default_Handler
+
+   .weak      WWDG_RST_IRQHandler
+   .thumb_set WWDG_RST_IRQHandler,Default_Handler
+
+   .weak      CRS_IRQHandler
+   .thumb_set CRS_IRQHandler,Default_Handler
+
+   .weak      ECC_IRQHandler
+   .thumb_set ECC_IRQHandler,Default_Handler
+
+   .weak      SAI4_IRQHandler
+   .thumb_set SAI4_IRQHandler,Default_Handler
+
+   .weak      HOLD_CORE_IRQHandler
+   .thumb_set HOLD_CORE_IRQHandler,Default_Handler
+
+   .weak      WAKEUP_PIN_IRQHandler
+   .thumb_set WAKEUP_PIN_IRQHandler,Default_Handler
+
+

+ 27 - 0
CM4/Debug/Common/Src/subdir.mk

@@ -0,0 +1,27 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS += \
+/home/jakubski/Projects/node-red/STM32H7-node-red/Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.c 
+
+OBJS += \
+./Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.o 
+
+C_DEPS += \
+./Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.o: /home/jakubski/Projects/node-red/STM32H7-node-red/Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.c Common/Src/subdir.mk
+	arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DCORE_CM4 -DUSE_HAL_DRIVER -DSTM32H745xx -c -I../Core/Inc -I../../Drivers/STM32H7xx_HAL_Driver/Inc -I../../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy -I../../Drivers/CMSIS/Device/ST/STM32H7xx/Include -I../../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -fcyclomatic-complexity -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Common-2f-Src
+
+clean-Common-2f-Src:
+	-$(RM) ./Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.cyclo ./Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.d ./Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.o ./Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.su
+
+.PHONY: clean-Common-2f-Src
+

File diff suppressed because it is too large
+ 39 - 0
CM4/Debug/Core/Src/subdir.mk


+ 27 - 0
CM4/Debug/Core/Startup/subdir.mk

@@ -0,0 +1,27 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables 
+S_SRCS += \
+../Core/Startup/startup_stm32h745xihx.s 
+
+OBJS += \
+./Core/Startup/startup_stm32h745xihx.o 
+
+S_DEPS += \
+./Core/Startup/startup_stm32h745xihx.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Core/Startup/%.o: ../Core/Startup/%.s Core/Startup/subdir.mk
+	arm-none-eabi-gcc -mcpu=cortex-m4 -g3 -DDEBUG -c -x assembler-with-cpp -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@" "$<"
+
+clean: clean-Core-2f-Startup
+
+clean-Core-2f-Startup:
+	-$(RM) ./Core/Startup/startup_stm32h745xihx.d ./Core/Startup/startup_stm32h745xihx.o
+
+.PHONY: clean-Core-2f-Startup
+

File diff suppressed because it is too large
+ 112 - 0
CM4/Debug/Drivers/STM32H7xx_HAL_Driver/subdir.mk


File diff suppressed because it is too large
+ 2014 - 0
CM4/Debug/STM32H7-node-red-CM4.list


File diff suppressed because it is too large
+ 4611 - 0
CM4/Debug/STM32H7-node-red-CM4.map


+ 95 - 0
CM4/Debug/makefile

@@ -0,0 +1,95 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+-include ../makefile.init
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include Drivers/STM32H7xx_HAL_Driver/subdir.mk
+-include Core/Startup/subdir.mk
+-include Core/Src/subdir.mk
+-include Common/Src/subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(S_DEPS)),)
+-include $(S_DEPS)
+endif
+ifneq ($(strip $(S_UPPER_DEPS)),)
+-include $(S_UPPER_DEPS)
+endif
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+OPTIONAL_TOOL_DEPS := \
+$(wildcard ../makefile.defs) \
+$(wildcard ../makefile.init) \
+$(wildcard ../makefile.targets) \
+
+
+BUILD_ARTIFACT_NAME := STM32H7-node-red-CM4
+BUILD_ARTIFACT_EXTENSION := elf
+BUILD_ARTIFACT_PREFIX :=
+BUILD_ARTIFACT := $(BUILD_ARTIFACT_PREFIX)$(BUILD_ARTIFACT_NAME)$(if $(BUILD_ARTIFACT_EXTENSION),.$(BUILD_ARTIFACT_EXTENSION),)
+
+# Add inputs and outputs from these tool invocations to the build variables 
+EXECUTABLES += \
+STM32H7-node-red-CM4.elf \
+
+MAP_FILES += \
+STM32H7-node-red-CM4.map \
+
+SIZE_OUTPUT += \
+default.size.stdout \
+
+OBJDUMP_LIST += \
+STM32H7-node-red-CM4.list \
+
+
+# All Target
+all: main-build
+
+# Main-build Target
+main-build: STM32H7-node-red-CM4.elf secondary-outputs
+
+# Tool invocations
+STM32H7-node-red-CM4.elf STM32H7-node-red-CM4.map: $(OBJS) $(USER_OBJS) /home/jakubski/Projects/node-red/STM32H7-node-red/CM4/STM32H745XIHX_FLASH.ld makefile objects.list $(OPTIONAL_TOOL_DEPS)
+	arm-none-eabi-gcc -o "STM32H7-node-red-CM4.elf" @"objects.list" $(USER_OBJS) $(LIBS) -mcpu=cortex-m4 -T"/home/jakubski/Projects/node-red/STM32H7-node-red/CM4/STM32H745XIHX_FLASH.ld" --specs=nosys.specs -Wl,-Map="STM32H7-node-red-CM4.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
+	@echo 'Finished building target: $@'
+	@echo ' '
+
+default.size.stdout: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)
+	arm-none-eabi-size  $(EXECUTABLES)
+	@echo 'Finished building: $@'
+	@echo ' '
+
+STM32H7-node-red-CM4.list: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)
+	arm-none-eabi-objdump -h -S $(EXECUTABLES) > "STM32H7-node-red-CM4.list"
+	@echo 'Finished building: $@'
+	@echo ' '
+
+# Other Targets
+clean:
+	-$(RM) STM32H7-node-red-CM4.elf STM32H7-node-red-CM4.list STM32H7-node-red-CM4.map default.size.stdout
+	-@echo ' '
+
+secondary-outputs: $(SIZE_OUTPUT) $(OBJDUMP_LIST)
+
+fail-specified-linker-script-missing:
+	@echo 'Error: Cannot find the specified linker script. Check the linker settings in the build configuration.'
+	@exit 2
+
+warn-no-linker-script-specified:
+	@echo 'Warning: No linker script specified. Check the linker settings in the build configuration.'
+
+.PHONY: all clean dependents main-build fail-specified-linker-script-missing warn-no-linker-script-specified
+
+-include ../makefile.targets

+ 25 - 0
CM4/Debug/objects.list

@@ -0,0 +1,25 @@
+"./Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.o"
+"./Core/Src/main.o"
+"./Core/Src/stm32h7xx_hal_msp.o"
+"./Core/Src/stm32h7xx_it.o"
+"./Core/Src/syscalls.o"
+"./Core/Src/sysmem.o"
+"./Core/Startup/startup_stm32h745xihx.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_cortex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_dma.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_dma_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_exti.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_flash.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_flash_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_gpio.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_hsem.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_i2c.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_i2c_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_mdma.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_pwr.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_pwr_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_rcc.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_rcc_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_tim.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_tim_ex.o"

+ 9 - 0
CM4/Debug/objects.mk

@@ -0,0 +1,9 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+

+ 29 - 0
CM4/Debug/sources.mk

@@ -0,0 +1,29 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+ELF_SRCS := 
+OBJ_SRCS := 
+S_SRCS := 
+C_SRCS := 
+S_UPPER_SRCS := 
+O_SRCS := 
+CYCLO_FILES := 
+SIZE_OUTPUT := 
+OBJDUMP_LIST := 
+SU_FILES := 
+EXECUTABLES := 
+OBJS := 
+MAP_FILES := 
+S_DEPS := 
+S_UPPER_DEPS := 
+C_DEPS := 
+
+# Every subdirectory with source files must be described here
+SUBDIRS := \
+Common/Src \
+Core/Src \
+Core/Startup \
+Drivers/STM32H7xx_HAL_Driver \
+

+ 174 - 0
CM4/STM32H745XIHX_FLASH.ld

@@ -0,0 +1,174 @@
+/*
+******************************************************************************
+**
+**  File        : LinkerScript.ld
+**
+**  Author      : STM32CubeIDE
+**
+**  Abstract    : Linker script for STM32H7 series
+**                1024Kbytes FLASH and 288Kbytes RAM
+**
+**                Set heap size, stack size and stack location according
+**                to application requirements.
+**
+**                Set memory bank area and size if external memory is used.
+**
+**  Target      : STMicroelectronics STM32
+**
+**  Distribution: The file is distributed as is, without any warranty
+**                of any kind.
+**
+*****************************************************************************
+** @attention
+**
+** Copyright (c) 2022 STMicroelectronics.
+** All rights reserved.
+**
+** This software is licensed under terms that can be found in the LICENSE file
+** in the root directory of this software component.
+** If no LICENSE file comes with this software, it is provided AS-IS.
+**
+****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200;      /* required amount of heap  */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+FLASH (rx)     : ORIGIN = 0x08100000, LENGTH = 1024K
+/* ETH_CODE: reduce RAM size, since end is used by ETH buffers */
+RAM (xrw)      : ORIGIN = 0x10000000, LENGTH = 128K
+}
+
+/* Define output sections */
+SECTIONS
+{
+  /* The startup code goes first into FLASH */
+  .isr_vector :
+  {
+    . = ALIGN(4);
+    KEEP(*(.isr_vector)) /* Startup code */
+    . = ALIGN(4);
+  } >FLASH
+
+  /* The program code and other data goes into FLASH */
+  .text :
+  {
+    . = ALIGN(4);
+    *(.text)           /* .text sections (code) */
+    *(.text*)          /* .text* sections (code) */
+    *(.glue_7)         /* glue arm to thumb code */
+    *(.glue_7t)        /* glue thumb to arm code */
+    *(.eh_frame)
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    . = ALIGN(4);
+    _etext = .;        /* define a global symbols at end of code */
+  } >FLASH
+
+  /* Constant data goes into FLASH */
+  .rodata :
+  {
+    . = ALIGN(4);
+    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
+    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
+    . = ALIGN(4);
+  } >FLASH
+
+  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
+  .ARM : {
+    __exidx_start = .;
+    *(.ARM.exidx*)
+    __exidx_end = .;
+  } >FLASH
+
+  .preinit_array     :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array*))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  } >FLASH
+  .init_array :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array*))
+    PROVIDE_HIDDEN (__init_array_end = .);
+  } >FLASH
+  .fini_array :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(SORT(.fini_array.*)))
+    KEEP (*(.fini_array*))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  } >FLASH
+
+  /* used by the startup to initialize data */
+  _sidata = LOADADDR(.data);
+
+  /* Initialized data sections goes into RAM, load LMA copy after code */
+  .data :
+  {
+    . = ALIGN(4);
+    _sdata = .;        /* create a global symbol at data start */
+    *(.data)           /* .data sections */
+    *(.data*)          /* .data* sections */
+    *(.RamFunc)        /* .RamFunc sections */
+    *(.RamFunc*)       /* .RamFunc* sections */
+
+    . = ALIGN(4);
+    _edata = .;        /* define a global symbol at data end */
+  } >RAM AT> FLASH
+
+
+  /* Uninitialized data section */
+  . = ALIGN(4);
+  .bss :
+  {
+    /* This is used by the startup in order to initialize the .bss section */
+    _sbss = .;         /* define a global symbol at bss start */
+    __bss_start__ = _sbss;
+    *(.bss)
+    *(.bss*)
+    *(COMMON)
+
+    . = ALIGN(4);
+    _ebss = .;         /* define a global symbol at bss end */
+    __bss_end__ = _ebss;
+  } >RAM
+
+  /* User_heap_stack section, used to check that there is enough RAM left */
+  ._user_heap_stack :
+  {
+    . = ALIGN(8);
+    PROVIDE ( end = . );
+    PROVIDE ( _end = . );
+    . = . + _Min_Heap_Size;
+    . = . + _Min_Stack_Size;
+    . = ALIGN(8);
+  } >RAM
+
+
+
+  /* Remove information from the standard libraries */
+  /DISCARD/ :
+  {
+    libc.a ( * )
+    libm.a ( * )
+    libgcc.a ( * )
+  }
+
+  .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+

+ 173 - 0
CM4/STM32H745XIHX_RAM.ld

@@ -0,0 +1,173 @@
+/*
+******************************************************************************
+**
+**  File        : LinkerScript.ld (debug in RAM dedicated)
+**
+**  Author      : STM32CubeIDE
+**
+**  Abstract    : Linker script for STM32H7 series
+**                128Kbytes RAM_EXEC and 160Kbytes RAM
+**
+**                Set heap size, stack size and stack location according
+**                to application requirements.
+**
+**                Set memory bank area and size if external memory is used.
+**
+**  Target      : STMicroelectronics STM32
+**
+**  Distribution: The file is distributed as is, without any warranty
+**                of any kind.
+**
+*****************************************************************************
+** @attention
+**
+** Copyright (c) 2022 STMicroelectronics.
+** All rights reserved.
+**
+** This software is licensed under terms that can be found in the LICENSE file
+** in the root directory of this software component.
+** If no LICENSE file comes with this software, it is provided AS-IS.
+**
+****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = ORIGIN(RAM) + LENGTH(RAM);    /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200 ;      /* required amount of heap  */
+_Min_Stack_Size = 0x400 ; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+RAM_EXEC (rx)  : ORIGIN = 0x10000000, LENGTH = 128K
+RAM (xrw)      : ORIGIN = 0x10020000, LENGTH = 160K
+}
+
+/* Define output sections */
+SECTIONS
+{
+  /* The startup code goes first into RAM_EXEC */
+  .isr_vector :
+  {
+    . = ALIGN(4);
+    KEEP(*(.isr_vector)) /* Startup code */
+    . = ALIGN(4);
+  } >RAM_EXEC
+
+  /* The program code and other data goes into RAM_EXEC */
+  .text :
+  {
+    . = ALIGN(4);
+    *(.text)           /* .text sections (code) */
+    *(.text*)          /* .text* sections (code) */
+    *(.glue_7)         /* glue arm to thumb code */
+    *(.glue_7t)        /* glue thumb to arm code */
+    *(.eh_frame)
+    *(.RamFunc)        /* .RamFunc sections */
+    *(.RamFunc*)       /* .RamFunc* sections */
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    . = ALIGN(4);
+    _etext = .;        /* define a global symbols at end of code */
+  } >RAM_EXEC
+
+  /* Constant data goes into RAM_EXEC */
+  .rodata :
+  {
+    . = ALIGN(4);
+    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
+    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
+    . = ALIGN(4);
+  } >RAM_EXEC
+
+  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >RAM_EXEC
+  .ARM : {
+    __exidx_start = .;
+    *(.ARM.exidx*)
+    __exidx_end = .;
+  } >RAM_EXEC
+
+  .preinit_array     :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array*))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  } >RAM_EXEC
+  .init_array :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array*))
+    PROVIDE_HIDDEN (__init_array_end = .);
+  } >RAM_EXEC
+  .fini_array :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(SORT(.fini_array.*)))
+    KEEP (*(.fini_array*))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  } >RAM_EXEC
+
+  /* used by the startup to initialize data */
+  _sidata = LOADADDR(.data);
+
+  /* Initialized data sections goes into RAM, load LMA copy after code */
+  .data :
+  {
+    . = ALIGN(4);
+    _sdata = .;        /* create a global symbol at data start */
+    *(.data)           /* .data sections */
+    *(.data*)          /* .data* sections */
+
+    . = ALIGN(4);
+    _edata = .;        /* define a global symbol at data end */
+  } >RAM AT> RAM_EXEC
+
+
+  /* Uninitialized data section */
+  . = ALIGN(4);
+  .bss :
+  {
+    /* This is used by the startup in order to initialize the .bss section */
+    _sbss = .;         /* define a global symbol at bss start */
+    __bss_start__ = _sbss;
+    *(.bss)
+    *(.bss*)
+    *(COMMON)
+
+    . = ALIGN(4);
+    _ebss = .;         /* define a global symbol at bss end */
+    __bss_end__ = _ebss;
+  } >RAM
+
+  /* User_heap_stack section, used to check that there is enough RAM left */
+  ._user_heap_stack :
+  {
+    . = ALIGN(8);
+    PROVIDE ( end = . );
+    PROVIDE ( _end = . );
+    . = . + _Min_Heap_Size;
+    . = . + _Min_Stack_Size;
+    . = ALIGN(8);
+  } >RAM
+
+
+
+  /* Remove information from the standard libraries */
+  /DISCARD/ :
+  {
+    libc.a ( * )
+    libm.a ( * )
+    libgcc.a ( * )
+  }
+
+  .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+

+ 173 - 0
CM7/Core/Inc/FreeRTOSConfig.h

@@ -0,0 +1,173 @@
+/* USER CODE BEGIN Header */
+/*
+ * FreeRTOS Kernel V10.3.1
+ * Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
+ * Portion Copyright (C) 2019 StMicroelectronics, Inc.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+/* USER CODE END Header */
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * These parameters and more are described within the 'configuration' section of the
+ * FreeRTOS API documentation available on the FreeRTOS.org web site.
+ *
+ * See http://www.freertos.org/a00110.html
+ *----------------------------------------------------------*/
+
+/* USER CODE BEGIN Includes */
+/* Section where include file can be added */
+/* USER CODE END Includes */
+
+/* Ensure definitions are only used by the compiler, and not by the assembler. */
+#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
+  #include <stdint.h>
+  extern uint32_t SystemCoreClock;
+#endif
+#ifndef CMSIS_device_header
+#define CMSIS_device_header "stm32h7xx.h"
+#endif /* CMSIS_device_header */
+
+#define configENABLE_FPU                         0
+#define configENABLE_MPU                         0
+
+#define configUSE_PREEMPTION                     1
+#define configSUPPORT_STATIC_ALLOCATION          1
+#define configSUPPORT_DYNAMIC_ALLOCATION         1
+#define configUSE_IDLE_HOOK                      0
+#define configUSE_TICK_HOOK                      0
+#define configCPU_CLOCK_HZ                       ( SystemCoreClock )
+#define configTICK_RATE_HZ                       ((TickType_t)1000)
+#define configMAX_PRIORITIES                     ( 56 )
+#define configMINIMAL_STACK_SIZE                 ((uint16_t)512)
+#define configTOTAL_HEAP_SIZE                    ((size_t)64*1024)
+#define configMAX_TASK_NAME_LEN                  ( 16 )
+#define configUSE_TRACE_FACILITY                 1
+#define configUSE_16_BIT_TICKS                   0
+#define configUSE_MUTEXES                        1
+#define configQUEUE_REGISTRY_SIZE                8
+#define configCHECK_FOR_STACK_OVERFLOW           1
+#define configUSE_RECURSIVE_MUTEXES              1
+#define configUSE_COUNTING_SEMAPHORES            1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION  0
+/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
+/* Defaults to size_t for backward compatibility, but can be changed
+   if lengths will always be less than the number of bytes in a size_t. */
+#define configMESSAGE_BUFFER_LENGTH_TYPE         size_t
+/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES                    0
+#define configMAX_CO_ROUTINE_PRIORITIES          ( 2 )
+
+/* Software timer definitions. */
+#define configUSE_TIMERS                         1
+#define configTIMER_TASK_PRIORITY                ( 2 )
+#define configTIMER_QUEUE_LENGTH                 10
+#define configTIMER_TASK_STACK_DEPTH             1024
+
+/* The following flag must be enabled only when using newlib */
+#define configUSE_NEWLIB_REENTRANT          1
+
+/* CMSIS-RTOS V2 flags */
+#define configUSE_OS2_THREAD_SUSPEND_RESUME  1
+#define configUSE_OS2_THREAD_ENUMERATE       1
+#define configUSE_OS2_EVENTFLAGS_FROM_ISR    1
+#define configUSE_OS2_THREAD_FLAGS           1
+#define configUSE_OS2_TIMER                  1
+#define configUSE_OS2_MUTEX                  1
+
+/* Set the following definitions to 1 to include the API function, or zero
+to exclude the API function. */
+#define INCLUDE_vTaskPrioritySet             1
+#define INCLUDE_uxTaskPriorityGet            1
+#define INCLUDE_vTaskDelete                  1
+#define INCLUDE_vTaskCleanUpResources        0
+#define INCLUDE_vTaskSuspend                 1
+#define INCLUDE_vTaskDelayUntil              1
+#define INCLUDE_vTaskDelay                   1
+#define INCLUDE_xTaskGetSchedulerState       1
+#define INCLUDE_xTimerPendFunctionCall       1
+#define INCLUDE_xQueueGetMutexHolder         1
+#define INCLUDE_uxTaskGetStackHighWaterMark  1
+#define INCLUDE_xTaskGetCurrentTaskHandle    1
+#define INCLUDE_eTaskGetState                1
+
+/*
+ * The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
+ * by the application thus the correct define need to be enabled below
+ */
+#define USE_FreeRTOS_HEAP_4
+
+/* Cortex-M specific definitions. */
+#ifdef __NVIC_PRIO_BITS
+ /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
+ #define configPRIO_BITS         __NVIC_PRIO_BITS
+#else
+ #define configPRIO_BITS         4
+#endif
+
+/* The lowest interrupt priority that can be used in a call to a "set priority"
+function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY   15
+
+/* The highest interrupt priority that can be used by any interrupt service
+routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
+
+/* Interrupt priorities used by the kernel port layer itself.  These are generic
+to all Cortex-M ports, and do not rely on any particular library functions. */
+#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+/* Normal assert() semantics without relying on the provision of an assert.h
+header file. */
+/* USER CODE BEGIN 1 */
+#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
+/* USER CODE END 1 */
+
+/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
+standard names. */
+#define vPortSVCHandler    SVC_Handler
+#define xPortPendSVHandler PendSV_Handler
+
+/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */
+ #define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0
+
+/* USER CODE BEGIN Defines */
+/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
+/* USER CODE END Defines */
+
+#endif /* FREERTOS_CONFIG_H */

+ 13 - 0
CM7/Core/Inc/echo_server.h

@@ -0,0 +1,13 @@
+/*
+ * echo_server.h
+ *
+ *  Created on: Jun 10, 2024
+ *      Author: jakubski
+ */
+
+#ifndef INC_ECHO_SERVER_H_
+#define INC_ECHO_SERVER_H_
+
+void echo_server_netconn_init(void);
+
+#endif /* INC_ECHO_SERVER_H_ */

+ 106 - 0
CM7/Core/Inc/main.h

@@ -0,0 +1,106 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file           : main.h
+  * @brief          : Header for main.c file.
+  *                   This file contains the common defines of the application.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MAIN_H
+#define __MAIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void Error_Handler(void);
+
+/* USER CODE BEGIN EFP */
+
+/* USER CODE END EFP */
+
+/* Private defines -----------------------------------------------------------*/
+#define MII_TX_EN_Pin GPIO_PIN_11
+#define MII_TX_EN_GPIO_Port GPIOG
+#define OSC32_OUT_Pin GPIO_PIN_15
+#define OSC32_OUT_GPIO_Port GPIOC
+#define OSC32_IN_Pin GPIO_PIN_14
+#define OSC32_IN_GPIO_Port GPIOC
+#define MII_TXD3_Pin GPIO_PIN_2
+#define MII_TXD3_GPIO_Port GPIOE
+#define MII_TXD1_Pin GPIO_PIN_12
+#define MII_TXD1_GPIO_Port GPIOG
+#define MII_TXD0_Pin GPIO_PIN_13
+#define MII_TXD0_GPIO_Port GPIOG
+#define MII_RX_ER_Pin GPIO_PIN_10
+#define MII_RX_ER_GPIO_Port GPIOI
+#define OSC_OUT_Pin GPIO_PIN_1
+#define OSC_OUT_GPIO_Port GPIOH
+#define OSC_IN_Pin GPIO_PIN_0
+#define OSC_IN_GPIO_Port GPIOH
+#define MII_MDC_Pin GPIO_PIN_1
+#define MII_MDC_GPIO_Port GPIOC
+#define MII_TXD2_Pin GPIO_PIN_2
+#define MII_TXD2_GPIO_Port GPIOC
+#define MII_TX_CLK_Pin GPIO_PIN_3
+#define MII_TX_CLK_GPIO_Port GPIOC
+#define MII_MDIO_Pin GPIO_PIN_2
+#define MII_MDIO_GPIO_Port GPIOA
+#define MII_CRS_Pin GPIO_PIN_0
+#define MII_CRS_GPIO_Port GPIOA
+#define MII_RXD0_Pin GPIO_PIN_4
+#define MII_RXD0_GPIO_Port GPIOC
+#define MII_RXD3_Pin GPIO_PIN_1
+#define MII_RXD3_GPIO_Port GPIOB
+#define MII_COL_Pin GPIO_PIN_3
+#define MII_COL_GPIO_Port GPIOA
+#define MII_RXD1_Pin GPIO_PIN_5
+#define MII_RXD1_GPIO_Port GPIOC
+#define MII_RXD2_Pin GPIO_PIN_0
+#define MII_RXD2_GPIO_Port GPIOB
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MAIN_H */

+ 14 - 0
CM7/Core/Inc/mqtt_client.h

@@ -0,0 +1,14 @@
+/*
+ * mqtt_client.h
+ *
+ *  Created on: Jun 10, 2024
+ *      Author: jakubski
+ */
+
+#ifndef INC_MQTT_CLIENT_H_
+#define INC_MQTT_CLIENT_H_
+
+
+void mqtt_cli_init(void);
+
+#endif /* INC_MQTT_CLIENT_H_ */

+ 26 - 0
CM7/Core/Inc/node-red-config.h

@@ -0,0 +1,26 @@
+/*
+ * node-red-config.h
+ *
+ *  Created on: Jun 14, 2024
+ *      Author: jakubski
+ */
+
+#ifndef INC_NODE_RED_CONFIG_H_
+#define INC_NODE_RED_CONFIG_H_
+
+#include "lwip.h"
+
+#define FEATURE_ON 1
+#define FEATURE_OFF 0
+
+#define USE_DHCP LWIP_DHCP // LWIP_DHCP defined in lwipopts.h
+#define DHCP_USER_LOGS FEATURE_ON
+// Static IP for cases when DHCP is not used or fails.
+#define STATIC_IP	"192.168.1.10"
+#define STATIC_GW	"192.168.1.0"
+#define STATIC_MASK "255.255.255.0"
+
+#define BROKER_IP	"192.168.1.34"
+#define MQTT_PORT	1883
+
+#endif /* INC_NODE_RED_CONFIG_H_ */

+ 510 - 0
CM7/Core/Inc/stm32h7xx_hal_conf.h

@@ -0,0 +1,510 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_hal_conf.h
+  * @author  MCD Application Team
+  * @brief   HAL configuration file.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32H7xx_HAL_CONF_H
+#define STM32H7xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+  * @brief This is the list of modules to be used in the HAL driver
+  */
+#define HAL_MODULE_ENABLED
+
+  /* #define HAL_ADC_MODULE_ENABLED   */
+/* #define HAL_FDCAN_MODULE_ENABLED   */
+/* #define HAL_FMAC_MODULE_ENABLED   */
+/* #define HAL_CEC_MODULE_ENABLED   */
+/* #define HAL_COMP_MODULE_ENABLED   */
+/* #define HAL_CORDIC_MODULE_ENABLED   */
+/* #define HAL_CRC_MODULE_ENABLED   */
+/* #define HAL_CRYP_MODULE_ENABLED   */
+/* #define HAL_DAC_MODULE_ENABLED   */
+/* #define HAL_DCMI_MODULE_ENABLED   */
+/* #define HAL_DMA2D_MODULE_ENABLED   */
+#define HAL_ETH_MODULE_ENABLED
+/* #define HAL_NAND_MODULE_ENABLED   */
+/* #define HAL_NOR_MODULE_ENABLED   */
+/* #define HAL_OTFDEC_MODULE_ENABLED   */
+/* #define HAL_SRAM_MODULE_ENABLED   */
+/* #define HAL_SDRAM_MODULE_ENABLED   */
+/* #define HAL_HASH_MODULE_ENABLED   */
+/* #define HAL_HRTIM_MODULE_ENABLED   */
+/* #define HAL_HSEM_MODULE_ENABLED   */
+/* #define HAL_GFXMMU_MODULE_ENABLED   */
+/* #define HAL_JPEG_MODULE_ENABLED   */
+/* #define HAL_OPAMP_MODULE_ENABLED   */
+/* #define HAL_OSPI_MODULE_ENABLED   */
+/* #define HAL_OSPI_MODULE_ENABLED   */
+/* #define HAL_I2S_MODULE_ENABLED   */
+/* #define HAL_SMBUS_MODULE_ENABLED   */
+/* #define HAL_IWDG_MODULE_ENABLED   */
+/* #define HAL_LPTIM_MODULE_ENABLED   */
+/* #define HAL_LTDC_MODULE_ENABLED   */
+/* #define HAL_QSPI_MODULE_ENABLED   */
+/* #define HAL_RAMECC_MODULE_ENABLED   */
+/* #define HAL_RNG_MODULE_ENABLED   */
+/* #define HAL_RTC_MODULE_ENABLED   */
+/* #define HAL_SAI_MODULE_ENABLED   */
+/* #define HAL_SD_MODULE_ENABLED   */
+/* #define HAL_MMC_MODULE_ENABLED   */
+/* #define HAL_SPDIFRX_MODULE_ENABLED   */
+/* #define HAL_SPI_MODULE_ENABLED   */
+/* #define HAL_SWPMI_MODULE_ENABLED   */
+#define HAL_TIM_MODULE_ENABLED
+/* #define HAL_UART_MODULE_ENABLED   */
+/* #define HAL_USART_MODULE_ENABLED   */
+/* #define HAL_IRDA_MODULE_ENABLED   */
+/* #define HAL_SMARTCARD_MODULE_ENABLED   */
+/* #define HAL_WWDG_MODULE_ENABLED   */
+/* #define HAL_PCD_MODULE_ENABLED   */
+/* #define HAL_HCD_MODULE_ENABLED   */
+/* #define HAL_DFSDM_MODULE_ENABLED   */
+/* #define HAL_DSI_MODULE_ENABLED   */
+/* #define HAL_JPEG_MODULE_ENABLED   */
+/* #define HAL_MDIOS_MODULE_ENABLED   */
+/* #define HAL_PSSI_MODULE_ENABLED   */
+/* #define HAL_DTS_MODULE_ENABLED   */
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_MDMA_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+#define HAL_HSEM_MODULE_ENABLED
+
+/* ########################## Oscillator Values adaptation ####################*/
+/**
+  * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+  *        This value is used by the RCC HAL module to compute the system frequency
+  *        (when HSE is used as system clock source, directly or through the PLL).
+  */
+#if !defined  (HSE_VALUE)
+#define HSE_VALUE    (25000000UL) /*!< Value of the External oscillator in Hz : FPGA case fixed to 60MHZ */
+#endif /* HSE_VALUE */
+
+#if !defined  (HSE_STARTUP_TIMEOUT)
+  #define HSE_STARTUP_TIMEOUT    (100UL)   /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+  * @brief Internal  oscillator (CSI) default value.
+  *        This value is the default CSI value after Reset.
+  */
+#if !defined  (CSI_VALUE)
+  #define CSI_VALUE    (4000000UL) /*!< Value of the Internal oscillator in Hz*/
+#endif /* CSI_VALUE */
+
+/**
+  * @brief Internal High Speed oscillator (HSI) value.
+  *        This value is used by the RCC HAL module to compute the system frequency
+  *        (when HSI is used as system clock source, directly or through the PLL).
+  */
+#if !defined  (HSI_VALUE)
+  #define HSI_VALUE    (64000000UL) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+  * @brief External Low Speed oscillator (LSE) value.
+  *        This value is used by the UART, RTC HAL module to compute the system frequency
+  */
+#if !defined  (LSE_VALUE)
+  #define LSE_VALUE    (32768UL) /*!< Value of the External oscillator in Hz*/
+#endif /* LSE_VALUE */
+
+#if !defined  (LSE_STARTUP_TIMEOUT)
+  #define LSE_STARTUP_TIMEOUT    (5000UL)   /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+#if !defined  (LSI_VALUE)
+  #define LSI_VALUE  (32000UL)              /*!< LSI Typical Value in Hz*/
+#endif /* LSI_VALUE */                      /*!< Value of the Internal Low Speed oscillator in Hz
+                                              The real value may vary depending on the variations
+                                              in voltage and temperature.*/
+
+/**
+  * @brief External clock source for I2S peripheral
+  *        This value is used by the I2S HAL module to compute the I2S clock source
+  *        frequency, this source is inserted directly through I2S_CKIN pad.
+  */
+#if !defined  (EXTERNAL_CLOCK_VALUE)
+  #define EXTERNAL_CLOCK_VALUE    12288000UL /*!< Value of the External clock in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+   ===  you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+  * @brief This is the HAL system configuration section
+  */
+#define  VDD_VALUE                    (3300UL) /*!< Value of VDD in mv */
+#define  TICK_INT_PRIORITY            (15UL) /*!< tick interrupt priority */
+#define  USE_RTOS                     0
+#define  USE_SD_TRANSCEIVER           0U               /*!< use uSD Transceiver */
+#define  USE_SPI_CRC	              0U               /*!< use CRC in SPI */
+
+#define  USE_HAL_ADC_REGISTER_CALLBACKS     0U /* ADC register callback disabled     */
+#define  USE_HAL_CEC_REGISTER_CALLBACKS     0U /* CEC register callback disabled     */
+#define  USE_HAL_COMP_REGISTER_CALLBACKS    0U /* COMP register callback disabled    */
+#define  USE_HAL_CORDIC_REGISTER_CALLBACKS  0U /* CORDIC register callback disabled  */
+#define  USE_HAL_CRYP_REGISTER_CALLBACKS    0U /* CRYP register callback disabled    */
+#define  USE_HAL_DAC_REGISTER_CALLBACKS     0U /* DAC register callback disabled     */
+#define  USE_HAL_DCMI_REGISTER_CALLBACKS    0U /* DCMI register callback disabled    */
+#define  USE_HAL_DFSDM_REGISTER_CALLBACKS   0U /* DFSDM register callback disabled   */
+#define  USE_HAL_DMA2D_REGISTER_CALLBACKS   0U /* DMA2D register callback disabled   */
+#define  USE_HAL_DSI_REGISTER_CALLBACKS     0U /* DSI register callback disabled     */
+#define  USE_HAL_DTS_REGISTER_CALLBACKS     0U /* DTS register callback disabled     */
+#define  USE_HAL_ETH_REGISTER_CALLBACKS     0U /* ETH register callback disabled     */
+#define  USE_HAL_FDCAN_REGISTER_CALLBACKS   0U /* FDCAN register callback disabled   */
+#define  USE_HAL_FMAC_REGISTER_CALLBACKS    0U /* FMAC register callback disabled  */
+#define  USE_HAL_NAND_REGISTER_CALLBACKS    0U /* NAND register callback disabled    */
+#define  USE_HAL_NOR_REGISTER_CALLBACKS     0U /* NOR register callback disabled     */
+#define  USE_HAL_SDRAM_REGISTER_CALLBACKS   0U /* SDRAM register callback disabled   */
+#define  USE_HAL_SRAM_REGISTER_CALLBACKS    0U /* SRAM register callback disabled    */
+#define  USE_HAL_HASH_REGISTER_CALLBACKS    0U /* HASH register callback disabled    */
+#define  USE_HAL_HCD_REGISTER_CALLBACKS     0U /* HCD register callback disabled     */
+#define  USE_HAL_GFXMMU_REGISTER_CALLBACKS  0U /* GFXMMU register callback disabled  */
+#define  USE_HAL_HRTIM_REGISTER_CALLBACKS   0U /* HRTIM register callback disabled   */
+#define  USE_HAL_I2C_REGISTER_CALLBACKS     0U /* I2C register callback disabled     */
+#define  USE_HAL_I2S_REGISTER_CALLBACKS     0U /* I2S register callback disabled     */
+#define  USE_HAL_IRDA_REGISTER_CALLBACKS    0U /* IRDA register callback disabled    */
+#define  USE_HAL_JPEG_REGISTER_CALLBACKS    0U /* JPEG register callback disabled    */
+#define  USE_HAL_LPTIM_REGISTER_CALLBACKS   0U /* LPTIM register callback disabled   */
+#define  USE_HAL_LTDC_REGISTER_CALLBACKS    0U /* LTDC register callback disabled    */
+#define  USE_HAL_MDIOS_REGISTER_CALLBACKS   0U /* MDIO register callback disabled    */
+#define  USE_HAL_MMC_REGISTER_CALLBACKS     0U /* MMC register callback disabled     */
+#define  USE_HAL_OPAMP_REGISTER_CALLBACKS   0U /* MDIO register callback disabled    */
+#define  USE_HAL_OSPI_REGISTER_CALLBACKS    0U /* OSPI register callback disabled    */
+#define  USE_HAL_OTFDEC_REGISTER_CALLBACKS  0U /* OTFDEC register callback disabled  */
+#define  USE_HAL_PCD_REGISTER_CALLBACKS     0U /* PCD register callback disabled     */
+#define  USE_HAL_QSPI_REGISTER_CALLBACKS    0U /* QSPI register callback disabled    */
+#define  USE_HAL_RNG_REGISTER_CALLBACKS     0U /* RNG register callback disabled     */
+#define  USE_HAL_RTC_REGISTER_CALLBACKS     0U /* RTC register callback disabled     */
+#define  USE_HAL_SAI_REGISTER_CALLBACKS     0U /* SAI register callback disabled     */
+#define  USE_HAL_SD_REGISTER_CALLBACKS      0U /* SD register callback disabled      */
+#define  USE_HAL_SMARTCARD_REGISTER_CALLBACKS  0U /* SMARTCARD register callback disabled */
+#define  USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
+#define  USE_HAL_SMBUS_REGISTER_CALLBACKS   0U /* SMBUS register callback disabled   */
+#define  USE_HAL_SPI_REGISTER_CALLBACKS     0U /* SPI register callback disabled     */
+#define  USE_HAL_SWPMI_REGISTER_CALLBACKS   0U /* SWPMI register callback disabled   */
+#define  USE_HAL_TIM_REGISTER_CALLBACKS     0U /* TIM register callback disabled     */
+#define  USE_HAL_UART_REGISTER_CALLBACKS    0U /* UART register callback disabled    */
+#define  USE_HAL_USART_REGISTER_CALLBACKS   0U /* USART register callback disabled   */
+#define  USE_HAL_WWDG_REGISTER_CALLBACKS    0U /* WWDG register callback disabled    */
+
+/* ########################### Ethernet Configuration ######################### */
+#define ETH_TX_DESC_CNT         4  /* number of Ethernet Tx DMA descriptors */
+#define ETH_RX_DESC_CNT         4  /* number of Ethernet Rx DMA descriptors */
+
+#define ETH_MAC_ADDR0    (0x02UL)
+#define ETH_MAC_ADDR1    (0x00UL)
+#define ETH_MAC_ADDR2    (0x00UL)
+#define ETH_MAC_ADDR3    (0x00UL)
+#define ETH_MAC_ADDR4    (0x00UL)
+#define ETH_MAC_ADDR5    (0x00UL)
+
+/* ########################## Assert Selection ############################## */
+/**
+  * @brief Uncomment the line below to expanse the "assert_param" macro in the
+  *        HAL drivers code
+  */
+/* #define USE_FULL_ASSERT    1U */
+
+/* Includes ------------------------------------------------------------------*/
+/**
+  * @brief Include module's header file
+  */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+  #include "stm32h7xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+  #include "stm32h7xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+  #include "stm32h7xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_MDMA_MODULE_ENABLED
+ #include "stm32h7xx_hal_mdma.h"
+#endif /* HAL_MDMA_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+  #include "stm32h7xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+  #include "stm32h7xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+  #include "stm32h7xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DSI_MODULE_ENABLED
+  #include "stm32h7xx_hal_dsi.h"
+#endif /* HAL_DSI_MODULE_ENABLED */
+
+#ifdef HAL_DFSDM_MODULE_ENABLED
+  #include "stm32h7xx_hal_dfsdm.h"
+#endif /* HAL_DFSDM_MODULE_ENABLED */
+
+#ifdef HAL_DTS_MODULE_ENABLED
+ #include "stm32h7xx_hal_dts.h"
+#endif /* HAL_DTS_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+  #include "stm32h7xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_EXTI_MODULE_ENABLED
+  #include "stm32h7xx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+  #include "stm32h7xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+  #include "stm32h7xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_FDCAN_MODULE_ENABLED
+  #include "stm32h7xx_hal_fdcan.h"
+#endif /* HAL_FDCAN_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+  #include "stm32h7xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_COMP_MODULE_ENABLED
+  #include "stm32h7xx_hal_comp.h"
+#endif /* HAL_COMP_MODULE_ENABLED */
+
+#ifdef HAL_CORDIC_MODULE_ENABLED
+  #include "stm32h7xx_hal_cordic.h"
+#endif /* HAL_CORDIC_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+  #include "stm32h7xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+  #include "stm32h7xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+  #include "stm32h7xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+  #include "stm32h7xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_GFXMMU_MODULE_ENABLED
+  #include "stm32h7xx_hal_gfxmmu.h"
+#endif /* HAL_GFXMMU_MODULE_ENABLED */
+
+#ifdef HAL_FMAC_MODULE_ENABLED
+  #include "stm32h7xx_hal_fmac.h"
+#endif /* HAL_FMAC_MODULE_ENABLED */
+
+#ifdef HAL_HRTIM_MODULE_ENABLED
+  #include "stm32h7xx_hal_hrtim.h"
+#endif /* HAL_HRTIM_MODULE_ENABLED */
+
+#ifdef HAL_HSEM_MODULE_ENABLED
+  #include "stm32h7xx_hal_hsem.h"
+#endif /* HAL_HSEM_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+  #include "stm32h7xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+  #include "stm32h7xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+  #include "stm32h7xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32h7xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32h7xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32h7xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_JPEG_MODULE_ENABLED
+ #include "stm32h7xx_hal_jpeg.h"
+#endif /* HAL_JPEG_MODULE_ENABLED */
+
+#ifdef HAL_MDIOS_MODULE_ENABLED
+ #include "stm32h7xx_hal_mdios.h"
+#endif /* HAL_MDIOS_MODULE_ENABLED */
+
+#ifdef HAL_MMC_MODULE_ENABLED
+ #include "stm32h7xx_hal_mmc.h"
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+#ifdef HAL_LPTIM_MODULE_ENABLED
+#include "stm32h7xx_hal_lptim.h"
+#endif /* HAL_LPTIM_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+#include "stm32h7xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_OPAMP_MODULE_ENABLED
+#include "stm32h7xx_hal_opamp.h"
+#endif /* HAL_OPAMP_MODULE_ENABLED */
+
+#ifdef HAL_OSPI_MODULE_ENABLED
+ #include "stm32h7xx_hal_ospi.h"
+#endif /* HAL_OSPI_MODULE_ENABLED */
+
+#ifdef HAL_OTFDEC_MODULE_ENABLED
+#include "stm32h7xx_hal_otfdec.h"
+#endif /* HAL_OTFDEC_MODULE_ENABLED */
+
+#ifdef HAL_PSSI_MODULE_ENABLED
+ #include "stm32h7xx_hal_pssi.h"
+#endif /* HAL_PSSI_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32h7xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_QSPI_MODULE_ENABLED
+ #include "stm32h7xx_hal_qspi.h"
+#endif /* HAL_QSPI_MODULE_ENABLED */
+
+#ifdef HAL_RAMECC_MODULE_ENABLED
+ #include "stm32h7xx_hal_ramecc.h"
+#endif /* HAL_RAMECC_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32h7xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32h7xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32h7xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32h7xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32h7xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32h7xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_SPDIFRX_MODULE_ENABLED
+ #include "stm32h7xx_hal_spdifrx.h"
+#endif /* HAL_SPDIFRX_MODULE_ENABLED */
+
+#ifdef HAL_SWPMI_MODULE_ENABLED
+ #include "stm32h7xx_hal_swpmi.h"
+#endif /* HAL_SWPMI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32h7xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32h7xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32h7xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32h7xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32h7xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_SMBUS_MODULE_ENABLED
+ #include "stm32h7xx_hal_smbus.h"
+#endif /* HAL_SMBUS_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32h7xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32h7xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32h7xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef  USE_FULL_ASSERT
+/**
+  * @brief  The assert_param macro is used for function's parameters check.
+  * @param  expr: If expr is false, it calls assert_failed function
+  *         which reports the name of the source file and the source
+  *         line number of the call that failed.
+  *         If expr is true, it returns no value.
+  * @retval None
+  */
+  #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+  void assert_failed(uint8_t *file, uint32_t line);
+#else
+  #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32H7xx_HAL_CONF_H */

+ 65 - 0
CM7/Core/Inc/stm32h7xx_it.h

@@ -0,0 +1,65 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_it.h
+  * @brief   This file contains the headers of the interrupt handlers.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+ ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32H7xx_IT_H
+#define __STM32H7xx_IT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void DebugMon_Handler(void);
+void TIM6_DAC_IRQHandler(void);
+void ETH_IRQHandler(void);
+/* USER CODE BEGIN EFP */
+
+/* USER CODE END EFP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32H7xx_IT_H */

+ 74 - 0
CM7/Core/Src/echo_server.c

@@ -0,0 +1,74 @@
+/*
+ * echo_server.c
+ *
+ *  Created on: Jun 9, 2024
+ *      Author: jakubski
+ */
+#include <stdio.h>
+
+#include "lwip/opt.h"
+#include "lwip/arch.h"
+#include "lwip/api.h"
+
+#include "cmsis_os.h"
+#define ECHOSERVER_THREAD_PRIO    ( tskIDLE_PRIORITY + 4 )
+
+void echo_server_thread(void *arg)
+{
+	struct netconn *conn, *newconn;
+	err_t err, recv_err;
+	struct netbuf *inbuf;
+	void *data;
+	u16_t len;
+	LWIP_UNUSED_ARG(arg);
+
+	/* Create a new TCP connection handle */
+	/* Bind to port 80 (HTTP) with default IP address */
+	conn = netconn_new(NETCONN_TCP);
+	LWIP_ERROR("echo_server: invalid conn", (conn != NULL), return;);
+
+	err = netconn_bind(conn, IP_ADDR_ANY, 7);
+	if (err == ERR_OK)
+	{
+		/* Put the connection into LISTEN state */
+		netconn_listen(conn);
+
+		do
+		{
+			err = netconn_accept(conn, &newconn);
+			if (err == ERR_OK)
+			{
+				while (( recv_err = netconn_recv(newconn, &inbuf)) == ERR_OK)
+				{
+					do
+					{
+						netbuf_data(inbuf, &data, &len);
+						netconn_write(newconn, data, len, NETCONN_COPY);
+						printf("Echoed %d bytes\r\n", len);
+						fflush(stdout);
+					}
+					while (netbuf_next(inbuf) >= 0);
+
+					netbuf_delete(inbuf);
+				}
+				netconn_close(newconn);
+				netconn_delete(newconn);
+			}
+			else
+			{
+				netconn_delete(newconn);
+			}
+		}
+		while (err == ERR_OK);
+
+//		LWIP_DEBUGF(HTTPD_DEBUG, ("echo_server_netconn_thread: netconn_accept received error %d, shutting down", err));
+		netconn_close(conn);
+		netconn_delete(conn);
+	}
+}
+
+/** Initialize the ECHO server (start its thread) */
+void echo_server_netconn_init(void)
+{
+  sys_thread_new("echo_server_netconn", echo_server_thread, NULL, DEFAULT_THREAD_STACKSIZE, ECHOSERVER_THREAD_PRIO);
+}

+ 72 - 0
CM7/Core/Src/freertos.c

@@ -0,0 +1,72 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * File Name          : freertos.c
+  * Description        : Code for freertos applications
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "FreeRTOS.h"
+#include "task.h"
+#include "main.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN PTD */
+
+/* USER CODE END PTD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN Variables */
+
+/* USER CODE END Variables */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN FunctionPrototypes */
+
+/* USER CODE END FunctionPrototypes */
+
+/* Hook prototypes */
+void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName);
+
+/* USER CODE BEGIN 4 */
+void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName)
+{
+   /* ETH_CODE: add breakpoint when stack oveflow is detected by FreeRTOS.
+	* Useful for debugging issues.
+	*/
+   __BKPT(0);
+}
+/* USER CODE END 4 */
+
+/* Private application code --------------------------------------------------*/
+/* USER CODE BEGIN Application */
+
+/* USER CODE END Application */
+

+ 841 - 0
CM7/Core/Src/lwiperf.c

@@ -0,0 +1,841 @@
+/**
+ * @file
+ * lwIP iPerf server implementation
+ */
+
+/**
+ * @defgroup iperf Iperf server
+ * @ingroup apps
+ *
+ * This is a simple performance measuring client/server to check your bandwith using
+ * iPerf2 on a PC as server/client.
+ * It is currently a minimal implementation providing a TCP client/server only.
+ *
+ * @todo:
+ * - implement UDP mode
+ * - protect combined sessions handling (via 'related_master_state') against reallocation
+ *   (this is a pointer address, currently, so if the same memory is allocated again,
+ *    session pairs (tx/rx) can be confused on reallocation)
+ */
+
+/*
+ * Copyright (c) 2014 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt
+ */
+
+#include "lwip/apps/lwiperf.h"
+
+#include "lwip/tcp.h"
+#include "lwip/sys.h"
+
+#include <string.h>
+
+/* Currently, only TCP is implemented */
+#if LWIP_TCP && LWIP_CALLBACK_API
+
+/** Specify the idle timeout (in seconds) after that the test fails */
+#ifndef LWIPERF_TCP_MAX_IDLE_SEC
+#define LWIPERF_TCP_MAX_IDLE_SEC    10U
+#endif
+#if LWIPERF_TCP_MAX_IDLE_SEC > 255
+#error LWIPERF_TCP_MAX_IDLE_SEC must fit into an u8_t
+#endif
+
+/** Change this if you don't want to lwiperf to listen to any IP version */
+#ifndef LWIPERF_SERVER_IP_TYPE
+#define LWIPERF_SERVER_IP_TYPE      IPADDR_TYPE_ANY
+#endif
+
+/* File internal memory allocation (struct lwiperf_*): this defaults to
+   the heap */
+#ifndef LWIPERF_ALLOC
+#define LWIPERF_ALLOC(type)         mem_malloc(sizeof(type))
+#define LWIPERF_FREE(type, item)    mem_free(item)
+#endif
+
+/** If this is 1, check that received data has the correct format */
+#ifndef LWIPERF_CHECK_RX_DATA
+#define LWIPERF_CHECK_RX_DATA       0
+#endif
+
+/** This is the Iperf settings struct sent from the client */
+typedef struct _lwiperf_settings {
+#define LWIPERF_FLAGS_ANSWER_TEST 0x80000000
+#define LWIPERF_FLAGS_ANSWER_NOW  0x00000001
+  u32_t flags;
+  u32_t num_threads; /* unused for now */
+  u32_t remote_port;
+  u32_t buffer_len; /* unused for now */
+  u32_t win_band; /* TCP window / UDP rate: unused for now */
+  u32_t amount; /* pos. value: bytes?; neg. values: time (unit is 10ms: 1/100 second) */
+} lwiperf_settings_t;
+
+/** Basic connection handle */
+struct _lwiperf_state_base;
+typedef struct _lwiperf_state_base lwiperf_state_base_t;
+struct _lwiperf_state_base {
+  /* linked list */
+  lwiperf_state_base_t *next;
+  /* 1=tcp, 0=udp */
+  u8_t tcp;
+  /* 1=server, 0=client */
+  u8_t server;
+  /* master state used to abort sessions (e.g. listener, main client) */
+  lwiperf_state_base_t *related_master_state;
+};
+
+/** Connection handle for a TCP iperf session */
+typedef struct _lwiperf_state_tcp {
+  lwiperf_state_base_t base;
+  struct tcp_pcb *server_pcb;
+  struct tcp_pcb *conn_pcb;
+  u32_t time_started;
+  lwiperf_report_fn report_fn;
+  void *report_arg;
+  u8_t poll_count;
+  u8_t next_num;
+  /* 1=start server when client is closed */
+  u8_t client_tradeoff_mode;
+  u32_t bytes_transferred;
+  lwiperf_settings_t settings;
+  u8_t have_settings_buf;
+  u8_t specific_remote;
+  ip_addr_t remote_addr;
+} lwiperf_state_tcp_t;
+
+/** List of active iperf sessions */
+static lwiperf_state_base_t *lwiperf_all_connections;
+/** A const buffer to send from: we want to measure sending, not copying! */
+static const u8_t lwiperf_txbuf_const[1600] = {
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+};
+
+static err_t lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb);
+static void lwiperf_tcp_err(void *arg, err_t err);
+static err_t lwiperf_start_tcp_server_impl(const ip_addr_t *local_addr, u16_t local_port,
+                                           lwiperf_report_fn report_fn, void *report_arg,
+                                           lwiperf_state_base_t *related_master_state, lwiperf_state_tcp_t **state);
+
+
+/** Add an iperf session to the 'active' list */
+static void
+lwiperf_list_add(lwiperf_state_base_t *item)
+{
+  item->next = lwiperf_all_connections;
+  lwiperf_all_connections = item;
+}
+
+/** Remove an iperf session from the 'active' list */
+static void
+lwiperf_list_remove(lwiperf_state_base_t *item)
+{
+  lwiperf_state_base_t *prev = NULL;
+  lwiperf_state_base_t *iter;
+  for (iter = lwiperf_all_connections; iter != NULL; prev = iter, iter = iter->next) {
+    if (iter == item) {
+      if (prev == NULL) {
+        lwiperf_all_connections = iter->next;
+      } else {
+        prev->next = iter->next;
+      }
+      /* @debug: ensure this item is listed only once */
+      for (iter = iter->next; iter != NULL; iter = iter->next) {
+        LWIP_ASSERT("duplicate entry", iter != item);
+      }
+      break;
+    }
+  }
+}
+
+static lwiperf_state_base_t *
+lwiperf_list_find(lwiperf_state_base_t *item)
+{
+  lwiperf_state_base_t *iter;
+  for (iter = lwiperf_all_connections; iter != NULL; iter = iter->next) {
+    if (iter == item) {
+      return item;
+    }
+  }
+  return NULL;
+}
+
+/** Call the report function of an iperf tcp session */
+static void
+lwip_tcp_conn_report(lwiperf_state_tcp_t *conn, enum lwiperf_report_type report_type)
+{
+  if ((conn != NULL) && (conn->report_fn != NULL)) {
+    u32_t now, duration_ms, bandwidth_kbitpsec;
+    now = sys_now();
+    duration_ms = now - conn->time_started;
+    if (duration_ms == 0) {
+      bandwidth_kbitpsec = 0;
+    } else {
+      bandwidth_kbitpsec = (conn->bytes_transferred / duration_ms) * 8U;
+    }
+    conn->report_fn(conn->report_arg, report_type,
+                    &conn->conn_pcb->local_ip, conn->conn_pcb->local_port,
+                    &conn->conn_pcb->remote_ip, conn->conn_pcb->remote_port,
+                    conn->bytes_transferred, duration_ms, bandwidth_kbitpsec);
+  }
+}
+
+/** Close an iperf tcp session */
+static void
+lwiperf_tcp_close(lwiperf_state_tcp_t *conn, enum lwiperf_report_type report_type)
+{
+  err_t err;
+
+  lwiperf_list_remove(&conn->base);
+  lwip_tcp_conn_report(conn, report_type);
+  if (conn->conn_pcb != NULL) {
+    tcp_arg(conn->conn_pcb, NULL);
+    tcp_poll(conn->conn_pcb, NULL, 0);
+    tcp_sent(conn->conn_pcb, NULL);
+    tcp_recv(conn->conn_pcb, NULL);
+    tcp_err(conn->conn_pcb, NULL);
+    err = tcp_close(conn->conn_pcb);
+    if (err != ERR_OK) {
+      /* don't want to wait for free memory here... */
+      tcp_abort(conn->conn_pcb);
+    }
+  } else {
+    /* no conn pcb, this is the listener pcb */
+    err = tcp_close(conn->server_pcb);
+    LWIP_ASSERT("error", err == ERR_OK);
+  }
+  LWIPERF_FREE(lwiperf_state_tcp_t, conn);
+}
+
+/** Try to send more data on an iperf tcp session */
+static err_t
+lwiperf_tcp_client_send_more(lwiperf_state_tcp_t *conn)
+{
+  int send_more;
+  err_t err;
+  u16_t txlen;
+  u16_t txlen_max;
+  void *txptr;
+  u8_t apiflags;
+
+  LWIP_ASSERT("conn invalid", (conn != NULL) && conn->base.tcp && (conn->base.server == 0));
+
+  do {
+    send_more = 0;
+    if (conn->settings.amount & PP_HTONL(0x80000000)) {
+      /* this session is time-limited */
+      u32_t now = sys_now();
+      u32_t diff_ms = now - conn->time_started;
+      u32_t time = (u32_t) - (s32_t)lwip_htonl(conn->settings.amount);
+      u32_t time_ms = time * 10;
+      if (diff_ms >= time_ms) {
+        /* time specified by the client is over -> close the connection */
+        lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT);
+        return ERR_OK;
+      }
+    } else {
+      /* this session is byte-limited */
+      u32_t amount_bytes = lwip_htonl(conn->settings.amount);
+      /* @todo: this can send up to 1*MSS more than requested... */
+      if (amount_bytes >= conn->bytes_transferred) {
+        /* all requested bytes transferred -> close the connection */
+        lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT);
+        return ERR_OK;
+      }
+    }
+
+    if (conn->bytes_transferred < 24) {
+      /* transmit the settings a first time */
+      txptr = &((u8_t *)&conn->settings)[conn->bytes_transferred];
+      txlen_max = (u16_t)(24 - conn->bytes_transferred);
+      apiflags = TCP_WRITE_FLAG_COPY;
+    } else if (conn->bytes_transferred < 48) {
+      /* transmit the settings a second time */
+      txptr = &((u8_t *)&conn->settings)[conn->bytes_transferred - 24];
+      txlen_max = (u16_t)(48 - conn->bytes_transferred);
+      apiflags = TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE;
+      send_more = 1;
+    } else {
+      /* transmit data */
+      /* @todo: every x bytes, transmit the settings again */
+      txptr = LWIP_CONST_CAST(void *, &lwiperf_txbuf_const[conn->bytes_transferred % 10]);
+      txlen_max = TCP_MSS;
+      if (conn->bytes_transferred == 48) { /* @todo: fix this for intermediate settings, too */
+        txlen_max = TCP_MSS - 24;
+      }
+      apiflags = 0; /* no copying needed */
+      send_more = 1;
+    }
+    txlen = txlen_max;
+    do {
+      err = tcp_write(conn->conn_pcb, txptr, txlen, apiflags);
+      if (err ==  ERR_MEM) {
+        txlen /= 2;
+      }
+    } while ((err == ERR_MEM) && (txlen >= (TCP_MSS / 2)));
+
+    if (err == ERR_OK) {
+      conn->bytes_transferred += txlen;
+    } else {
+      send_more = 0;
+    }
+  } while (send_more);
+
+  tcp_output(conn->conn_pcb);
+  return ERR_OK;
+}
+
+/** TCP sent callback, try to send more data */
+static err_t
+lwiperf_tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
+{
+  lwiperf_state_tcp_t *conn = (lwiperf_state_tcp_t *)arg;
+  /* @todo: check 'len' (e.g. to time ACK of all data)? for now, we just send more... */
+  LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb);
+  LWIP_UNUSED_ARG(tpcb);
+  LWIP_UNUSED_ARG(len);
+
+  conn->poll_count = 0;
+
+  return lwiperf_tcp_client_send_more(conn);
+}
+
+/** TCP connected callback (active connection), send data now */
+static err_t
+lwiperf_tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
+{
+  lwiperf_state_tcp_t *conn = (lwiperf_state_tcp_t *)arg;
+  LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb);
+  LWIP_UNUSED_ARG(tpcb);
+  if (err != ERR_OK) {
+    lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
+    return ERR_OK;
+  }
+  conn->poll_count = 0;
+  conn->time_started = sys_now();
+  return lwiperf_tcp_client_send_more(conn);
+}
+
+/** Start TCP connection back to the client (either parallel or after the
+ * receive test has finished.
+ */
+static err_t
+lwiperf_tx_start_impl(const ip_addr_t *remote_ip, u16_t remote_port, lwiperf_settings_t *settings, lwiperf_report_fn report_fn,
+                      void *report_arg, lwiperf_state_base_t *related_master_state, lwiperf_state_tcp_t **new_conn)
+{
+  err_t err;
+  lwiperf_state_tcp_t *client_conn;
+  struct tcp_pcb *newpcb;
+  ip_addr_t remote_addr;
+
+  LWIP_ASSERT("remote_ip != NULL", remote_ip != NULL);
+  LWIP_ASSERT("remote_ip != NULL", settings != NULL);
+  LWIP_ASSERT("new_conn != NULL", new_conn != NULL);
+  *new_conn = NULL;
+
+  client_conn = (lwiperf_state_tcp_t *)LWIPERF_ALLOC(lwiperf_state_tcp_t);
+  if (client_conn == NULL) {
+    return ERR_MEM;
+  }
+  newpcb = tcp_new_ip_type(IP_GET_TYPE(remote_ip));
+  if (newpcb == NULL) {
+    LWIPERF_FREE(lwiperf_state_tcp_t, client_conn);
+    return ERR_MEM;
+  }
+  memset(client_conn, 0, sizeof(lwiperf_state_tcp_t));
+  client_conn->base.tcp = 1;
+  client_conn->base.related_master_state = related_master_state;
+  client_conn->conn_pcb = newpcb;
+  client_conn->time_started = sys_now(); /* @todo: set this again on 'connected' */
+  client_conn->report_fn = report_fn;
+  client_conn->report_arg = report_arg;
+  client_conn->next_num = 4; /* initial nr is '4' since the header has 24 byte */
+  client_conn->bytes_transferred = 0;
+  memcpy(&client_conn->settings, settings, sizeof(*settings));
+  client_conn->have_settings_buf = 1;
+
+  tcp_arg(newpcb, client_conn);
+  tcp_sent(newpcb, lwiperf_tcp_client_sent);
+  tcp_poll(newpcb, lwiperf_tcp_poll, 2U);
+  tcp_err(newpcb, lwiperf_tcp_err);
+
+  ip_addr_copy(remote_addr, *remote_ip);
+
+  err = tcp_connect(newpcb, &remote_addr, remote_port, lwiperf_tcp_client_connected);
+  if (err != ERR_OK) {
+    lwiperf_tcp_close(client_conn, LWIPERF_TCP_ABORTED_LOCAL);
+    return err;
+  }
+  lwiperf_list_add(&client_conn->base);
+  *new_conn = client_conn;
+  return ERR_OK;
+}
+
+static err_t
+lwiperf_tx_start_passive(lwiperf_state_tcp_t *conn)
+{
+  err_t ret;
+  lwiperf_state_tcp_t *new_conn = NULL;
+  u16_t remote_port = (u16_t)lwip_htonl(conn->settings.remote_port);
+
+  ret = lwiperf_tx_start_impl(&conn->conn_pcb->remote_ip, remote_port, &conn->settings, conn->report_fn, conn->report_arg,
+    conn->base.related_master_state, &new_conn);
+  if (ret == ERR_OK) {
+    LWIP_ASSERT("new_conn != NULL", new_conn != NULL);
+    new_conn->settings.flags = 0; /* prevent the remote side starting back as client again */
+  }
+  return ret;
+}
+
+/** Receive data on an iperf tcp session */
+static err_t
+lwiperf_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
+{
+  u8_t tmp;
+  u16_t tot_len;
+  u32_t packet_idx;
+  struct pbuf *q;
+  lwiperf_state_tcp_t *conn = (lwiperf_state_tcp_t *)arg;
+
+  LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb);
+  LWIP_UNUSED_ARG(tpcb);
+
+  if (err != ERR_OK) {
+    lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
+    return ERR_OK;
+  }
+  if (p == NULL) {
+    /* connection closed -> test done */
+    if (conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) {
+      if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_NOW)) == 0) {
+        /* client requested transmission after end of test */
+        lwiperf_tx_start_passive(conn);
+      }
+    }
+    lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_SERVER);
+    return ERR_OK;
+  }
+  tot_len = p->tot_len;
+
+  conn->poll_count = 0;
+
+  if ((!conn->have_settings_buf) || ((conn->bytes_transferred - 24) % (1024 * 128) == 0)) {
+    /* wait for 24-byte header */
+    if (p->tot_len < sizeof(lwiperf_settings_t)) {
+      lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
+      pbuf_free(p);
+      return ERR_OK;
+    }
+    if (!conn->have_settings_buf) {
+      if (pbuf_copy_partial(p, &conn->settings, sizeof(lwiperf_settings_t), 0) != sizeof(lwiperf_settings_t)) {
+        lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL);
+        pbuf_free(p);
+        return ERR_OK;
+      }
+      conn->have_settings_buf = 1;
+      if (conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) {
+        if (conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_NOW)) {
+          /* client requested parallel transmission test */
+          err_t err2 = lwiperf_tx_start_passive(conn);
+          if (err2 != ERR_OK) {
+            lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_TXERROR);
+            pbuf_free(p);
+            return ERR_OK;
+          }
+        }
+      }
+    } else {
+      if (conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) {
+        if (pbuf_memcmp(p, 0, &conn->settings, sizeof(lwiperf_settings_t)) != 0) {
+          lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
+          pbuf_free(p);
+          return ERR_OK;
+        }
+      }
+    }
+    conn->bytes_transferred += sizeof(lwiperf_settings_t);
+    if (conn->bytes_transferred <= 24) {
+      conn->time_started = sys_now();
+      tcp_recved(tpcb, p->tot_len);
+      pbuf_free(p);
+      return ERR_OK;
+    }
+    conn->next_num = 4; /* 24 bytes received... */
+    tmp = pbuf_remove_header(p, 24);
+    LWIP_ASSERT("pbuf_remove_header failed", tmp == 0);
+    LWIP_UNUSED_ARG(tmp); /* for LWIP_NOASSERT */
+  }
+
+  packet_idx = 0;
+  for (q = p; q != NULL; q = q->next) {
+#if LWIPERF_CHECK_RX_DATA
+    const u8_t *payload = (const u8_t *)q->payload;
+    u16_t i;
+    for (i = 0; i < q->len; i++) {
+      u8_t val = payload[i];
+      u8_t num = val - '0';
+      if (num == conn->next_num) {
+        conn->next_num++;
+        if (conn->next_num == 10) {
+          conn->next_num = 0;
+        }
+      } else {
+        lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
+        pbuf_free(p);
+        return ERR_OK;
+      }
+    }
+#endif
+    packet_idx += q->len;
+  }
+  LWIP_ASSERT("count mismatch", packet_idx == p->tot_len);
+  conn->bytes_transferred += packet_idx;
+  tcp_recved(tpcb, tot_len);
+  pbuf_free(p);
+  return ERR_OK;
+}
+
+/** Error callback, iperf tcp session aborted */
+static void
+lwiperf_tcp_err(void *arg, err_t err)
+{
+  lwiperf_state_tcp_t *conn = (lwiperf_state_tcp_t *)arg;
+  LWIP_UNUSED_ARG(err);
+  lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
+}
+
+/** TCP poll callback, try to send more data */
+static err_t
+lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb)
+{
+  lwiperf_state_tcp_t *conn = (lwiperf_state_tcp_t *)arg;
+  LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb);
+  LWIP_UNUSED_ARG(tpcb);
+  if (++conn->poll_count >= LWIPERF_TCP_MAX_IDLE_SEC) {
+    lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL);
+    return ERR_OK; /* lwiperf_tcp_close frees conn */
+  }
+
+  if (!conn->base.server) {
+    lwiperf_tcp_client_send_more(conn);
+  }
+
+  return ERR_OK;
+}
+
+/** This is called when a new client connects for an iperf tcp session */
+static err_t
+lwiperf_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
+{
+  lwiperf_state_tcp_t *s, *conn;
+  if ((err != ERR_OK) || (newpcb == NULL) || (arg == NULL)) {
+    return ERR_VAL;
+  }
+
+  s = (lwiperf_state_tcp_t *)arg;
+  LWIP_ASSERT("invalid session", s->base.server);
+  LWIP_ASSERT("invalid listen pcb", s->server_pcb != NULL);
+  LWIP_ASSERT("invalid conn pcb", s->conn_pcb == NULL);
+  if (s->specific_remote) {
+    LWIP_ASSERT("s->base.related_master_state != NULL", s->base.related_master_state != NULL);
+    if (!ip_addr_cmp(&newpcb->remote_ip, &s->remote_addr)) {
+      /* this listener belongs to a client session, and this is not the correct remote */
+      return ERR_VAL;
+    }
+  } else {
+    LWIP_ASSERT("s->base.related_master_state == NULL", s->base.related_master_state == NULL);
+  }
+
+  conn = (lwiperf_state_tcp_t *)LWIPERF_ALLOC(lwiperf_state_tcp_t);
+  if (conn == NULL) {
+    return ERR_MEM;
+  }
+  memset(conn, 0, sizeof(lwiperf_state_tcp_t));
+  conn->base.tcp = 1;
+  conn->base.server = 1;
+  conn->base.related_master_state = &s->base;
+  conn->conn_pcb = newpcb;
+  conn->time_started = sys_now();
+  conn->report_fn = s->report_fn;
+  conn->report_arg = s->report_arg;
+
+  /* setup the tcp rx connection */
+  tcp_arg(newpcb, conn);
+  tcp_recv(newpcb, lwiperf_tcp_recv);
+  tcp_poll(newpcb, lwiperf_tcp_poll, 2U);
+  tcp_err(conn->conn_pcb, lwiperf_tcp_err);
+
+  if (s->specific_remote) {
+    /* this listener belongs to a client, so make the client the master of the newly created connection */
+    conn->base.related_master_state = s->base.related_master_state;
+    /* if dual mode or (tradeoff mode AND client is done): close the listener */
+    if (!s->client_tradeoff_mode || !lwiperf_list_find(s->base.related_master_state)) {
+      /* prevent report when closing: this is expected */
+      s->report_fn = NULL;
+      lwiperf_tcp_close(s, LWIPERF_TCP_ABORTED_LOCAL);
+    }
+  }
+  lwiperf_list_add(&conn->base);
+  return ERR_OK;
+}
+
+/**
+ * @ingroup iperf
+ * Start a TCP iperf server on the default TCP port (5001) and listen for
+ * incoming connections from iperf clients.
+ *
+ * @returns a connection handle that can be used to abort the server
+ *          by calling @ref lwiperf_abort()
+ */
+void *
+lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void *report_arg)
+{
+  return lwiperf_start_tcp_server(IP_ADDR_ANY, LWIPERF_TCP_PORT_DEFAULT,
+                                  report_fn, report_arg);
+}
+
+/**
+ * @ingroup iperf
+ * Start a TCP iperf server on a specific IP address and port and listen for
+ * incoming connections from iperf clients.
+ *
+ * @returns a connection handle that can be used to abort the server
+ *          by calling @ref lwiperf_abort()
+ */
+void *
+lwiperf_start_tcp_server(const ip_addr_t *local_addr, u16_t local_port,
+                         lwiperf_report_fn report_fn, void *report_arg)
+{
+  err_t err;
+  lwiperf_state_tcp_t *state = NULL;
+
+  err = lwiperf_start_tcp_server_impl(local_addr, local_port, report_fn, report_arg,
+    NULL, &state);
+  if (err == ERR_OK) {
+    return state;
+  }
+  return NULL;
+}
+
+static err_t lwiperf_start_tcp_server_impl(const ip_addr_t *local_addr, u16_t local_port,
+                                           lwiperf_report_fn report_fn, void *report_arg,
+                                           lwiperf_state_base_t *related_master_state, lwiperf_state_tcp_t **state)
+{
+  err_t err;
+  struct tcp_pcb *pcb;
+  lwiperf_state_tcp_t *s;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  LWIP_ASSERT("state != NULL", state != NULL);
+
+  if (local_addr == NULL) {
+    return ERR_ARG;
+  }
+
+  s = (lwiperf_state_tcp_t *)LWIPERF_ALLOC(lwiperf_state_tcp_t);
+  if (s == NULL) {
+    return ERR_MEM;
+  }
+  memset(s, 0, sizeof(lwiperf_state_tcp_t));
+  s->base.tcp = 1;
+  s->base.server = 1;
+  s->base.related_master_state = related_master_state;
+  s->report_fn = report_fn;
+  s->report_arg = report_arg;
+
+  pcb = tcp_new_ip_type(LWIPERF_SERVER_IP_TYPE);
+  if (pcb == NULL) {
+    return ERR_MEM;
+  }
+  err = tcp_bind(pcb, local_addr, local_port);
+  if (err != ERR_OK) {
+    return err;
+  }
+  s->server_pcb = tcp_listen_with_backlog(pcb, 1);
+  if (s->server_pcb == NULL) {
+    if (pcb != NULL) {
+      tcp_close(pcb);
+    }
+    LWIPERF_FREE(lwiperf_state_tcp_t, s);
+    return ERR_MEM;
+  }
+  pcb = NULL;
+
+  tcp_arg(s->server_pcb, s);
+  tcp_accept(s->server_pcb, lwiperf_tcp_accept);
+
+  lwiperf_list_add(&s->base);
+  *state = s;
+  return ERR_OK;
+}
+
+/**
+ * @ingroup iperf
+ * Start a TCP iperf client to the default TCP port (5001).
+ *
+ * @returns a connection handle that can be used to abort the client
+ *          by calling @ref lwiperf_abort()
+ */
+void* lwiperf_start_tcp_client_default(const ip_addr_t* remote_addr,
+                               lwiperf_report_fn report_fn, void* report_arg)
+{
+  return lwiperf_start_tcp_client(remote_addr, LWIPERF_TCP_PORT_DEFAULT, LWIPERF_CLIENT,
+                                  report_fn, report_arg);
+}
+
+/**
+ * @ingroup iperf
+ * Start a TCP iperf client to a specific IP address and port.
+ *
+ * @returns a connection handle that can be used to abort the client
+ *          by calling @ref lwiperf_abort()
+ */
+void* lwiperf_start_tcp_client(const ip_addr_t* remote_addr, u16_t remote_port,
+  enum lwiperf_client_type type, lwiperf_report_fn report_fn, void* report_arg)
+{
+  err_t ret;
+  lwiperf_settings_t settings;
+  lwiperf_state_tcp_t *state = NULL;
+
+  memset(&settings, 0, sizeof(settings));
+  switch (type) {
+  case LWIPERF_CLIENT:
+    /* Unidirectional tx only test */
+    settings.flags = 0;
+    break;
+  case LWIPERF_DUAL:
+    /* Do a bidirectional test simultaneously */
+    settings.flags = htonl(LWIPERF_FLAGS_ANSWER_TEST | LWIPERF_FLAGS_ANSWER_NOW);
+    break;
+  case LWIPERF_TRADEOFF:
+    /* Do a bidirectional test individually */
+    settings.flags = htonl(LWIPERF_FLAGS_ANSWER_TEST);
+    break;
+  default:
+    /* invalid argument */
+    return NULL;
+  }
+  settings.num_threads = htonl(1);
+  settings.remote_port = htonl(LWIPERF_TCP_PORT_DEFAULT);
+  /* TODO: implement passing duration/amount of bytes to transfer */
+  settings.amount = htonl((u32_t)-1000);
+
+  ret = lwiperf_tx_start_impl(remote_addr, remote_port, &settings, report_fn, report_arg, NULL, &state);
+  if (ret == ERR_OK) {
+    LWIP_ASSERT("state != NULL", state != NULL);
+    if (type != LWIPERF_CLIENT) {
+      /* start corresponding server now */
+      lwiperf_state_tcp_t *server = NULL;
+      ret = lwiperf_start_tcp_server_impl(&state->conn_pcb->local_ip, LWIPERF_TCP_PORT_DEFAULT,
+        report_fn, report_arg, (lwiperf_state_base_t *)state, &server);
+      if (ret != ERR_OK) {
+        /* starting server failed, abort client */
+        lwiperf_abort(state);
+        return NULL;
+      }
+      /* make this server accept one connection only */
+      server->specific_remote = 1;
+      server->remote_addr = state->conn_pcb->remote_ip;
+      if (type == LWIPERF_TRADEOFF) {
+        /* tradeoff means that the remote host connects only after the client is done,
+           so keep the listen pcb open until the client is done */
+        server->client_tradeoff_mode = 1;
+      }
+    }
+    return state;
+  }
+  return NULL;
+}
+
+/**
+ * @ingroup iperf
+ * Abort an iperf session (handle returned by lwiperf_start_tcp_server*())
+ */
+void
+lwiperf_abort(void *lwiperf_session)
+{
+  lwiperf_state_base_t *i, *dealloc, *last = NULL;
+
+  LWIP_ASSERT_CORE_LOCKED();
+
+  for (i = lwiperf_all_connections; i != NULL; ) {
+    if ((i == lwiperf_session) || (i->related_master_state == lwiperf_session)) {
+      dealloc = i;
+      i = i->next;
+      if (last != NULL) {
+        last->next = i;
+      }
+      LWIPERF_FREE(lwiperf_state_tcp_t, dealloc); /* @todo: type? */
+    } else {
+      last = i;
+      i = i->next;
+    }
+  }
+}
+
+#endif /* LWIP_TCP && LWIP_CALLBACK_API */

+ 416 - 0
CM7/Core/Src/main.c

@@ -0,0 +1,416 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file           : main.c
+  * @brief          : Main program body
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "cmsis_os.h"
+#include "lwip.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+/* ETH_CODE: add lwiperf, see comment in StartDefaultTask function */
+#include "lwip/apps/lwiperf.h"
+#include <stdio.h>
+#include "echo_server.h"
+#include "mqtt_client.h"
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN PTD */
+
+/* USER CODE END PTD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+#ifndef HSEM_ID_0
+#define HSEM_ID_0 (0U) /* HW semaphore 0*/
+#endif
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+
+/* Definitions for defaultTask */
+osThreadId_t defaultTaskHandle;
+const osThreadAttr_t defaultTask_attributes = {
+  .name = "defaultTask",
+  .stack_size = 512 * 4,
+  .priority = (osPriority_t) osPriorityNormal,
+};
+/* USER CODE BEGIN PV */
+extern uint32_t MilliTimer;
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+void SystemClock_Config(void);
+static void MPU_Config(void);
+static void MX_GPIO_Init(void);
+void StartDefaultTask(void *argument);
+
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+uint32_t my_counter =0;
+
+/* USER CODE END 0 */
+
+/**
+  * @brief  The application entry point.
+  * @retval int
+  */
+int main(void)
+{
+  /* USER CODE BEGIN 1 */
+
+  /* USER CODE END 1 */
+/* USER CODE BEGIN Boot_Mode_Sequence_0 */
+
+/* USER CODE END Boot_Mode_Sequence_0 */
+
+  /* MPU Configuration--------------------------------------------------------*/
+  MPU_Config();
+
+  /* Enable I-Cache---------------------------------------------------------*/
+  SCB_EnableICache();
+
+  /* Enable D-Cache---------------------------------------------------------*/
+  SCB_EnableDCache();
+
+/* USER CODE BEGIN Boot_Mode_Sequence_1 */
+
+/* USER CODE END Boot_Mode_Sequence_1 */
+  /* MCU Configuration--------------------------------------------------------*/
+
+  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+  HAL_Init();
+
+  /* USER CODE BEGIN Init */
+
+  /* USER CODE END Init */
+
+  /* Configure the system clock */
+  SystemClock_Config();
+/* USER CODE BEGIN Boot_Mode_Sequence_2 */
+
+/* USER CODE END Boot_Mode_Sequence_2 */
+
+  /* USER CODE BEGIN SysInit */
+  ITM->TCR |= ITM_TCR_ITMENA_Msk;
+  ITM->TER |= 1UL;
+//  DBGMCU->CR |= DBGMCU_CR_DBG_TRACECKEN_Msk;
+  /* USER CODE END SysInit */
+
+  /* Initialize all configured peripherals */
+  MX_GPIO_Init();
+  /* USER CODE BEGIN 2 */
+  /* ETH_CODE: fixed core synchronization
+     * Release M4 core after GPIO and peripherals init
+     * to avoid conflict.
+     */
+    __HAL_RCC_HSEM_CLK_ENABLE();
+    HAL_HSEM_FastTake(HSEM_ID_0);
+    HAL_HSEM_Release(HSEM_ID_0,0);
+  /* USER CODE END 2 */
+
+  /* Init scheduler */
+  osKernelInitialize();
+
+  /* USER CODE BEGIN RTOS_MUTEX */
+  /* add mutexes, ... */
+  /* USER CODE END RTOS_MUTEX */
+
+  /* USER CODE BEGIN RTOS_SEMAPHORES */
+  /* add semaphores, ... */
+  /* USER CODE END RTOS_SEMAPHORES */
+
+  /* USER CODE BEGIN RTOS_TIMERS */
+  /* start timers, add new ones, ... */
+  /* USER CODE END RTOS_TIMERS */
+
+  /* USER CODE BEGIN RTOS_QUEUES */
+  /* add queues, ... */
+  /* USER CODE END RTOS_QUEUES */
+
+  /* Create the thread(s) */
+  /* creation of defaultTask */
+  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
+//  echo_server_netconn_init();
+  mqtt_cli_init();
+
+  /* USER CODE BEGIN RTOS_THREADS */
+  /* add threads, ... */
+  /* USER CODE END RTOS_THREADS */
+
+  /* USER CODE BEGIN RTOS_EVENTS */
+  /* add events, ... */
+  /* USER CODE END RTOS_EVENTS */
+
+  /* Start scheduler */
+  osKernelStart();
+
+  /* We should never get here as control is now taken by the scheduler */
+  /* Infinite loop */
+  /* USER CODE BEGIN WHILE */
+  while (1)
+  {
+    /* USER CODE END WHILE */
+
+    /* USER CODE BEGIN 3 */
+  }
+  /* USER CODE END 3 */
+}
+
+/**
+  * @brief System Clock Configuration
+  * @retval None
+  */
+void SystemClock_Config(void)
+{
+  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+
+  /** Supply configuration update enable
+  */
+  HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);
+
+  /** Configure the main internal regulator output voltage
+  */
+  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+
+  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
+
+  /** Initializes the RCC Oscillators according to the specified parameters
+  * in the RCC_OscInitTypeDef structure.
+  */
+  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+  RCC_OscInitStruct.PLL.PLLM = 5;
+  RCC_OscInitStruct.PLL.PLLN = 160;
+  RCC_OscInitStruct.PLL.PLLP = 2;
+  RCC_OscInitStruct.PLL.PLLQ = 4;
+  RCC_OscInitStruct.PLL.PLLR = 4;
+  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
+  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
+  RCC_OscInitStruct.PLL.PLLFRACN = 0;
+  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+  {
+    Error_Handler();
+  }
+
+  /** Initializes the CPU, AHB and APB buses clocks
+  */
+  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
+                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
+  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
+  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
+  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
+  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
+  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
+  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
+
+  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
+  {
+    Error_Handler();
+  }
+}
+
+/**
+  * @brief GPIO Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_GPIO_Init(void)
+{
+
+  /* GPIO Ports Clock Enable */
+  __HAL_RCC_GPIOG_CLK_ENABLE();
+  __HAL_RCC_GPIOA_CLK_ENABLE();
+  __HAL_RCC_GPIOC_CLK_ENABLE();
+  __HAL_RCC_GPIOE_CLK_ENABLE();
+  __HAL_RCC_GPIOB_CLK_ENABLE();
+  __HAL_RCC_GPIOI_CLK_ENABLE();
+  __HAL_RCC_GPIOH_CLK_ENABLE();
+
+}
+
+/* USER CODE BEGIN 4 */
+
+/* USER CODE END 4 */
+
+/* USER CODE BEGIN Header_StartDefaultTask */
+/**
+  * @brief  Function implementing the defaultTask thread.
+  * @param  argument: Not used
+  * @retval None
+  */
+/* USER CODE END Header_StartDefaultTask */
+void StartDefaultTask(void *argument)
+{
+  /* init code for LWIP */
+  MX_LWIP_Init();
+  /* USER CODE BEGIN 5 */
+  /* ETH_CODE: Adding lwiperf to measure TCP/IP performance.
+     * iperf 2.0.6 (or older?) is required for the tests. Newer iperf2 versions
+     * might work without data check, but they send different headers.
+     * iperf3 is not compatible at all.
+     * Adding lwiperf.c file to the project is necessary.
+     * The default include path should already contain
+     * 'lwip/apps/lwiperf.h'
+     */
+//    LOCK_TCPIP_CORE();
+//    lwiperf_start_tcp_server_default(NULL, NULL);
+//
+//    ip4_addr_t remote_addr;
+//    IP4_ADDR(&remote_addr, 192, 168, 1, 63);
+//    lwiperf_start_tcp_client_default(&remote_addr, NULL, NULL);
+//    UNLOCK_TCPIP_CORE();
+    /* Infinite loop */
+
+    for(;;)
+    {
+//    	printf("Hello World! %d\n\r", (int16_t)my_counter);
+      osDelay(pdMS_TO_TICKS(1000));
+//    	fflush(stdout);
+
+    	my_counter++;
+    	if(my_counter > 10)
+    	{
+    		my_counter = 0;
+    	}
+    }
+  /* USER CODE END 5 */
+}
+
+/* MPU Configuration */
+
+void MPU_Config(void)
+{
+  MPU_Region_InitTypeDef MPU_InitStruct = {0};
+
+  /* Disables the MPU */
+  HAL_MPU_Disable();
+
+  /** Initializes and configures the Region and the memory to be protected
+  */
+  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
+  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
+  MPU_InitStruct.BaseAddress = 0x0;
+  MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
+  MPU_InitStruct.SubRegionDisable = 0x87;
+  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
+  MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
+  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
+  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
+  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
+  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
+
+  HAL_MPU_ConfigRegion(&MPU_InitStruct);
+
+  /** Initializes and configures the Region and the memory to be protected
+  */
+  MPU_InitStruct.Number = MPU_REGION_NUMBER1;
+  MPU_InitStruct.BaseAddress = 0x30020000;
+  MPU_InitStruct.Size = MPU_REGION_SIZE_128KB;
+  MPU_InitStruct.SubRegionDisable = 0x0;
+  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
+  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
+  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
+
+  HAL_MPU_ConfigRegion(&MPU_InitStruct);
+
+  /** Initializes and configures the Region and the memory to be protected
+  */
+  MPU_InitStruct.Number = MPU_REGION_NUMBER2;
+  MPU_InitStruct.BaseAddress = 0x30040000;
+  MPU_InitStruct.Size = MPU_REGION_SIZE_512B;
+  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
+  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
+  MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
+
+  HAL_MPU_ConfigRegion(&MPU_InitStruct);
+  /* Enables the MPU */
+  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
+
+}
+
+/**
+  * @brief  Period elapsed callback in non blocking mode
+  * @note   This function is called  when TIM6 interrupt took place, inside
+  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
+  * a global variable "uwTick" used as application time base.
+  * @param  htim : TIM handle
+  * @retval None
+  */
+void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
+{
+  /* USER CODE BEGIN Callback 0 */
+
+  /* USER CODE END Callback 0 */
+  if (htim->Instance == TIM6) {
+    HAL_IncTick();
+    MilliTimer++;
+  }
+  /* USER CODE BEGIN Callback 1 */
+
+  /* USER CODE END Callback 1 */
+}
+
+/**
+  * @brief  This function is executed in case of error occurrence.
+  * @retval None
+  */
+void Error_Handler(void)
+{
+  /* USER CODE BEGIN Error_Handler_Debug */
+  /* User can add his own implementation to report the HAL error return state */
+  __disable_irq();
+  while (1)
+  {
+  }
+  /* USER CODE END Error_Handler_Debug */
+}
+
+#ifdef  USE_FULL_ASSERT
+/**
+  * @brief  Reports the name of the source file and the source line number
+  *         where the assert_param error has occurred.
+  * @param  file: pointer to the source file name
+  * @param  line: assert_param error line source number
+  * @retval None
+  */
+void assert_failed(uint8_t *file, uint32_t line)
+{
+  /* USER CODE BEGIN 6 */
+  /* User can add his own implementation to report the file name and line number,
+     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+  /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */

+ 259 - 0
CM7/Core/Src/mqtt_client.c

@@ -0,0 +1,259 @@
+/*
+ * mqtt_client.c
+ *
+ *  Created on: Jun 10, 2024
+ *      Author: jakubski
+ */
+#include <stdio.h>
+#if 1
+#include "FreeRTOS.h"
+#include "task.h"
+#include "main.h"
+#include "cmsis_os.h"
+
+#include <string.h>
+#include "lwip.h"
+#include "lwip/api.h"
+#include "MQTTClient.h"
+#include "MQTTInterface.h"
+#include "node-red-config.h"
+
+#define MQTT_BUFSIZE	1024
+
+extern struct netif gnetif; //extern gnetif
+
+const osThreadAttr_t mqttClientSubTaskAttr = {
+  .name = "mqttClientSubTask",
+  .stack_size = configMINIMAL_STACK_SIZE * 2,
+  .priority = (osPriority_t) osPriorityNormal,
+};
+
+const osThreadAttr_t mqttClientPubTaskAttr = {
+  .name = "mqttClientPsubTask",
+  .stack_size = configMINIMAL_STACK_SIZE * 2,
+  .priority = (osPriority_t) osPriorityNormal,
+};
+
+osThreadId mqttClientSubTaskHandle;  //mqtt client task handle
+osThreadId mqttClientPubTaskHandle;  //mqtt client task handle
+
+Network net; //mqtt network
+MQTTClient mqttClient; //mqtt client
+
+uint8_t sndBuffer[MQTT_BUFSIZE]; //mqtt send buffer
+uint8_t rcvBuffer[MQTT_BUFSIZE]; //mqtt receive buffer
+uint8_t msgBuffer[MQTT_BUFSIZE]; //mqtt message buffer
+
+void MqttClientSubTask(void *argument); //mqtt client subscribe task function
+void MqttClientPubTask(void *argument); //mqtt client publish task function
+int  MqttConnectBroker(void); 				//mqtt broker connect function
+void MqttMessageArrived(MessageData* msg); //mqtt message callback function
+
+void MqttClientSubTask(void *argument)
+{
+	while(1)
+	{
+		//waiting for valid ip address
+		if (gnetif.ip_addr.addr == 0 || gnetif.netmask.addr == 0 || gnetif.gw.addr == 0) //system has no valid ip address
+		{
+			osDelay(pdMS_TO_TICKS(1000));
+			continue;
+		}
+		else
+		{
+			printf("DHCP/Static IP O.K.\n");
+			break;
+		}
+	}
+
+	while(1)
+	{
+		if(!mqttClient.isconnected)
+		{
+			//try to connect to the broker
+			MQTTDisconnect(&mqttClient);
+			MqttConnectBroker();
+			osDelay(pdMS_TO_TICKS(1000));
+		}
+		else
+		{
+			MQTTYield(&mqttClient, 500); //handle timer
+			osDelay(pdMS_TO_TICKS(100));
+		}
+	}
+}
+
+void MqttClientPubTask(void *argument)
+{
+	const char* str = "MQTT message from STM32";
+	MQTTMessage message;
+
+	while(1)
+	{
+		if(mqttClient.isconnected)
+		{
+			message.payload = (void*)str;
+			message.payloadlen = strlen(str);
+
+			if(is_link_up())
+			{
+				MQTTPublish(&mqttClient, "test", &message); //publish a message
+			}
+		}
+
+		osDelay(pdMS_TO_TICKS(1000));
+	}
+}
+
+int MqttConnectBroker()
+{
+	int ret;
+
+	NewNetwork(&net);
+	ret = ConnectNetwork(&net, BROKER_IP, MQTT_PORT);
+	if(ret != MQTT_SUCCESS)
+	{
+		printf("ConnectNetwork failed.\n");
+		return -1;
+	}
+
+	MQTTClientInit(&mqttClient, &net, 1000, sndBuffer, sizeof(sndBuffer), rcvBuffer, sizeof(rcvBuffer));
+
+	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
+	data.willFlag = 0;
+	data.MQTTVersion = 3;
+	data.clientID.cstring = "test_user1";
+	data.username.cstring = "test_user1";
+	data.password.cstring = "1234";
+	data.keepAliveInterval = 100;
+	data.cleansession = 1;
+
+	ret = MQTTConnect(&mqttClient, &data);
+	if(ret != MQTT_SUCCESS)
+	{
+		net_disconnect(&net);
+		printf("MQTTConnect failed.\n");
+		return ret;
+	}
+
+//	osDelay(pdMS_TO_TICKS(100));
+	ret = MQTTSubscribe(&mqttClient, "test_second", QOS0, MqttMessageArrived);
+	if(ret != MQTT_SUCCESS)
+	{
+		net_disconnect(&net);
+		printf("MQTTSubscribe failed.\n");
+		return ret;
+	}
+	printf("MQTT_ConnectBroker O.K.\n");
+
+	return MQTT_SUCCESS;
+}
+
+void MqttMessageArrived(MessageData* msg)
+{
+	MQTTMessage* message = msg->message;
+	memset(msgBuffer, 0, sizeof(msgBuffer));
+	memcpy(msgBuffer, message->payload,message->payloadlen);
+
+	printf("MQTT MSG[%d]:%s\n", (int)message->payloadlen, msgBuffer);
+}
+
+void mqtt_cli_init(void)
+{
+	mqttClientSubTaskHandle = osThreadNew(MqttClientSubTask, NULL, &mqttClientSubTaskAttr); //subscribe task
+	mqttClientPubTaskHandle = osThreadNew(MqttClientPubTask, NULL, &mqttClientPubTaskAttr); //publish task
+}
+
+#else
+#include "lwip/opt.h"
+#include "lwip/arch.h"
+#include "lwip/api.h"
+#include "lwip/apps/mqtt.h"
+
+#include "cmsis_os.h"
+
+#define MQTT_CLI_THREAD_PRIO    ( tskIDLE_PRIORITY + 4 )
+
+#ifndef LWIP_MQTT_EXAMPLE_IPADDR_INIT
+#if LWIP_IPV4
+#define LWIP_MQTT_EXAMPLE_IPADDR_INIT = IPADDR4_INIT(PP_HTONL(IPADDR_LOOPBACK))
+#else
+#define LWIP_MQTT_EXAMPLE_IPADDR_INIT
+#endif
+#endif
+
+static ip_addr_t mqtt_ip LWIP_MQTT_EXAMPLE_IPADDR_INIT;
+
+static const struct mqtt_connect_client_info_t mqtt_client_info =
+{
+	"test_user1",
+	"test_user1", /* user */
+	"1234", /* pass */
+	100,  /* keep alive */
+	NULL, /* will_topic */
+	NULL, /* will_msg */
+	0,    /* will_qos */
+	0     /* will_retain */
+	#if LWIP_ALTCP && LWIP_ALTCP_TLS
+	, NULL
+	#endif
+};
+
+static void mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
+{
+	const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+//	LWIP_UNUSED_ARG(data);
+
+	LWIP_PLATFORM_DIAG(("MQTT client \"%s\" data cb: len %d, flags %d\n", client_info->client_id, (int)len, (int)flags));
+	LWIP_PLATFORM_DIAG(("Data:\n%s\n", data));
+}
+
+static void mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
+{
+	const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+
+	LWIP_PLATFORM_DIAG(("MQTT client \"%s\" publish cb: topic %s, len %d\n", client_info->client_id, topic, (int)tot_len));
+}
+
+static void mqtt_request_cb(void *arg, err_t err)
+{
+	const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+
+	LWIP_PLATFORM_DIAG(("MQTT client \"%s\" request cb: err %d\n", client_info->client_id, (int)err));
+}
+
+static void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
+{
+	const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+//	LWIP_UNUSED_ARG(client);
+
+	LWIP_PLATFORM_DIAG(("MQTT client \"%s\" connection cb: status %d\n", client_info->client_id, (int)status));
+
+	if (status == MQTT_CONNECT_ACCEPTED)
+	{
+		mqtt_sub_unsub(client, "topic_qos1", 1, mqtt_request_cb, LWIP_CONST_CAST(void*, client_info), 1);
+		mqtt_sub_unsub(client, "topic_qos0", 0, mqtt_request_cb, LWIP_CONST_CAST(void*, client_info), 1);
+	}
+}
+
+void mqtt_cli_thread(void *arg)
+{
+	mqtt_client_t* mqtt_client;
+	osDelay(pdMS_TO_TICKS(7000));
+	ipaddr_aton("192.168.1.34", &mqtt_ip);
+	LOCK_TCPIP_CORE();
+	mqtt_client = mqtt_client_new();
+	mqtt_client_connect(mqtt_client, &mqtt_ip, MQTT_PORT, mqtt_connection_cb, LWIP_CONST_CAST(void*, &mqtt_client_info), &mqtt_client_info);
+	mqtt_set_inpub_callback(mqtt_client, mqtt_incoming_publish_cb, mqtt_incoming_data_cb, LWIP_CONST_CAST(void*, &mqtt_client_info));
+	UNLOCK_TCPIP_CORE();
+	while(1)
+	{
+		osDelay(pdMS_TO_TICKS(100));
+	}
+}
+
+void mqtt_cli_init(void)
+{
+	sys_thread_new("mqtt_cli_netconn", mqtt_cli_thread, NULL, DEFAULT_THREAD_STACKSIZE, MQTT_CLI_THREAD_PRIO);
+}
+#endif

+ 82 - 0
CM7/Core/Src/stm32h7xx_hal_msp.c

@@ -0,0 +1,82 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file         stm32h7xx_hal_msp.c
+  * @brief        This file provides code for the MSP Initialization
+  *               and de-Initialization codes.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN Define */
+
+/* USER CODE END Define */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN Macro */
+
+/* USER CODE END Macro */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* External functions --------------------------------------------------------*/
+/* USER CODE BEGIN ExternalFunctions */
+
+/* USER CODE END ExternalFunctions */
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+/**
+  * Initializes the Global MSP.
+  */
+void HAL_MspInit(void)
+{
+  /* USER CODE BEGIN MspInit 0 */
+
+  /* USER CODE END MspInit 0 */
+
+  __HAL_RCC_SYSCFG_CLK_ENABLE();
+
+  /* System interrupt init*/
+  /* PendSV_IRQn interrupt configuration */
+  HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
+
+  /* USER CODE BEGIN MspInit 1 */
+
+  /* USER CODE END MspInit 1 */
+}
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */

+ 130 - 0
CM7/Core/Src/stm32h7xx_hal_timebase_tim.c

@@ -0,0 +1,130 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_hal_timebase_TIM.c
+  * @brief   HAL time base based on the hardware TIM.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+#include "stm32h7xx_hal_tim.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+TIM_HandleTypeDef        htim6;
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/**
+  * @brief  This function configures the TIM6 as a time base source.
+  *         The time source is configured  to have 1ms time base with a dedicated
+  *         Tick interrupt priority.
+  * @note   This function is called  automatically at the beginning of program after
+  *         reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
+  * @param  TickPriority: Tick interrupt priority.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
+{
+  RCC_ClkInitTypeDef    clkconfig;
+  uint32_t              uwTimclock, uwAPB1Prescaler;
+
+  uint32_t              uwPrescalerValue;
+  uint32_t              pFLatency;
+/*Configure the TIM6 IRQ priority */
+  if (TickPriority < (1UL << __NVIC_PRIO_BITS))
+  {
+  HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0U);
+
+  /* Enable the TIM6 global Interrupt */
+  HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
+    uwTickPrio = TickPriority;
+    }
+  else
+  {
+    return HAL_ERROR;
+  }
+
+  /* Enable TIM6 clock */
+  __HAL_RCC_TIM6_CLK_ENABLE();
+
+  /* Get clock configuration */
+  HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
+
+  /* Get APB1 prescaler */
+  uwAPB1Prescaler = clkconfig.APB1CLKDivider;
+  /* Compute TIM6 clock */
+  if (uwAPB1Prescaler == RCC_HCLK_DIV1)
+  {
+    uwTimclock = HAL_RCC_GetPCLK1Freq();
+  }
+  else
+  {
+    uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
+  }
+
+  /* Compute the prescaler value to have TIM6 counter clock equal to 1MHz */
+  uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
+
+  /* Initialize TIM6 */
+  htim6.Instance = TIM6;
+
+  /* Initialize TIMx peripheral as follow:
+  + Period = [(TIM6CLK/1000) - 1]. to have a (1/1000) s time base.
+  + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
+  + ClockDivision = 0
+  + Counter direction = Up
+  */
+  htim6.Init.Period = (1000000U / 1000U) - 1U;
+  htim6.Init.Prescaler = uwPrescalerValue;
+  htim6.Init.ClockDivision = 0;
+  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
+
+  if(HAL_TIM_Base_Init(&htim6) == HAL_OK)
+  {
+    /* Start the TIM time Base generation in interrupt mode */
+    return HAL_TIM_Base_Start_IT(&htim6);
+  }
+
+  /* Return function status */
+  return HAL_ERROR;
+}
+
+/**
+  * @brief  Suspend Tick increment.
+  * @note   Disable the tick increment by disabling TIM6 update interrupt.
+  * @param  None
+  * @retval None
+  */
+void HAL_SuspendTick(void)
+{
+  /* Disable TIM6 update Interrupt */
+  __HAL_TIM_DISABLE_IT(&htim6, TIM_IT_UPDATE);
+}
+
+/**
+  * @brief  Resume Tick increment.
+  * @note   Enable the tick increment by Enabling TIM6 update interrupt.
+  * @param  None
+  * @retval None
+  */
+void HAL_ResumeTick(void)
+{
+  /* Enable TIM6 Update interrupt */
+  __HAL_TIM_ENABLE_IT(&htim6, TIM_IT_UPDATE);
+}
+

+ 193 - 0
CM7/Core/Src/stm32h7xx_it.c

@@ -0,0 +1,193 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_it.c
+  * @brief   Interrupt Service Routines.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "stm32h7xx_it.h"
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/* External variables --------------------------------------------------------*/
+extern ETH_HandleTypeDef heth;
+extern TIM_HandleTypeDef htim6;
+
+/* USER CODE BEGIN EV */
+
+/* USER CODE END EV */
+
+/******************************************************************************/
+/*           Cortex Processor Interruption and Exception Handlers          */
+/******************************************************************************/
+/**
+  * @brief This function handles Non maskable interrupt.
+  */
+void NMI_Handler(void)
+{
+  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
+
+  /* USER CODE END NonMaskableInt_IRQn 0 */
+  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
+  while (1)
+  {
+  }
+  /* USER CODE END NonMaskableInt_IRQn 1 */
+}
+
+/**
+  * @brief This function handles Hard fault interrupt.
+  */
+void HardFault_Handler(void)
+{
+  /* USER CODE BEGIN HardFault_IRQn 0 */
+
+  /* USER CODE END HardFault_IRQn 0 */
+  while (1)
+  {
+    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
+    /* USER CODE END W1_HardFault_IRQn 0 */
+  }
+}
+
+/**
+  * @brief This function handles Memory management fault.
+  */
+void MemManage_Handler(void)
+{
+  /* USER CODE BEGIN MemoryManagement_IRQn 0 */
+
+  /* USER CODE END MemoryManagement_IRQn 0 */
+  while (1)
+  {
+    /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
+    /* USER CODE END W1_MemoryManagement_IRQn 0 */
+  }
+}
+
+/**
+  * @brief This function handles Pre-fetch fault, memory access fault.
+  */
+void BusFault_Handler(void)
+{
+  /* USER CODE BEGIN BusFault_IRQn 0 */
+
+  /* USER CODE END BusFault_IRQn 0 */
+  while (1)
+  {
+    /* USER CODE BEGIN W1_BusFault_IRQn 0 */
+    /* USER CODE END W1_BusFault_IRQn 0 */
+  }
+}
+
+/**
+  * @brief This function handles Undefined instruction or illegal state.
+  */
+void UsageFault_Handler(void)
+{
+  /* USER CODE BEGIN UsageFault_IRQn 0 */
+
+  /* USER CODE END UsageFault_IRQn 0 */
+  while (1)
+  {
+    /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
+    /* USER CODE END W1_UsageFault_IRQn 0 */
+  }
+}
+
+/**
+  * @brief This function handles Debug monitor.
+  */
+void DebugMon_Handler(void)
+{
+  /* USER CODE BEGIN DebugMonitor_IRQn 0 */
+
+  /* USER CODE END DebugMonitor_IRQn 0 */
+  /* USER CODE BEGIN DebugMonitor_IRQn 1 */
+
+  /* USER CODE END DebugMonitor_IRQn 1 */
+}
+
+/******************************************************************************/
+/* STM32H7xx Peripheral Interrupt Handlers                                    */
+/* Add here the Interrupt Handlers for the used peripherals.                  */
+/* For the available peripheral interrupt handler names,                      */
+/* please refer to the startup file (startup_stm32h7xx.s).                    */
+/******************************************************************************/
+
+/**
+  * @brief This function handles TIM6 global interrupt, DAC1_CH1 and DAC1_CH2 underrun error interrupts.
+  */
+void TIM6_DAC_IRQHandler(void)
+{
+  /* USER CODE BEGIN TIM6_DAC_IRQn 0 */
+
+  /* USER CODE END TIM6_DAC_IRQn 0 */
+  HAL_TIM_IRQHandler(&htim6);
+  /* USER CODE BEGIN TIM6_DAC_IRQn 1 */
+
+  /* USER CODE END TIM6_DAC_IRQn 1 */
+}
+
+/**
+  * @brief This function handles Ethernet global interrupt.
+  */
+void ETH_IRQHandler(void)
+{
+  /* USER CODE BEGIN ETH_IRQn 0 */
+
+  /* USER CODE END ETH_IRQn 0 */
+  HAL_ETH_IRQHandler(&heth);
+  /* USER CODE BEGIN ETH_IRQn 1 */
+
+  /* USER CODE END ETH_IRQn 1 */
+}
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */

+ 156 - 0
CM7/Core/Src/syscalls.c

@@ -0,0 +1,156 @@
+/**
+ ******************************************************************************
+ * @file      syscalls.c
+ * @author    Auto-generated by STM32CubeIDE
+ * @brief     STM32CubeIDE Minimal System calls file
+ *
+ *            For more information about which c-functions
+ *            need which of these lowlevel functions
+ *            please consult the Newlib libc-manual
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2022 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Includes */
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/times.h>
+
+
+/* Variables */
+extern int __io_putchar(int ch) __attribute__((weak));
+extern int __io_getchar(void) __attribute__((weak));
+
+
+char *__env[1] = { 0 };
+char **environ = __env;
+
+
+/* Functions */
+void initialise_monitor_handles()
+{
+}
+
+int _getpid(void)
+{
+	return 1;
+}
+
+int _kill(int pid, int sig)
+{
+	errno = EINVAL;
+	return -1;
+}
+
+void _exit (int status)
+{
+	_kill(status, -1);
+	while (1) {}		/* Make sure we hang here */
+}
+
+__attribute__((weak)) int _read(int file, char *ptr, int len)
+{
+	int DataIdx;
+
+	for (DataIdx = 0; DataIdx < len; DataIdx++)
+	{
+		*ptr++ = __io_getchar();
+	}
+
+return len;
+}
+
+__attribute__((weak)) int _write(int file, char *ptr, int len)
+{
+	int DataIdx;
+
+	for (DataIdx = 0; DataIdx < len; DataIdx++)
+	{
+//		__io_putchar(*ptr++);
+		ITM_SendChar(*ptr++);
+	}
+	return len;
+}
+
+int _close(int file)
+{
+	return -1;
+}
+
+
+int _fstat(int file, struct stat *st)
+{
+	st->st_mode = S_IFCHR;
+	return 0;
+}
+
+int _isatty(int file)
+{
+	return 1;
+}
+
+int _lseek(int file, int ptr, int dir)
+{
+	return 0;
+}
+
+int _open(char *path, int flags, ...)
+{
+	/* Pretend like we always fail */
+	return -1;
+}
+
+int _wait(int *status)
+{
+	errno = ECHILD;
+	return -1;
+}
+
+int _unlink(char *name)
+{
+	errno = ENOENT;
+	return -1;
+}
+
+int _times(struct tms *buf)
+{
+	return -1;
+}
+
+int _stat(char *file, struct stat *st)
+{
+	st->st_mode = S_IFCHR;
+	return 0;
+}
+
+int _link(char *old, char *new)
+{
+	errno = EMLINK;
+	return -1;
+}
+
+int _fork(void)
+{
+	errno = EAGAIN;
+	return -1;
+}
+
+int _execve(char *name, char **argv, char **env)
+{
+	errno = ENOMEM;
+	return -1;
+}

+ 79 - 0
CM7/Core/Src/sysmem.c

@@ -0,0 +1,79 @@
+/**
+ ******************************************************************************
+ * @file      sysmem.c
+ * @author    Generated by STM32CubeIDE
+ * @brief     STM32CubeIDE System Memory calls file
+ *
+ *            For more information about which C functions
+ *            need which of these lowlevel functions
+ *            please consult the newlib libc manual
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2022 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Includes */
+#include <errno.h>
+#include <stdint.h>
+
+/**
+ * Pointer to the current high watermark of the heap usage
+ */
+static uint8_t *__sbrk_heap_end = NULL;
+
+/**
+ * @brief _sbrk() allocates memory to the newlib heap and is used by malloc
+ *        and others from the C library
+ *
+ * @verbatim
+ * ############################################################################
+ * #  .data  #  .bss  #       newlib heap       #          MSP stack          #
+ * #         #        #                         # Reserved by _Min_Stack_Size #
+ * ############################################################################
+ * ^-- RAM start      ^-- _end                             _estack, RAM end --^
+ * @endverbatim
+ *
+ * This implementation starts allocating at the '_end' linker symbol
+ * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
+ * The implementation considers '_estack' linker symbol to be RAM end
+ * NOTE: If the MSP stack, at any point during execution, grows larger than the
+ * reserved size, please increase the '_Min_Stack_Size'.
+ *
+ * @param incr Memory size
+ * @return Pointer to allocated memory
+ */
+void *_sbrk(ptrdiff_t incr)
+{
+  extern uint8_t _end; /* Symbol defined in the linker script */
+  extern uint8_t _estack; /* Symbol defined in the linker script */
+  extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
+  const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
+  const uint8_t *max_heap = (uint8_t *)stack_limit;
+  uint8_t *prev_heap_end;
+
+  /* Initialize heap end at first call */
+  if (NULL == __sbrk_heap_end)
+  {
+    __sbrk_heap_end = &_end;
+  }
+
+  /* Protect heap from growing into the reserved MSP stack */
+  if (__sbrk_heap_end + incr > max_heap)
+  {
+    errno = ENOMEM;
+    return (void *)-1;
+  }
+
+  prev_heap_end = __sbrk_heap_end;
+  __sbrk_heap_end += incr;
+
+  return (void *)prev_heap_end;
+}

+ 764 - 0
CM7/Core/Startup/startup_stm32h745xihx.s

@@ -0,0 +1,764 @@
+/**
+  ******************************************************************************
+  * @file      startup_stm32h745xx.s
+  * @author    MCD Application Team
+  * @brief     STM32H745xx Devices vector table for GCC based toolchain.
+  *            This module performs:
+  *                - Set the initial SP
+  *                - Set the initial PC == Reset_Handler,
+  *                - Set the vector table entries with the exceptions ISR address
+  *                - Branches to main in the C library (which eventually
+  *                  calls main()).
+  *            After Reset the Cortex-M processor is in Thread mode,
+  *            priority is Privileged, and the Stack is set to Main.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+  .syntax unified
+  .cpu cortex-m7
+  .fpu softvfp
+  .thumb
+
+.global  g_pfnVectors
+.global  Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word  _sidata
+/* start address for the .data section. defined in linker script */
+.word  _sdata
+/* end address for the .data section. defined in linker script */
+.word  _edata
+/* start address for the .bss section. defined in linker script */
+.word  _sbss
+/* end address for the .bss section. defined in linker script */
+.word  _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+/**
+ * @brief  This is the code that gets called when the processor first
+ *          starts execution following a reset event. Only the absolutely
+ *          necessary set is performed, after which the application
+ *          supplied main() routine is called.
+ * @param  None
+ * @retval : None
+*/
+
+    .section  .text.Reset_Handler
+  .weak  Reset_Handler
+  .type  Reset_Handler, %function
+Reset_Handler:
+  ldr   sp, =_estack      /* set stack pointer */
+
+/* Call the clock system initialization function.*/
+  bl  SystemInit
+
+/* Copy the data segment initializers from flash to SRAM */
+  ldr r0, =_sdata
+  ldr r1, =_edata
+  ldr r2, =_sidata
+  movs r3, #0
+  b LoopCopyDataInit
+
+CopyDataInit:
+  ldr r4, [r2, r3]
+  str r4, [r0, r3]
+  adds r3, r3, #4
+
+LoopCopyDataInit:
+  adds r4, r0, r3
+  cmp r4, r1
+  bcc CopyDataInit
+/* Zero fill the bss segment. */
+  ldr r2, =_sbss
+  ldr r4, =_ebss
+  movs r3, #0
+  b LoopFillZerobss
+
+FillZerobss:
+  str  r3, [r2]
+  adds r2, r2, #4
+
+LoopFillZerobss:
+  cmp r2, r4
+  bcc FillZerobss
+
+/* Call static constructors */
+    bl __libc_init_array
+/* Call the application's entry point.*/
+  bl  main
+  bx  lr
+.size  Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief  This is the code that gets called when the processor receives an
+ *         unexpected interrupt.  This simply enters an infinite loop, preserving
+ *         the system state for examination by a debugger.
+ * @param  None
+ * @retval None
+*/
+    .section  .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+  b  Infinite_Loop
+  .size  Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+   .section  .isr_vector,"a",%progbits
+  .type  g_pfnVectors, %object
+  .size  g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+  .word  _estack
+  .word  Reset_Handler
+
+  .word  NMI_Handler
+  .word  HardFault_Handler
+  .word  MemManage_Handler
+  .word  BusFault_Handler
+  .word  UsageFault_Handler
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  SVC_Handler
+  .word  DebugMon_Handler
+  .word  0
+  .word  PendSV_Handler
+  .word  SysTick_Handler
+
+  /* External Interrupts */
+  .word     WWDG_IRQHandler                   /* Window WatchDog Interrupt ( wwdg1_it, wwdg2_it) */
+  .word     PVD_AVD_IRQHandler                /* PVD/AVD through EXTI Line detection */
+  .word     TAMP_STAMP_IRQHandler             /* Tamper and TimeStamps through the EXTI line */
+  .word     RTC_WKUP_IRQHandler               /* RTC Wakeup through the EXTI line */
+  .word     FLASH_IRQHandler                  /* FLASH                        */
+  .word     RCC_IRQHandler                    /* RCC                          */
+  .word     EXTI0_IRQHandler                  /* EXTI Line0                   */
+  .word     EXTI1_IRQHandler                  /* EXTI Line1                   */
+  .word     EXTI2_IRQHandler                  /* EXTI Line2                   */
+  .word     EXTI3_IRQHandler                  /* EXTI Line3                   */
+  .word     EXTI4_IRQHandler                  /* EXTI Line4                   */
+  .word     DMA1_Stream0_IRQHandler           /* DMA1 Stream 0                */
+  .word     DMA1_Stream1_IRQHandler           /* DMA1 Stream 1                */
+  .word     DMA1_Stream2_IRQHandler           /* DMA1 Stream 2                */
+  .word     DMA1_Stream3_IRQHandler           /* DMA1 Stream 3                */
+  .word     DMA1_Stream4_IRQHandler           /* DMA1 Stream 4                */
+  .word     DMA1_Stream5_IRQHandler           /* DMA1 Stream 5                */
+  .word     DMA1_Stream6_IRQHandler           /* DMA1 Stream 6                */
+  .word     ADC_IRQHandler                    /* ADC1, ADC2 and ADC3s         */
+  .word     FDCAN1_IT0_IRQHandler             /* FDCAN1 interrupt line 0      */
+  .word     FDCAN2_IT0_IRQHandler             /* FDCAN2 interrupt line 0      */
+  .word     FDCAN1_IT1_IRQHandler             /* FDCAN1 interrupt line 1      */
+  .word     FDCAN2_IT1_IRQHandler             /* FDCAN2 interrupt line 1      */
+  .word     EXTI9_5_IRQHandler                /* External Line[9:5]s          */
+  .word     TIM1_BRK_IRQHandler               /* TIM1 Break interrupt         */
+  .word     TIM1_UP_IRQHandler                /* TIM1 Update interrupt        */
+  .word     TIM1_TRG_COM_IRQHandler           /* TIM1 Trigger and Commutation interrupt */
+  .word     TIM1_CC_IRQHandler                /* TIM1 Capture Compare         */
+  .word     TIM2_IRQHandler                   /* TIM2                         */
+  .word     TIM3_IRQHandler                   /* TIM3                         */
+  .word     TIM4_IRQHandler                   /* TIM4                         */
+  .word     I2C1_EV_IRQHandler                /* I2C1 Event                   */
+  .word     I2C1_ER_IRQHandler                /* I2C1 Error                   */
+  .word     I2C2_EV_IRQHandler                /* I2C2 Event                   */
+  .word     I2C2_ER_IRQHandler                /* I2C2 Error                   */
+  .word     SPI1_IRQHandler                   /* SPI1                         */
+  .word     SPI2_IRQHandler                   /* SPI2                         */
+  .word     USART1_IRQHandler                 /* USART1                       */
+  .word     USART2_IRQHandler                 /* USART2                       */
+  .word     USART3_IRQHandler                 /* USART3                       */
+  .word     EXTI15_10_IRQHandler              /* External Line[15:10]s        */
+  .word     RTC_Alarm_IRQHandler              /* RTC Alarm (A and B) through EXTI Line */
+  .word     0                                 /* Reserved                     */
+  .word     TIM8_BRK_TIM12_IRQHandler         /* TIM8 Break and TIM12         */
+  .word     TIM8_UP_TIM13_IRQHandler          /* TIM8 Update and TIM13        */
+  .word     TIM8_TRG_COM_TIM14_IRQHandler     /* TIM8 Trigger and Commutation and TIM14 */
+  .word     TIM8_CC_IRQHandler                /* TIM8 Capture Compare         */
+  .word     DMA1_Stream7_IRQHandler           /* DMA1 Stream7                 */
+  .word     FMC_IRQHandler                    /* FMC                          */
+  .word     SDMMC1_IRQHandler                 /* SDMMC1                       */
+  .word     TIM5_IRQHandler                   /* TIM5                         */
+  .word     SPI3_IRQHandler                   /* SPI3                         */
+  .word     UART4_IRQHandler                  /* UART4                        */
+  .word     UART5_IRQHandler                  /* UART5                        */
+  .word     TIM6_DAC_IRQHandler               /* TIM6 and DAC1&2 underrun errors */
+  .word     TIM7_IRQHandler                   /* TIM7                         */
+  .word     DMA2_Stream0_IRQHandler           /* DMA2 Stream 0                */
+  .word     DMA2_Stream1_IRQHandler           /* DMA2 Stream 1                */
+  .word     DMA2_Stream2_IRQHandler           /* DMA2 Stream 2                */
+  .word     DMA2_Stream3_IRQHandler           /* DMA2 Stream 3                */
+  .word     DMA2_Stream4_IRQHandler           /* DMA2 Stream 4                */
+  .word     ETH_IRQHandler                    /* Ethernet                     */
+  .word     ETH_WKUP_IRQHandler               /* Ethernet Wakeup through EXTI line */
+  .word     FDCAN_CAL_IRQHandler              /* FDCAN calibration unit interrupt  */
+  .word     CM7_SEV_IRQHandler                /* CM7 Send event interrupt for CM4  */
+  .word     CM4_SEV_IRQHandler                /* CM4 Send event interrupt for CM7  */
+  .word     0                                 /* Reserved                     */
+  .word     0                                 /* Reserved                     */
+  .word     DMA2_Stream5_IRQHandler           /* DMA2 Stream 5                */
+  .word     DMA2_Stream6_IRQHandler           /* DMA2 Stream 6                */
+  .word     DMA2_Stream7_IRQHandler           /* DMA2 Stream 7                */
+  .word     USART6_IRQHandler                 /* USART6                       */
+  .word     I2C3_EV_IRQHandler                /* I2C3 event                   */
+  .word     I2C3_ER_IRQHandler                /* I2C3 error                   */
+  .word     OTG_HS_EP1_OUT_IRQHandler         /* USB OTG HS End Point 1 Out   */
+  .word     OTG_HS_EP1_IN_IRQHandler          /* USB OTG HS End Point 1 In    */
+  .word     OTG_HS_WKUP_IRQHandler            /* USB OTG HS Wakeup through EXTI */
+  .word     OTG_HS_IRQHandler                 /* USB OTG HS                   */
+  .word     DCMI_IRQHandler                   /* DCMI                         */
+  .word     0                                 /* Reserved                     */
+  .word     RNG_IRQHandler                    /* Rng                          */
+  .word     FPU_IRQHandler                    /* FPU                          */
+  .word     UART7_IRQHandler                  /* UART7                        */
+  .word     UART8_IRQHandler                  /* UART8                        */
+  .word     SPI4_IRQHandler                   /* SPI4                         */
+  .word     SPI5_IRQHandler                   /* SPI5                         */
+  .word     SPI6_IRQHandler                   /* SPI6                         */
+  .word     SAI1_IRQHandler                   /* SAI1                         */
+  .word     LTDC_IRQHandler                   /* LTDC                         */
+  .word     LTDC_ER_IRQHandler                /* LTDC error                   */
+  .word     DMA2D_IRQHandler                  /* DMA2D                        */
+  .word     SAI2_IRQHandler                   /* SAI2                         */
+  .word     QUADSPI_IRQHandler                /* QUADSPI                      */
+  .word     LPTIM1_IRQHandler                 /* LPTIM1                       */
+  .word     CEC_IRQHandler                    /* HDMI_CEC                     */
+  .word     I2C4_EV_IRQHandler                /* I2C4 Event                   */
+  .word     I2C4_ER_IRQHandler                /* I2C4 Error                   */
+  .word     SPDIF_RX_IRQHandler               /* SPDIF_RX                     */
+  .word     OTG_FS_EP1_OUT_IRQHandler         /* USB OTG FS End Point 1 Out   */
+  .word     OTG_FS_EP1_IN_IRQHandler          /* USB OTG FS End Point 1 In    */
+  .word     OTG_FS_WKUP_IRQHandler            /* USB OTG FS Wakeup through EXTI */
+  .word     OTG_FS_IRQHandler                 /* USB OTG FS                   */
+  .word     DMAMUX1_OVR_IRQHandler            /* DMAMUX1 Overrun interrupt    */
+  .word     HRTIM1_Master_IRQHandler          /* HRTIM Master Timer global Interrupt */
+  .word     HRTIM1_TIMA_IRQHandler            /* HRTIM Timer A global Interrupt */
+  .word     HRTIM1_TIMB_IRQHandler            /* HRTIM Timer B global Interrupt */
+  .word     HRTIM1_TIMC_IRQHandler            /* HRTIM Timer C global Interrupt */
+  .word     HRTIM1_TIMD_IRQHandler            /* HRTIM Timer D global Interrupt */
+  .word     HRTIM1_TIME_IRQHandler            /* HRTIM Timer E global Interrupt */
+  .word     HRTIM1_FLT_IRQHandler             /* HRTIM Fault global Interrupt   */
+  .word     DFSDM1_FLT0_IRQHandler            /* DFSDM Filter0 Interrupt        */
+  .word     DFSDM1_FLT1_IRQHandler            /* DFSDM Filter1 Interrupt        */
+  .word     DFSDM1_FLT2_IRQHandler            /* DFSDM Filter2 Interrupt        */
+  .word     DFSDM1_FLT3_IRQHandler            /* DFSDM Filter3 Interrupt        */
+  .word     SAI3_IRQHandler                   /* SAI3 global Interrupt          */
+  .word     SWPMI1_IRQHandler                 /* Serial Wire Interface 1 global interrupt */
+  .word     TIM15_IRQHandler                  /* TIM15 global Interrupt      */
+  .word     TIM16_IRQHandler                  /* TIM16 global Interrupt      */
+  .word     TIM17_IRQHandler                  /* TIM17 global Interrupt      */
+  .word     MDIOS_WKUP_IRQHandler             /* MDIOS Wakeup  Interrupt     */
+  .word     MDIOS_IRQHandler                  /* MDIOS global Interrupt      */
+  .word     JPEG_IRQHandler                   /* JPEG global Interrupt       */
+  .word     MDMA_IRQHandler                   /* MDMA global Interrupt       */
+  .word     0                                 /* Reserved                   */
+  .word     SDMMC2_IRQHandler                 /* SDMMC2 global Interrupt     */
+  .word     HSEM1_IRQHandler                  /* HSEM1 global Interrupt      */
+  .word     HSEM2_IRQHandler                  /* HSEM1 global Interrupt      */
+  .word     ADC3_IRQHandler                   /* ADC3 global Interrupt       */
+  .word     DMAMUX2_OVR_IRQHandler            /* DMAMUX Overrun interrupt    */
+  .word     BDMA_Channel0_IRQHandler          /* BDMA Channel 0 global Interrupt */
+  .word     BDMA_Channel1_IRQHandler          /* BDMA Channel 1 global Interrupt */
+  .word     BDMA_Channel2_IRQHandler          /* BDMA Channel 2 global Interrupt */
+  .word     BDMA_Channel3_IRQHandler          /* BDMA Channel 3 global Interrupt */
+  .word     BDMA_Channel4_IRQHandler          /* BDMA Channel 4 global Interrupt */
+  .word     BDMA_Channel5_IRQHandler          /* BDMA Channel 5 global Interrupt */
+  .word     BDMA_Channel6_IRQHandler          /* BDMA Channel 6 global Interrupt */
+  .word     BDMA_Channel7_IRQHandler          /* BDMA Channel 7 global Interrupt */
+  .word     COMP1_IRQHandler                  /* COMP1 global Interrupt     */
+  .word     LPTIM2_IRQHandler                 /* LP TIM2 global interrupt   */
+  .word     LPTIM3_IRQHandler                 /* LP TIM3 global interrupt   */
+  .word     LPTIM4_IRQHandler                 /* LP TIM4 global interrupt   */
+  .word     LPTIM5_IRQHandler                 /* LP TIM5 global interrupt   */
+  .word     LPUART1_IRQHandler                /* LP UART1 interrupt         */
+  .word     WWDG_RST_IRQHandler               /* Window Watchdog reset interrupt (exti_d2_wwdg_it, exti_d1_wwdg_it) */
+  .word     CRS_IRQHandler                    /* Clock Recovery Global Interrupt */
+  .word     ECC_IRQHandler                    /* ECC diagnostic Global Interrupt */
+  .word     SAI4_IRQHandler                   /* SAI4 global interrupt      */
+  .word     0                                 /* Reserved                   */
+  .word     HOLD_CORE_IRQHandler              /* Hold core interrupt        */
+  .word     WAKEUP_PIN_IRQHandler             /* Interrupt for all 6 wake-up pins */
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+   .weak      NMI_Handler
+   .thumb_set NMI_Handler,Default_Handler
+
+   .weak      HardFault_Handler
+   .thumb_set HardFault_Handler,Default_Handler
+
+   .weak      MemManage_Handler
+   .thumb_set MemManage_Handler,Default_Handler
+
+   .weak      BusFault_Handler
+   .thumb_set BusFault_Handler,Default_Handler
+
+   .weak      UsageFault_Handler
+   .thumb_set UsageFault_Handler,Default_Handler
+
+   .weak      SVC_Handler
+   .thumb_set SVC_Handler,Default_Handler
+
+   .weak      DebugMon_Handler
+   .thumb_set DebugMon_Handler,Default_Handler
+
+   .weak      PendSV_Handler
+   .thumb_set PendSV_Handler,Default_Handler
+
+   .weak      SysTick_Handler
+   .thumb_set SysTick_Handler,Default_Handler
+
+   .weak      WWDG_IRQHandler
+   .thumb_set WWDG_IRQHandler,Default_Handler
+
+   .weak      PVD_AVD_IRQHandler
+   .thumb_set PVD_AVD_IRQHandler,Default_Handler
+
+   .weak      TAMP_STAMP_IRQHandler
+   .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+   .weak      RTC_WKUP_IRQHandler
+   .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+   .weak      FLASH_IRQHandler
+   .thumb_set FLASH_IRQHandler,Default_Handler
+
+   .weak      RCC_IRQHandler
+   .thumb_set RCC_IRQHandler,Default_Handler
+
+   .weak      EXTI0_IRQHandler
+   .thumb_set EXTI0_IRQHandler,Default_Handler
+
+   .weak      EXTI1_IRQHandler
+   .thumb_set EXTI1_IRQHandler,Default_Handler
+
+   .weak      EXTI2_IRQHandler
+   .thumb_set EXTI2_IRQHandler,Default_Handler
+
+   .weak      EXTI3_IRQHandler
+   .thumb_set EXTI3_IRQHandler,Default_Handler
+
+   .weak      EXTI4_IRQHandler
+   .thumb_set EXTI4_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream0_IRQHandler
+   .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream1_IRQHandler
+   .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream2_IRQHandler
+   .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream3_IRQHandler
+   .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream4_IRQHandler
+   .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream5_IRQHandler
+   .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream6_IRQHandler
+   .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
+
+   .weak      ADC_IRQHandler
+   .thumb_set ADC_IRQHandler,Default_Handler
+
+   .weak      FDCAN1_IT0_IRQHandler
+   .thumb_set FDCAN1_IT0_IRQHandler,Default_Handler
+
+   .weak      FDCAN2_IT0_IRQHandler
+   .thumb_set FDCAN2_IT0_IRQHandler,Default_Handler
+
+   .weak      FDCAN1_IT1_IRQHandler
+   .thumb_set FDCAN1_IT1_IRQHandler,Default_Handler
+
+   .weak      FDCAN2_IT1_IRQHandler
+   .thumb_set FDCAN2_IT1_IRQHandler,Default_Handler
+
+   .weak      EXTI9_5_IRQHandler
+   .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+   .weak      TIM1_BRK_IRQHandler
+   .thumb_set TIM1_BRK_IRQHandler,Default_Handler
+
+   .weak      TIM1_UP_IRQHandler
+   .thumb_set TIM1_UP_IRQHandler,Default_Handler
+
+   .weak      TIM1_TRG_COM_IRQHandler
+   .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
+
+   .weak      TIM1_CC_IRQHandler
+   .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+   .weak      TIM2_IRQHandler
+   .thumb_set TIM2_IRQHandler,Default_Handler
+
+   .weak      TIM3_IRQHandler
+   .thumb_set TIM3_IRQHandler,Default_Handler
+
+   .weak      TIM4_IRQHandler
+   .thumb_set TIM4_IRQHandler,Default_Handler
+
+   .weak      I2C1_EV_IRQHandler
+   .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+   .weak      I2C1_ER_IRQHandler
+   .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+   .weak      I2C2_EV_IRQHandler
+   .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+   .weak      I2C2_ER_IRQHandler
+   .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+   .weak      SPI1_IRQHandler
+   .thumb_set SPI1_IRQHandler,Default_Handler
+
+   .weak      SPI2_IRQHandler
+   .thumb_set SPI2_IRQHandler,Default_Handler
+
+   .weak      USART1_IRQHandler
+   .thumb_set USART1_IRQHandler,Default_Handler
+
+   .weak      USART2_IRQHandler
+   .thumb_set USART2_IRQHandler,Default_Handler
+
+   .weak      USART3_IRQHandler
+   .thumb_set USART3_IRQHandler,Default_Handler
+
+   .weak      EXTI15_10_IRQHandler
+   .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+   .weak      RTC_Alarm_IRQHandler
+   .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+   .weak      TIM8_BRK_TIM12_IRQHandler
+   .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
+
+   .weak      TIM8_UP_TIM13_IRQHandler
+   .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
+
+   .weak      TIM8_TRG_COM_TIM14_IRQHandler
+   .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
+
+   .weak      TIM8_CC_IRQHandler
+   .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream7_IRQHandler
+   .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
+
+   .weak      FMC_IRQHandler
+   .thumb_set FMC_IRQHandler,Default_Handler
+
+   .weak      SDMMC1_IRQHandler
+   .thumb_set SDMMC1_IRQHandler,Default_Handler
+
+   .weak      TIM5_IRQHandler
+   .thumb_set TIM5_IRQHandler,Default_Handler
+
+   .weak      SPI3_IRQHandler
+   .thumb_set SPI3_IRQHandler,Default_Handler
+
+   .weak      UART4_IRQHandler
+   .thumb_set UART4_IRQHandler,Default_Handler
+
+   .weak      UART5_IRQHandler
+   .thumb_set UART5_IRQHandler,Default_Handler
+
+   .weak      TIM6_DAC_IRQHandler
+   .thumb_set TIM6_DAC_IRQHandler,Default_Handler
+
+   .weak      TIM7_IRQHandler
+   .thumb_set TIM7_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream0_IRQHandler
+   .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream1_IRQHandler
+   .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream2_IRQHandler
+   .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream3_IRQHandler
+   .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream4_IRQHandler
+   .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
+
+   .weak      ETH_IRQHandler
+   .thumb_set ETH_IRQHandler,Default_Handler
+
+   .weak      ETH_WKUP_IRQHandler
+   .thumb_set ETH_WKUP_IRQHandler,Default_Handler
+
+   .weak      FDCAN_CAL_IRQHandler
+   .thumb_set FDCAN_CAL_IRQHandler,Default_Handler
+
+   .weak      CM7_SEV_IRQHandler
+   .thumb_set CM7_SEV_IRQHandler,Default_Handler
+
+   .weak      CM4_SEV_IRQHandler
+   .thumb_set CM4_SEV_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream5_IRQHandler
+   .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream6_IRQHandler
+   .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream7_IRQHandler
+   .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
+
+   .weak      USART6_IRQHandler
+   .thumb_set USART6_IRQHandler,Default_Handler
+
+   .weak      I2C3_EV_IRQHandler
+   .thumb_set I2C3_EV_IRQHandler,Default_Handler
+
+   .weak      I2C3_ER_IRQHandler
+   .thumb_set I2C3_ER_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_EP1_OUT_IRQHandler
+   .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_EP1_IN_IRQHandler
+   .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_WKUP_IRQHandler
+   .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_IRQHandler
+   .thumb_set OTG_HS_IRQHandler,Default_Handler
+
+   .weak      DCMI_IRQHandler
+   .thumb_set DCMI_IRQHandler,Default_Handler
+
+   .weak      RNG_IRQHandler
+   .thumb_set RNG_IRQHandler,Default_Handler
+
+   .weak      FPU_IRQHandler
+   .thumb_set FPU_IRQHandler,Default_Handler
+
+   .weak      UART7_IRQHandler
+   .thumb_set UART7_IRQHandler,Default_Handler
+
+   .weak      UART8_IRQHandler
+   .thumb_set UART8_IRQHandler,Default_Handler
+
+   .weak      SPI4_IRQHandler
+   .thumb_set SPI4_IRQHandler,Default_Handler
+
+   .weak      SPI5_IRQHandler
+   .thumb_set SPI5_IRQHandler,Default_Handler
+
+   .weak      SPI6_IRQHandler
+   .thumb_set SPI6_IRQHandler,Default_Handler
+
+   .weak      SAI1_IRQHandler
+   .thumb_set SAI1_IRQHandler,Default_Handler
+
+   .weak      LTDC_IRQHandler
+   .thumb_set LTDC_IRQHandler,Default_Handler
+
+   .weak      LTDC_ER_IRQHandler
+   .thumb_set LTDC_ER_IRQHandler,Default_Handler
+
+   .weak      DMA2D_IRQHandler
+   .thumb_set DMA2D_IRQHandler,Default_Handler
+
+   .weak      SAI2_IRQHandler
+   .thumb_set SAI2_IRQHandler,Default_Handler
+
+   .weak      QUADSPI_IRQHandler
+   .thumb_set QUADSPI_IRQHandler,Default_Handler
+
+   .weak      LPTIM1_IRQHandler
+   .thumb_set LPTIM1_IRQHandler,Default_Handler
+
+   .weak      CEC_IRQHandler
+   .thumb_set CEC_IRQHandler,Default_Handler
+
+   .weak      I2C4_EV_IRQHandler
+   .thumb_set I2C4_EV_IRQHandler,Default_Handler
+
+   .weak      I2C4_ER_IRQHandler
+   .thumb_set I2C4_ER_IRQHandler,Default_Handler
+
+   .weak      SPDIF_RX_IRQHandler
+   .thumb_set SPDIF_RX_IRQHandler,Default_Handler
+
+   .weak      OTG_FS_EP1_OUT_IRQHandler
+   .thumb_set OTG_FS_EP1_OUT_IRQHandler,Default_Handler
+
+   .weak      OTG_FS_EP1_IN_IRQHandler
+   .thumb_set OTG_FS_EP1_IN_IRQHandler,Default_Handler
+
+   .weak      OTG_FS_WKUP_IRQHandler
+   .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+   .weak      OTG_FS_IRQHandler
+   .thumb_set OTG_FS_IRQHandler,Default_Handler
+
+   .weak      DMAMUX1_OVR_IRQHandler
+   .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_Master_IRQHandler
+   .thumb_set HRTIM1_Master_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_TIMA_IRQHandler
+   .thumb_set HRTIM1_TIMA_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_TIMB_IRQHandler
+   .thumb_set HRTIM1_TIMB_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_TIMC_IRQHandler
+   .thumb_set HRTIM1_TIMC_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_TIMD_IRQHandler
+   .thumb_set HRTIM1_TIMD_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_TIME_IRQHandler
+   .thumb_set HRTIM1_TIME_IRQHandler,Default_Handler
+
+   .weak      HRTIM1_FLT_IRQHandler
+   .thumb_set HRTIM1_FLT_IRQHandler,Default_Handler
+
+   .weak      DFSDM1_FLT0_IRQHandler
+   .thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler
+
+   .weak      DFSDM1_FLT1_IRQHandler
+   .thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler
+
+   .weak      DFSDM1_FLT2_IRQHandler
+   .thumb_set DFSDM1_FLT2_IRQHandler,Default_Handler
+
+   .weak      DFSDM1_FLT3_IRQHandler
+   .thumb_set DFSDM1_FLT3_IRQHandler,Default_Handler
+
+   .weak      SAI3_IRQHandler
+   .thumb_set SAI3_IRQHandler,Default_Handler
+
+   .weak      SWPMI1_IRQHandler
+   .thumb_set SWPMI1_IRQHandler,Default_Handler
+
+   .weak      TIM15_IRQHandler
+   .thumb_set TIM15_IRQHandler,Default_Handler
+
+   .weak      TIM16_IRQHandler
+   .thumb_set TIM16_IRQHandler,Default_Handler
+
+   .weak      TIM17_IRQHandler
+   .thumb_set TIM17_IRQHandler,Default_Handler
+
+   .weak      MDIOS_WKUP_IRQHandler
+   .thumb_set MDIOS_WKUP_IRQHandler,Default_Handler
+
+   .weak      MDIOS_IRQHandler
+   .thumb_set MDIOS_IRQHandler,Default_Handler
+
+   .weak      JPEG_IRQHandler
+   .thumb_set JPEG_IRQHandler,Default_Handler
+
+   .weak      MDMA_IRQHandler
+   .thumb_set MDMA_IRQHandler,Default_Handler
+
+   .weak      SDMMC2_IRQHandler
+   .thumb_set SDMMC2_IRQHandler,Default_Handler
+
+   .weak      HSEM1_IRQHandler
+   .thumb_set HSEM1_IRQHandler,Default_Handler
+
+   .weak      HSEM2_IRQHandler
+   .thumb_set HSEM2_IRQHandler,Default_Handler
+
+   .weak      ADC3_IRQHandler
+   .thumb_set ADC3_IRQHandler,Default_Handler
+
+   .weak      DMAMUX2_OVR_IRQHandler
+   .thumb_set DMAMUX2_OVR_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel0_IRQHandler
+   .thumb_set BDMA_Channel0_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel1_IRQHandler
+   .thumb_set BDMA_Channel1_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel2_IRQHandler
+   .thumb_set BDMA_Channel2_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel3_IRQHandler
+   .thumb_set BDMA_Channel3_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel4_IRQHandler
+   .thumb_set BDMA_Channel4_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel5_IRQHandler
+   .thumb_set BDMA_Channel5_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel6_IRQHandler
+   .thumb_set BDMA_Channel6_IRQHandler,Default_Handler
+
+   .weak      BDMA_Channel7_IRQHandler
+   .thumb_set BDMA_Channel7_IRQHandler,Default_Handler
+
+   .weak      COMP1_IRQHandler
+   .thumb_set COMP1_IRQHandler,Default_Handler
+
+   .weak      LPTIM2_IRQHandler
+   .thumb_set LPTIM2_IRQHandler,Default_Handler
+
+   .weak      LPTIM3_IRQHandler
+   .thumb_set LPTIM3_IRQHandler,Default_Handler
+
+   .weak      LPTIM4_IRQHandler
+   .thumb_set LPTIM4_IRQHandler,Default_Handler
+
+   .weak      LPTIM5_IRQHandler
+   .thumb_set LPTIM5_IRQHandler,Default_Handler
+
+   .weak      LPUART1_IRQHandler
+   .thumb_set LPUART1_IRQHandler,Default_Handler
+
+   .weak      WWDG_RST_IRQHandler
+   .thumb_set WWDG_RST_IRQHandler,Default_Handler
+
+   .weak      CRS_IRQHandler
+   .thumb_set CRS_IRQHandler,Default_Handler
+
+   .weak      ECC_IRQHandler
+   .thumb_set ECC_IRQHandler,Default_Handler
+
+   .weak      SAI4_IRQHandler
+   .thumb_set SAI4_IRQHandler,Default_Handler
+
+   .weak      HOLD_CORE_IRQHandler
+   .thumb_set HOLD_CORE_IRQHandler,Default_Handler
+
+   .weak      WAKEUP_PIN_IRQHandler
+   .thumb_set WAKEUP_PIN_IRQHandler,Default_Handler
+
+

File diff suppressed because it is too large
+ 27 - 0
CM7/Debug/Common/Src/subdir.mk


File diff suppressed because it is too large
+ 54 - 0
CM7/Debug/Core/Src/subdir.mk


+ 27 - 0
CM7/Debug/Core/Startup/subdir.mk

@@ -0,0 +1,27 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables 
+S_SRCS += \
+../Core/Startup/startup_stm32h745xihx.s 
+
+OBJS += \
+./Core/Startup/startup_stm32h745xihx.o 
+
+S_DEPS += \
+./Core/Startup/startup_stm32h745xihx.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Core/Startup/%.o: ../Core/Startup/%.s Core/Startup/subdir.mk
+	arm-none-eabi-gcc -mcpu=cortex-m7 -g3 -DDEBUG -c -x assembler-with-cpp -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -o "$@" "$<"
+
+clean: clean-Core-2f-Startup
+
+clean-Core-2f-Startup:
+	-$(RM) ./Core/Startup/startup_stm32h745xihx.d ./Core/Startup/startup_stm32h745xihx.o
+
+.PHONY: clean-Core-2f-Startup
+

File diff suppressed because it is too large
+ 27 - 0
CM7/Debug/Drivers/BSP/Components/subdir.mk


File diff suppressed because it is too large
+ 122 - 0
CM7/Debug/Drivers/STM32H7xx_HAL_Driver/subdir.mk


File diff suppressed because it is too large
+ 27 - 0
CM7/Debug/LWIP/App/subdir.mk


File diff suppressed because it is too large
+ 27 - 0
CM7/Debug/LWIP/Target/subdir.mk


File diff suppressed because it is too large
+ 72 - 0
CM7/Debug/Middlewares/Third_Party/FreeRTOS/subdir.mk


File diff suppressed because it is too large
+ 429 - 0
CM7/Debug/Middlewares/Third_Party/LwIP/subdir.mk


File diff suppressed because it is too large
+ 54 - 0
CM7/Debug/Middlewares/Third_Party/MQTT/MQTTPacket/subdir.mk


File diff suppressed because it is too large
+ 30 - 0
CM7/Debug/Middlewares/Third_Party/MQTT/subdir.mk


File diff suppressed because it is too large
+ 48811 - 0
CM7/Debug/STM32H7-node-red-CM7.list


File diff suppressed because it is too large
+ 34338 - 0
CM7/Debug/STM32H7-node-red-CM7.map


+ 102 - 0
CM7/Debug/makefile

@@ -0,0 +1,102 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+-include ../makefile.init
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include Middlewares/Third_Party/MQTT/MQTTPacket/subdir.mk
+-include Middlewares/Third_Party/MQTT/subdir.mk
+-include Middlewares/Third_Party/LwIP/subdir.mk
+-include Middlewares/Third_Party/FreeRTOS/subdir.mk
+-include LWIP/Target/subdir.mk
+-include LWIP/App/subdir.mk
+-include Drivers/STM32H7xx_HAL_Driver/subdir.mk
+-include Drivers/BSP/Components/subdir.mk
+-include Core/Startup/subdir.mk
+-include Core/Src/subdir.mk
+-include Common/Src/subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(S_DEPS)),)
+-include $(S_DEPS)
+endif
+ifneq ($(strip $(S_UPPER_DEPS)),)
+-include $(S_UPPER_DEPS)
+endif
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+OPTIONAL_TOOL_DEPS := \
+$(wildcard ../makefile.defs) \
+$(wildcard ../makefile.init) \
+$(wildcard ../makefile.targets) \
+
+
+BUILD_ARTIFACT_NAME := STM32H7-node-red-CM7
+BUILD_ARTIFACT_EXTENSION := elf
+BUILD_ARTIFACT_PREFIX :=
+BUILD_ARTIFACT := $(BUILD_ARTIFACT_PREFIX)$(BUILD_ARTIFACT_NAME)$(if $(BUILD_ARTIFACT_EXTENSION),.$(BUILD_ARTIFACT_EXTENSION),)
+
+# Add inputs and outputs from these tool invocations to the build variables 
+EXECUTABLES += \
+STM32H7-node-red-CM7.elf \
+
+MAP_FILES += \
+STM32H7-node-red-CM7.map \
+
+SIZE_OUTPUT += \
+default.size.stdout \
+
+OBJDUMP_LIST += \
+STM32H7-node-red-CM7.list \
+
+
+# All Target
+all: main-build
+
+# Main-build Target
+main-build: STM32H7-node-red-CM7.elf secondary-outputs
+
+# Tool invocations
+STM32H7-node-red-CM7.elf STM32H7-node-red-CM7.map: $(OBJS) $(USER_OBJS) /home/jakubski/Projects/node-red/STM32H7-node-red/CM7/STM32H745XIHX_FLASH.ld makefile objects.list $(OPTIONAL_TOOL_DEPS)
+	arm-none-eabi-gcc -o "STM32H7-node-red-CM7.elf" @"objects.list" $(USER_OBJS) $(LIBS) -mcpu=cortex-m7 -T"/home/jakubski/Projects/node-red/STM32H7-node-red/CM7/STM32H745XIHX_FLASH.ld" --specs=nosys.specs -Wl,-Map="STM32H7-node-red-CM7.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
+	@echo 'Finished building target: $@'
+	@echo ' '
+
+default.size.stdout: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)
+	arm-none-eabi-size  $(EXECUTABLES)
+	@echo 'Finished building: $@'
+	@echo ' '
+
+STM32H7-node-red-CM7.list: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)
+	arm-none-eabi-objdump -h -S $(EXECUTABLES) > "STM32H7-node-red-CM7.list"
+	@echo 'Finished building: $@'
+	@echo ' '
+
+# Other Targets
+clean:
+	-$(RM) STM32H7-node-red-CM7.elf STM32H7-node-red-CM7.list STM32H7-node-red-CM7.map default.size.stdout
+	-@echo ' '
+
+secondary-outputs: $(SIZE_OUTPUT) $(OBJDUMP_LIST)
+
+fail-specified-linker-script-missing:
+	@echo 'Error: Cannot find the specified linker script. Check the linker settings in the build configuration.'
+	@exit 2
+
+warn-no-linker-script-specified:
+	@echo 'Warning: No linker script specified. Check the linker settings in the build configuration.'
+
+.PHONY: all clean dependents main-build fail-specified-linker-script-missing warn-no-linker-script-specified
+
+-include ../makefile.targets

+ 138 - 0
CM7/Debug/objects.list

@@ -0,0 +1,138 @@
+"./Common/Src/system_stm32h7xx_dualcore_boot_cm4_cm7.o"
+"./Core/Src/echo_server.o"
+"./Core/Src/freertos.o"
+"./Core/Src/lwiperf.o"
+"./Core/Src/main.o"
+"./Core/Src/mqtt_client.o"
+"./Core/Src/stm32h7xx_hal_msp.o"
+"./Core/Src/stm32h7xx_hal_timebase_tim.o"
+"./Core/Src/stm32h7xx_it.o"
+"./Core/Src/syscalls.o"
+"./Core/Src/sysmem.o"
+"./Core/Startup/startup_stm32h745xihx.o"
+"./Drivers/BSP/Components/lan8742.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_cortex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_dma.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_dma_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_exti.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_flash.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_flash_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_gpio.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_hsem.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_i2c.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_i2c_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_mdma.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_pwr.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_pwr_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_rcc.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_rcc_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_tim.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_tim_ex.o"
+"./LWIP/App/lwip.o"
+"./LWIP/Target/ethernetif.o"
+"./Middlewares/Third_Party/FreeRTOS/cmsis_os2.o"
+"./Middlewares/Third_Party/FreeRTOS/croutine.o"
+"./Middlewares/Third_Party/FreeRTOS/event_groups.o"
+"./Middlewares/Third_Party/FreeRTOS/heap_4.o"
+"./Middlewares/Third_Party/FreeRTOS/list.o"
+"./Middlewares/Third_Party/FreeRTOS/port.o"
+"./Middlewares/Third_Party/FreeRTOS/queue.o"
+"./Middlewares/Third_Party/FreeRTOS/stream_buffer.o"
+"./Middlewares/Third_Party/FreeRTOS/tasks.o"
+"./Middlewares/Third_Party/FreeRTOS/timers.o"
+"./Middlewares/Third_Party/LwIP/altcp.o"
+"./Middlewares/Third_Party/LwIP/altcp_alloc.o"
+"./Middlewares/Third_Party/LwIP/altcp_tcp.o"
+"./Middlewares/Third_Party/LwIP/api_lib.o"
+"./Middlewares/Third_Party/LwIP/api_msg.o"
+"./Middlewares/Third_Party/LwIP/auth.o"
+"./Middlewares/Third_Party/LwIP/autoip.o"
+"./Middlewares/Third_Party/LwIP/bridgeif.o"
+"./Middlewares/Third_Party/LwIP/bridgeif_fdb.o"
+"./Middlewares/Third_Party/LwIP/ccp.o"
+"./Middlewares/Third_Party/LwIP/chap-md5.o"
+"./Middlewares/Third_Party/LwIP/chap-new.o"
+"./Middlewares/Third_Party/LwIP/chap_ms.o"
+"./Middlewares/Third_Party/LwIP/def.o"
+"./Middlewares/Third_Party/LwIP/demand.o"
+"./Middlewares/Third_Party/LwIP/dhcp.o"
+"./Middlewares/Third_Party/LwIP/dhcp6.o"
+"./Middlewares/Third_Party/LwIP/dns.o"
+"./Middlewares/Third_Party/LwIP/eap.o"
+"./Middlewares/Third_Party/LwIP/ecp.o"
+"./Middlewares/Third_Party/LwIP/err.o"
+"./Middlewares/Third_Party/LwIP/etharp.o"
+"./Middlewares/Third_Party/LwIP/ethernet.o"
+"./Middlewares/Third_Party/LwIP/ethip6.o"
+"./Middlewares/Third_Party/LwIP/eui64.o"
+"./Middlewares/Third_Party/LwIP/fsm.o"
+"./Middlewares/Third_Party/LwIP/icmp.o"
+"./Middlewares/Third_Party/LwIP/icmp6.o"
+"./Middlewares/Third_Party/LwIP/if_api.o"
+"./Middlewares/Third_Party/LwIP/igmp.o"
+"./Middlewares/Third_Party/LwIP/inet6.o"
+"./Middlewares/Third_Party/LwIP/inet_chksum.o"
+"./Middlewares/Third_Party/LwIP/init.o"
+"./Middlewares/Third_Party/LwIP/ip.o"
+"./Middlewares/Third_Party/LwIP/ip4.o"
+"./Middlewares/Third_Party/LwIP/ip4_addr.o"
+"./Middlewares/Third_Party/LwIP/ip4_frag.o"
+"./Middlewares/Third_Party/LwIP/ip6.o"
+"./Middlewares/Third_Party/LwIP/ip6_addr.o"
+"./Middlewares/Third_Party/LwIP/ip6_frag.o"
+"./Middlewares/Third_Party/LwIP/ipcp.o"
+"./Middlewares/Third_Party/LwIP/ipv6cp.o"
+"./Middlewares/Third_Party/LwIP/lcp.o"
+"./Middlewares/Third_Party/LwIP/lowpan6.o"
+"./Middlewares/Third_Party/LwIP/lowpan6_ble.o"
+"./Middlewares/Third_Party/LwIP/lowpan6_common.o"
+"./Middlewares/Third_Party/LwIP/magic.o"
+"./Middlewares/Third_Party/LwIP/mem.o"
+"./Middlewares/Third_Party/LwIP/memp.o"
+"./Middlewares/Third_Party/LwIP/mld6.o"
+"./Middlewares/Third_Party/LwIP/mppe.o"
+"./Middlewares/Third_Party/LwIP/mqtt.o"
+"./Middlewares/Third_Party/LwIP/multilink.o"
+"./Middlewares/Third_Party/LwIP/nd6.o"
+"./Middlewares/Third_Party/LwIP/netbuf.o"
+"./Middlewares/Third_Party/LwIP/netdb.o"
+"./Middlewares/Third_Party/LwIP/netif.o"
+"./Middlewares/Third_Party/LwIP/netifapi.o"
+"./Middlewares/Third_Party/LwIP/pbuf.o"
+"./Middlewares/Third_Party/LwIP/ppp.o"
+"./Middlewares/Third_Party/LwIP/pppapi.o"
+"./Middlewares/Third_Party/LwIP/pppcrypt.o"
+"./Middlewares/Third_Party/LwIP/pppoe.o"
+"./Middlewares/Third_Party/LwIP/pppol2tp.o"
+"./Middlewares/Third_Party/LwIP/pppos.o"
+"./Middlewares/Third_Party/LwIP/raw.o"
+"./Middlewares/Third_Party/LwIP/slipif.o"
+"./Middlewares/Third_Party/LwIP/sockets.o"
+"./Middlewares/Third_Party/LwIP/stats.o"
+"./Middlewares/Third_Party/LwIP/sys.o"
+"./Middlewares/Third_Party/LwIP/sys_arch.o"
+"./Middlewares/Third_Party/LwIP/tcp.o"
+"./Middlewares/Third_Party/LwIP/tcp_in.o"
+"./Middlewares/Third_Party/LwIP/tcp_out.o"
+"./Middlewares/Third_Party/LwIP/tcpip.o"
+"./Middlewares/Third_Party/LwIP/timeouts.o"
+"./Middlewares/Third_Party/LwIP/udp.o"
+"./Middlewares/Third_Party/LwIP/upap.o"
+"./Middlewares/Third_Party/LwIP/utils.o"
+"./Middlewares/Third_Party/LwIP/vj.o"
+"./Middlewares/Third_Party/LwIP/zepif.o"
+"./Middlewares/Third_Party/MQTT/MQTTClient.o"
+"./Middlewares/Third_Party/MQTT/MQTTInterface.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTConnectClient.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTConnectServer.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTDeserializePublish.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTFormat.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTPacket.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSerializePublish.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSubscribeClient.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSubscribeServer.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTUnsubscribeClient.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTUnsubscribeServer.o"

+ 9 - 0
CM7/Debug/objects.mk

@@ -0,0 +1,9 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+

+ 36 - 0
CM7/Debug/sources.mk

@@ -0,0 +1,36 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+ELF_SRCS := 
+OBJ_SRCS := 
+S_SRCS := 
+C_SRCS := 
+S_UPPER_SRCS := 
+O_SRCS := 
+CYCLO_FILES := 
+SIZE_OUTPUT := 
+OBJDUMP_LIST := 
+SU_FILES := 
+EXECUTABLES := 
+OBJS := 
+MAP_FILES := 
+S_DEPS := 
+S_UPPER_DEPS := 
+C_DEPS := 
+
+# Every subdirectory with source files must be described here
+SUBDIRS := \
+Common/Src \
+Core/Src \
+Core/Startup \
+Drivers/BSP/Components \
+Drivers/STM32H7xx_HAL_Driver \
+LWIP/App \
+LWIP/Target \
+Middlewares/Third_Party/FreeRTOS \
+Middlewares/Third_Party/LwIP \
+Middlewares/Third_Party/MQTT \
+Middlewares/Third_Party/MQTT/MQTTPacket \
+

+ 251 - 0
CM7/LWIP/App/lwip.c

@@ -0,0 +1,251 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+  * File Name          : LWIP.c
+  * Description        : This file provides initialization code for LWIP
+  *                      middleWare.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lwip.h"
+#include "lwip/init.h"
+#include "lwip/netif.h"
+#if defined ( __CC_ARM )  /* MDK ARM Compiler */
+#include "lwip/sio.h"
+#endif /* MDK ARM Compiler */
+#include "ethernetif.h"
+//#include "dhcp_app.h"
+#include <string.h>
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+/* Private function prototypes -----------------------------------------------*/
+static void ethernet_link_status_updated(struct netif *netif);
+/* ETH Variables initialization ----------------------------------------------*/
+void Error_Handler(void);
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+
+/* Variables Initialization */
+struct netif gnetif;
+ip4_addr_t ipaddr;
+ip4_addr_t netmask;
+ip4_addr_t gw;
+//uint8_t IP_ADDRESS[4];
+//uint8_t NETMASK_ADDRESS[4];
+//uint8_t GATEWAY_ADDRESS[4];
+/* USER CODE BEGIN OS_THREAD_ATTR_CMSIS_RTOS_V2 */
+#define INTERFACE_THREAD_STACK_SIZE ( 1024 )
+osThreadAttr_t attributes;
+/* USER CODE END OS_THREAD_ATTR_CMSIS_RTOS_V2 */
+
+/* USER CODE BEGIN 2 */
+/* ETH_CODE: workaround to call LOCK_TCPIP_CORE after tcpip_init in MX_LWIP_Init
+ * This is to keep the code after MX code re-generation */
+static inline void tcpip_init_wrap(tcpip_init_done_fn tcpip_init_done, void *arg){
+	tcpip_init(tcpip_init_done, arg);
+	LOCK_TCPIP_CORE();
+}
+#define tcpip_init tcpip_init_wrap
+
+uint8_t is_link_up(void)
+{
+	return netif_is_up(&gnetif);
+}
+/* USER CODE END 2 */
+
+/**
+  * LwIP initialization function
+  */
+void MX_LWIP_Init(void)
+{
+  /* IP addresses initialization */
+//  IP_ADDRESS[0] = 192;
+//  IP_ADDRESS[1] = 168;
+//  IP_ADDRESS[2] = 1;
+//  IP_ADDRESS[3] = 10;
+//  NETMASK_ADDRESS[0] = 255;
+//  NETMASK_ADDRESS[1] = 255;
+//  NETMASK_ADDRESS[2] = 255;
+//  NETMASK_ADDRESS[3] = 0;
+//  GATEWAY_ADDRESS[0] = 0;
+//  GATEWAY_ADDRESS[1] = 0;
+//  GATEWAY_ADDRESS[2] = 0;
+//  GATEWAY_ADDRESS[3] = 0;
+
+	/* USER CODE BEGIN IP_ADDRESSES */
+#if !defined(USE_DHCP)
+  /* IP addresses initialization without DHCP (IPv4) */
+	ipaddr_aton(STATIC_IP, &ipaddr);
+	ipaddr_aton(STATIC_MASK, &netmask);
+	ipaddr_aton(STATIC_GW, &gw);
+#else
+    ip_addr_set_zero_ip4(&ipaddr);
+    ip_addr_set_zero_ip4(&netmask);
+    ip_addr_set_zero_ip4(&gw);
+#endif
+	/* USER CODE END IP_ADDRESSES */
+
+  /* Initilialize the LwIP stack with RTOS */
+  tcpip_init( NULL, NULL );
+
+//  IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);
+//  IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
+//  IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);
+
+  /* add the network interface (IPv4/IPv6) with RTOS */
+  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
+
+  /* Registers the default network interface */
+  netif_set_default(&gnetif);
+
+  if (netif_is_link_up(&gnetif))
+  {
+    /* When the netif is fully configured this function must be called */
+    netif_set_up(&gnetif);
+  }
+  else
+  {
+    /* When the netif link is down this function must be called */
+    netif_set_down(&gnetif);
+  }
+
+  /* Set the link callback function, this function is called on change of link status*/
+  netif_set_link_callback(&gnetif, ethernet_link_status_updated);
+
+  /* Create the Ethernet link handler thread */
+/* USER CODE BEGIN H7_OS_THREAD_NEW_CMSIS_RTOS_V2 */
+  memset(&attributes, 0x0, sizeof(osThreadAttr_t));
+  attributes.name = "EthLink";
+  attributes.stack_size = INTERFACE_THREAD_STACK_SIZE * 2;
+  attributes.priority = osPriorityBelowNormal;
+  osThreadNew(ethernet_link_thread, &gnetif, &attributes);
+//  DHCP_thread_init(&gnetif);
+/* USER CODE END H7_OS_THREAD_NEW_CMSIS_RTOS_V2 */
+
+/* USER CODE BEGIN 3 */
+  /* Start DHCP negotiation for a network interface (IPv4) */
+#if USE_DHCP
+  dhcp_start(&gnetif);
+#else
+  netif_set_addr(&gnetif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask), ip_2_ip4(&gw));
+#endif
+  /* ETH_CODE: call UNLOCK_TCPIP_CORE after we are done */
+  UNLOCK_TCPIP_CORE();
+/* USER CODE END 3 */
+}
+
+#ifdef USE_OBSOLETE_USER_CODE_SECTION_4
+/* Kept to help code migration. (See new 4_1, 4_2... sections) */
+/* Avoid to use this user section which will become obsolete. */
+/* USER CODE BEGIN 4 */
+/* USER CODE END 4 */
+#endif
+
+/**
+  * @brief  Notify the User about the network interface config status
+  * @param  netif: the network interface
+  * @retval None
+  */
+static void ethernet_link_status_updated(struct netif *netif)
+{
+  if (netif_is_up(netif))
+  {
+/* USER CODE BEGIN 5 */
+/* USER CODE END 5 */
+  }
+  else /* netif is down */
+  {
+/* USER CODE BEGIN 6 */
+/* USER CODE END 6 */
+  }
+}
+
+#if defined ( __CC_ARM )  /* MDK ARM Compiler */
+/**
+ * Opens a serial device for communication.
+ *
+ * @param devnum device number
+ * @return handle to serial device if successful, NULL otherwise
+ */
+sio_fd_t sio_open(u8_t devnum)
+{
+  sio_fd_t sd;
+
+/* USER CODE BEGIN 7 */
+  sd = 0; // dummy code
+/* USER CODE END 7 */
+
+  return sd;
+}
+
+/**
+ * Sends a single character to the serial device.
+ *
+ * @param c character to send
+ * @param fd serial device handle
+ *
+ * @note This function will block until the character can be sent.
+ */
+void sio_send(u8_t c, sio_fd_t fd)
+{
+/* USER CODE BEGIN 8 */
+/* USER CODE END 8 */
+}
+
+/**
+ * Reads from the serial device.
+ *
+ * @param fd serial device handle
+ * @param data pointer to data buffer for receiving
+ * @param len maximum length (in bytes) of data to receive
+ * @return number of bytes actually received - may be 0 if aborted by sio_read_abort
+ *
+ * @note This function will block until data can be received. The blocking
+ * can be cancelled by calling sio_read_abort().
+ */
+u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len)
+{
+  u32_t recved_bytes;
+
+/* USER CODE BEGIN 9 */
+  recved_bytes = 0; // dummy code
+/* USER CODE END 9 */
+  return recved_bytes;
+}
+
+/**
+ * Tries to read from the serial device. Same as sio_read but returns
+ * immediately if no data is available and never blocks.
+ *
+ * @param fd serial device handle
+ * @param data pointer to data buffer for receiving
+ * @param len maximum length (in bytes) of data to receive
+ * @return number of bytes actually received
+ */
+u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len)
+{
+  u32_t recved_bytes;
+
+/* USER CODE BEGIN 10 */
+  recved_bytes = 0; // dummy code
+/* USER CODE END 10 */
+  return recved_bytes;
+}
+#endif /* MDK ARM Compiler */
+

+ 76 - 0
CM7/LWIP/App/lwip.h

@@ -0,0 +1,76 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * File Name          : LWIP.h
+  * Description        : This file provides code for the configuration
+  *                      of the LWIP.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  *************************************************************************
+
+  */
+/* USER CODE END Header */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __mx_lwip_H
+#define __mx_lwip_H
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "lwip/opt.h"
+#include "lwip/mem.h"
+#include "lwip/memp.h"
+#include "netif/etharp.h"
+#include "lwip/dhcp.h"
+#include "lwip/netif.h"
+#include "lwip/timeouts.h"
+#include "ethernetif.h"
+
+/* Includes for RTOS ---------------------------------------------------------*/
+#if WITH_RTOS
+#include "lwip/tcpip.h"
+#endif /* WITH_RTOS */
+
+/* USER CODE BEGIN 0 */
+ uint8_t is_link_up(void);
+/* USER CODE END 0 */
+
+/* Global Variables ----------------------------------------------------------*/
+extern ETH_HandleTypeDef heth;
+
+/* LWIP init function */
+void MX_LWIP_Init(void);
+
+#if !WITH_RTOS
+/* USER CODE BEGIN 1 */
+/* Function defined in lwip.c to:
+ *   - Read a received packet from the Ethernet buffers
+ *   - Send it to the lwIP stack for handling
+ *   - Handle timeouts if NO_SYS_NO_TIMERS not set
+ */
+void MX_LWIP_Process(void);
+
+/* USER CODE END 1 */
+#endif /* WITH_RTOS */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__ mx_lwip_H */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */

File diff suppressed because it is too large
+ 1143 - 0
CM7/LWIP/Target/ethernetif.c


+ 47 - 0
CM7/LWIP/Target/ethernetif.h

@@ -0,0 +1,47 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+  * File Name          : ethernetif.h
+  * Description        : This file provides initialization code for LWIP
+  *                      middleWare.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+#ifndef __ETHERNETIF_H__
+#define __ETHERNETIF_H__
+
+#include "lwip/err.h"
+#include "lwip/netif.h"
+#include "cmsis_os.h"
+
+/* Within 'USER CODE' section, code will be kept by default at each generation */
+/* USER CODE BEGIN 0 */
+#include "node-red-config.h"
+/* USER CODE END 0 */
+
+/* Exported functions ------------------------------------------------------- */
+err_t ethernetif_init(struct netif *netif);
+
+void ethernetif_input(void* argument);
+void ethernet_link_thread(void* argument );
+void ethernetif_notify_conn_changed(struct netif *netif);
+
+void Error_Handler(void);
+u32_t sys_jiffies(void);
+u32_t sys_now(void);
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+#endif

+ 164 - 0
CM7/LWIP/Target/lwipopts.h

@@ -0,0 +1,164 @@
+/* USER CODE BEGIN Header */
+/**
+  ******************************************************************************
+  * File Name          : Target/lwipopts.h
+  * Description        : This file overrides LwIP stack default configuration
+  *                      done in opt.h file.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion --------------------------------------*/
+#ifndef __LWIPOPTS__H__
+#define __LWIPOPTS__H__
+
+#include "main.h"
+
+/*-----------------------------------------------------------------------------*/
+/* Current version of LwIP supported by CubeMx: 2.1.2 -*/
+/*-----------------------------------------------------------------------------*/
+
+/* Within 'USER CODE' section, code will be kept by default at each generation */
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* STM32CubeMX Specific Parameters (not defined in opt.h) ---------------------*/
+/* Parameters set in STM32CubeMX LwIP Configuration GUI -*/
+/*----- WITH_RTOS enabled (Since FREERTOS is set) -----*/
+#define WITH_RTOS 1
+/*----- CHECKSUM_BY_HARDWARE enabled -----*/
+#define CHECKSUM_BY_HARDWARE 1
+/*-----------------------------------------------------------------------------*/
+
+/* LwIP Stack Parameters (modified compared to initialization value in opt.h) -*/
+/* Parameters set in STM32CubeMX LwIP Configuration GUI -*/
+/*----- Default value in ETH configuration GUI in CubeMx: 1524 -----*/
+#define ETH_RX_BUFFER_SIZE 1536
+/*----- Value in opt.h for MEM_ALIGNMENT: 1 -----*/
+#define MEM_ALIGNMENT 4
+/*----- Default Value for MEM_SIZE: 1600 ---*/
+#define MEM_SIZE 131048
+/*----- Default Value for H7 devices: 0x30044000 -----*/
+#define LWIP_RAM_HEAP_POINTER 0x30020000
+/*----- Value supported for H7 devices: 1 -----*/
+#define LWIP_SUPPORT_CUSTOM_PBUF 1
+/*----- Value in opt.h for LWIP_ETHERNET: LWIP_ARP || PPPOE_SUPPORT -*/
+#define LWIP_ETHERNET 1
+/*----- Value in opt.h for LWIP_DNS_SECURE: (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) -*/
+#define LWIP_DNS_SECURE 7
+/*----- Default Value for TCP_MSS: 536 ---*/
+#define TCP_MSS 1460
+/*----- Default Value for TCP_SND_BUF: 2920 ---*/
+#define TCP_SND_BUF 5840
+/*----- Default Value for TCP_SND_QUEUELEN: 17 ---*/
+#define TCP_SND_QUEUELEN 16
+/*----- Value in opt.h for LWIP_NETIF_LINK_CALLBACK: 0 -----*/
+#define LWIP_NETIF_LINK_CALLBACK 1
+/*----- Value in opt.h for TCPIP_THREAD_STACKSIZE: 0 -----*/
+#define TCPIP_THREAD_STACKSIZE 2 * 2048
+/*----- Value in opt.h for TCPIP_THREAD_PRIO: 1 -----*/
+//#define TCPIP_THREAD_PRIO 24
+ #define TCPIP_THREAD_PRIO 48
+/*----- Value in opt.h for TCPIP_MBOX_SIZE: 0 -----*/
+#define TCPIP_MBOX_SIZE 6
+/*----- Value in opt.h for SLIPIF_THREAD_STACKSIZE: 0 -----*/
+#define SLIPIF_THREAD_STACKSIZE 1024
+/*----- Value in opt.h for SLIPIF_THREAD_PRIO: 1 -----*/
+#define SLIPIF_THREAD_PRIO 3
+/*----- Value in opt.h for DEFAULT_THREAD_STACKSIZE: 0 -----*/
+#define DEFAULT_THREAD_STACKSIZE 2048
+/*----- Value in opt.h for DEFAULT_THREAD_PRIO: 1 -----*/
+#define DEFAULT_THREAD_PRIO 3
+/*----- Value in opt.h for DEFAULT_UDP_RECVMBOX_SIZE: 0 -----*/
+#define DEFAULT_UDP_RECVMBOX_SIZE 6
+/*----- Value in opt.h for DEFAULT_TCP_RECVMBOX_SIZE: 0 -----*/
+#define DEFAULT_TCP_RECVMBOX_SIZE 6
+/*----- Value in opt.h for DEFAULT_ACCEPTMBOX_SIZE: 0 -----*/
+#define DEFAULT_ACCEPTMBOX_SIZE 6
+/*----- Value in opt.h for RECV_BUFSIZE_DEFAULT: INT_MAX -----*/
+#define RECV_BUFSIZE_DEFAULT 2000000000
+/*----- Value in opt.h for LWIP_STATS: 1 -----*/
+#define LWIP_STATS 0
+/*----- Value in opt.h for CHECKSUM_GEN_IP: 1 -----*/
+#define CHECKSUM_GEN_IP 0
+/*----- Value in opt.h for CHECKSUM_GEN_UDP: 1 -----*/
+#define CHECKSUM_GEN_UDP 0
+/*----- Value in opt.h for CHECKSUM_GEN_TCP: 1 -----*/
+#define CHECKSUM_GEN_TCP 0
+/*----- Value in opt.h for CHECKSUM_GEN_ICMP6: 1 -----*/
+#define CHECKSUM_GEN_ICMP6 0
+/*----- Value in opt.h for CHECKSUM_CHECK_IP: 1 -----*/
+#define CHECKSUM_CHECK_IP 0
+/*----- Value in opt.h for CHECKSUM_CHECK_UDP: 1 -----*/
+#define CHECKSUM_CHECK_UDP 0
+/*----- Value in opt.h for CHECKSUM_CHECK_TCP: 1 -----*/
+#define CHECKSUM_CHECK_TCP 0
+/*----- Value in opt.h for CHECKSUM_CHECK_ICMP6: 1 -----*/
+#define CHECKSUM_CHECK_ICMP6 0
+/*-----------------------------------------------------------------------------*/
+/* USER CODE BEGIN 1 */
+#define LWIP_DHCP 1
+#define LWIP_NETCONN 1
+#define LWIP_TCP 1
+#define LWIP_SO_RCVTIMEO 1
+#define LWIP_SO_RCVBUF 1
+//#define MEMP_NUM_SYS_TIMEOUT 8
+//#define TCP_SNDLOWAT 1071
+//#define TCP_SNDQUEUELOWAT 5
+//#define TCP_WND_UPDATE_THRESHOLD 536
+//#define MEMP_NUM_NETCONN 8
+//#define MEMP_NUM_NETBUF 4
+//#define LWIP_ALTCP 1
+//#define LWIP_TCPIP_CORE_LOCKING 1
+#define LWIP_DEBUG 0
+#define NETIF_DEBUG LWIP_DBG_OFF
+#define DHCP_DEBUG LWIP_DBG_OFF
+#define UDP_DEBUG  LWIP_DBG_OFF
+#define TCP_DEBUG  LWIP_DBG_OFF
+#define MEMP_DEBUG LWIP_DBG_OFF
+#define MEM_DEBUG LWIP_DBG_OFF
+#define ICMP_DEBUG LWIP_DBG_OFF
+#define MQTT_DEBUG LWIP_DBG_OFF
+#define API_LIB_DEBUG LWIP_DBG_OFF
+/* ETH_CODE: first 2 macros solve errno issue with GCC 10 and ST LwIP
+ * LWIPERF_CHECK_RX_DATA enables data check for iperf. Removing it might improve performance.
+ */
+#undef LWIP_PROVIDE_ERRNO
+#define LWIP_ERRNO_STDINCLUDE
+#define LWIPERF_CHECK_RX_DATA 1
+
+/* ETH_CODE: macro and prototypes for proper (hopefuly?)
+ * multithreading support
+ */
+#define LOCK_TCPIP_CORE sys_lock_tcpip_core
+#define UNLOCK_TCPIP_CORE sys_unlock_tcpip_core
+
+#define LWIP_ASSERT_CORE_LOCKED sys_check_core_locking
+#define LWIP_MARK_TCPIP_THREAD sys_mark_tcpip_thread
+
+void sys_lock_tcpip_core(void);
+void sys_unlock_tcpip_core(void);
+
+void sys_check_core_locking(void);
+void sys_mark_tcpip_thread(void);
+/* USER CODE END 1 */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__LWIPOPTS__H__ */

+ 719 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTClient.c

@@ -0,0 +1,719 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 2017 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *   Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation
+ *   Ian Craggs - fix for #96 - check rem_len in readPacket
+ *   Ian Craggs - add ability to set message handler separately #6
+ *******************************************************************************/
+#include <MQTTClient.h>
+#include <stdio.h>
+#include <string.h>
+#include "cmsis_os.h"
+
+osMutexId_t mqttMutex;
+
+static void NewMessageData(MessageData* md, MQTTString* aTopicName, MQTTMessage* aMessage) {
+    md->topicName = aTopicName;
+    md->message = aMessage;
+}
+
+
+static int getNextPacketId(MQTTClient *c) {
+    return c->next_packetid = (c->next_packetid == MAX_PACKET_ID) ? 1 : c->next_packetid + 1;
+}
+
+
+static int sendPacket(MQTTClient* c, int length, Timer* timer)
+{
+    int rc = FAILURE,
+        sent = 0;
+
+    while (sent < length && !TimerIsExpired(timer))
+    {
+        rc = c->ipstack->mqttwrite(c->ipstack, &c->buf[sent], length, TimerLeftMS(timer));
+        if (rc < 0)  // there was an error writing the data
+            break;
+        sent += rc;
+    }
+    if (sent == length)
+    {
+        TimerCountdown(&c->last_sent, c->keepAliveInterval); // record the fact that we have MQTT_SUCCESSfully sent the packet
+        rc = MQTT_SUCCESS;
+    }
+    else
+        rc = FAILURE;
+    return rc;
+}
+
+
+void MQTTClientInit(MQTTClient* c, Network* network, unsigned int command_timeout_ms,
+		unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size)
+{
+    int i;
+    c->ipstack = network;
+
+    for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
+        c->messageHandlers[i].topicFilter = 0;
+    c->command_timeout_ms = command_timeout_ms;
+    c->buf = sendbuf;
+    c->buf_size = sendbuf_size;
+    c->readbuf = readbuf;
+    c->readbuf_size = readbuf_size;
+    c->isconnected = 0;
+    c->cleansession = 0;
+    c->ping_outstanding = 0;
+    c->defaultMessageHandler = NULL;
+	  c->next_packetid = 1;
+    TimerInit(&c->last_sent);
+    TimerInit(&c->last_received);
+#if defined(MQTT_TASK)
+	  MutexInit(&c->mutex);
+#endif
+	  if(mqttMutex == NULL)
+	  {
+		  osMutexDef(mqttMutex);
+		  mqttMutex = osMutexNew(NULL);
+	  }
+}
+
+
+static int decodePacket(MQTTClient* c, int* value, int timeout)
+{
+    unsigned char i;
+    int multiplier = 1;
+    int len = 0;
+    const int MAX_NO_OF_REMAINING_LENGTH_BYTES = 4;
+
+    *value = 0;
+    do
+    {
+        int rc = MQTTPACKET_READ_ERROR;
+
+        if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
+        {
+            rc = MQTTPACKET_READ_ERROR; /* bad data */
+            goto exit;
+        }
+        rc = c->ipstack->mqttread(c->ipstack, &i, 1, timeout);
+        if (rc != 1)
+            goto exit;
+        *value += (i & 127) * multiplier;
+        multiplier *= 128;
+    } while ((i & 128) != 0);
+exit:
+    return len;
+}
+
+
+static int readPacket(MQTTClient* c, Timer* timer)
+{
+    MQTTHeader header = {0};
+    int len = 0;
+    int rem_len = 0;
+
+    /* 1. read the header byte.  This has the packet type in it */
+    int rc = c->ipstack->mqttread(c->ipstack, c->readbuf, 1, TimerLeftMS(timer));
+    if (rc != 1)
+        goto exit;
+
+    len = 1;
+    /* 2. read the remaining length.  This is variable in itself */
+    decodePacket(c, &rem_len, TimerLeftMS(timer));
+    len += MQTTPacket_encode(c->readbuf + 1, rem_len); /* put the original remaining length back into the buffer */
+
+    if (rem_len > (c->readbuf_size - len))
+    {
+        rc = BUFFER_OVERFLOW;
+        goto exit;
+    }
+
+    /* 3. read the rest of the buffer using a callback to supply the rest of the data */
+    if (rem_len > 0 && (rc = c->ipstack->mqttread(c->ipstack, c->readbuf + len, rem_len, TimerLeftMS(timer)) != rem_len)) {
+        rc = 0;
+        goto exit;
+    }
+
+    header.byte = c->readbuf[0];
+    rc = header.bits.type;
+    if (c->keepAliveInterval > 0)
+        TimerCountdown(&c->last_received, c->keepAliveInterval); // record the fact that we have MQTT_SUCCESSfully received a packet
+exit:
+    return rc;
+}
+
+
+// assume topic filter and name is in correct format
+// # can only be at end
+// + and # can only be next to separator
+static char isTopicMatched(char* topicFilter, MQTTString* topicName)
+{
+    char* curf = topicFilter;
+    char* curn = topicName->lenstring.data;
+    char* curn_end = curn + topicName->lenstring.len;
+
+    while (*curf && curn < curn_end)
+    {
+        if (*curn == '/' && *curf != '/')
+            break;
+        if (*curf != '+' && *curf != '#' && *curf != *curn)
+            break;
+        if (*curf == '+')
+        {   // skip until we meet the next separator, or end of string
+            char* nextpos = curn + 1;
+            while (nextpos < curn_end && *nextpos != '/')
+                nextpos = ++curn + 1;
+        }
+        else if (*curf == '#')
+            curn = curn_end - 1;    // skip until end of string
+        curf++;
+        curn++;
+    };
+
+    return (curn == curn_end) && (*curf == '\0');
+}
+
+
+int deliverMessage(MQTTClient* c, MQTTString* topicName, MQTTMessage* message)
+{
+    int i;
+    int rc = FAILURE;
+
+    // we have to find the right message handler - indexed by topic
+    for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
+    {
+        if (c->messageHandlers[i].topicFilter != 0 && (MQTTPacket_equals(topicName, (char*)c->messageHandlers[i].topicFilter) ||
+                isTopicMatched((char*)c->messageHandlers[i].topicFilter, topicName)))
+        {
+            if (c->messageHandlers[i].fp != NULL)
+            {
+                MessageData md;
+                NewMessageData(&md, topicName, message);
+                c->messageHandlers[i].fp(&md);
+                rc = MQTT_SUCCESS;
+            }
+        }
+    }
+
+    if (rc == FAILURE && c->defaultMessageHandler != NULL)
+    {
+        MessageData md;
+        NewMessageData(&md, topicName, message);
+        c->defaultMessageHandler(&md);
+        rc = MQTT_SUCCESS;
+    }
+
+    return rc;
+}
+
+
+int keepalive(MQTTClient* c)
+{
+    int rc = MQTT_SUCCESS;
+
+    if (c->keepAliveInterval == 0)
+        goto exit;
+
+    if (TimerIsExpired(&c->last_sent) || TimerIsExpired(&c->last_received))
+    {
+        if (c->ping_outstanding)
+            rc = FAILURE; /* PINGRESP not received in keepalive interval */
+        else
+        {
+            Timer timer;
+            TimerInit(&timer);
+            TimerCountdownMS(&timer, 1000);
+            int len = MQTTSerialize_pingreq(c->buf, c->buf_size);
+            if (len > 0 && (rc = sendPacket(c, len, &timer)) == MQTT_SUCCESS) // send the ping packet
+                c->ping_outstanding = 1;
+        }
+    }
+
+exit:
+    return rc;
+}
+
+
+void MQTTCleanSession(MQTTClient* c)
+{
+    int i = 0;
+
+    for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
+        c->messageHandlers[i].topicFilter = NULL;
+}
+
+
+void MQTTCloseSession(MQTTClient* c)
+{
+    c->ping_outstanding = 0;
+    c->isconnected = 0;
+    if (c->cleansession)
+        MQTTCleanSession(c);
+}
+
+
+int cycle(MQTTClient* c, Timer* timer)
+{
+    int len = 0,
+        rc = MQTT_SUCCESS;
+
+    int packet_type = readPacket(c, timer);     /* read the socket, see what work is due */
+
+    switch (packet_type)
+    {
+        default:
+            /* no more data to read, unrecoverable. Or read packet fails due to unexpected network error */
+            rc = packet_type;
+            goto exit;
+        case 0: /* timed out reading packet */
+            break;
+        case CONNACK:
+        case PUBACK:
+        case SUBACK:
+        case UNSUBACK:
+            break;
+        case PUBLISH:
+        {
+            MQTTString topicName;
+            MQTTMessage msg;
+            int intQoS;
+            msg.payloadlen = 0; /* this is a size_t, but deserialize publish sets this as int */
+            if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName,
+               (unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
+                goto exit;
+            msg.qos = (enum QoS)intQoS;
+            deliverMessage(c, &topicName, &msg);
+            if (msg.qos != QOS0)
+            {
+                if (msg.qos == QOS1)
+                    len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
+                else if (msg.qos == QOS2)
+                    len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
+                if (len <= 0)
+                    rc = FAILURE;
+                else
+                    rc = sendPacket(c, len, timer);
+                if (rc == FAILURE)
+                    goto exit; // there was a problem
+            }
+            break;
+        }
+        case PUBREC:
+        case PUBREL:
+        {
+            unsigned short mypacketid;
+            unsigned char dup, type;
+            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
+                rc = FAILURE;
+            else if ((len = MQTTSerialize_ack(c->buf, c->buf_size,
+                (packet_type == PUBREC) ? PUBREL : PUBCOMP, 0, mypacketid)) <= 0)
+                rc = FAILURE;
+            else if ((rc = sendPacket(c, len, timer)) != MQTT_SUCCESS) // send the PUBREL packet
+                rc = FAILURE; // there was a problem
+            if (rc == FAILURE)
+                goto exit; // there was a problem
+            break;
+        }
+
+        case PUBCOMP:
+            break;
+        case PINGRESP:
+            c->ping_outstanding = 0;
+            break;
+    }
+
+    if (keepalive(c) != MQTT_SUCCESS) {
+        //check only keepalive FAILURE status so that previous FAILURE status can be considered as FAULT
+        rc = FAILURE;
+    }
+
+exit:
+    if (rc == MQTT_SUCCESS)
+        rc = packet_type;
+    else if (c->isconnected)
+        MQTTCloseSession(c);
+    return rc;
+}
+
+
+int MQTTYield(MQTTClient* c, int timeout_ms)
+{
+    int rc = MQTT_SUCCESS;
+    Timer timer;
+
+    TimerInit(&timer);
+    TimerCountdownMS(&timer, timeout_ms);
+
+	  do
+    {
+        if (cycle(c, &timer) < 0)
+        {
+            rc = FAILURE;
+            break;
+        }
+  	} while (!TimerIsExpired(&timer));
+
+    return rc;
+}
+
+int MQTTIsConnected(MQTTClient* client)
+{
+  return client->isconnected;
+}
+
+void MQTTRun(void* parm)
+{
+	Timer timer;
+	MQTTClient* c = (MQTTClient*)parm;
+
+	TimerInit(&timer);
+
+	while (1)
+	{
+#if defined(MQTT_TASK)
+		MutexLock(&c->mutex);
+#endif
+		osMutexAcquire(mqttMutex, osWaitForever);
+		TimerCountdownMS(&timer, 500); /* Don't wait too long if no traffic is incoming */
+		cycle(c, &timer);
+#if defined(MQTT_TASK)
+		MutexUnlock(&c->mutex);
+#endif
+		osMutexRelease(mqttMutex);
+	}
+}
+
+
+#if defined(MQTT_TASK)
+int MQTTStartTask(MQTTClient* client)
+{
+	return ThreadStart(&client->thread, &MQTTRun, client);
+}
+#endif
+
+
+int waitfor(MQTTClient* c, int packet_type, Timer* timer)
+{
+    int rc = FAILURE;
+
+    do
+    {
+        if (TimerIsExpired(timer))
+            break; // we timed out
+        rc = cycle(c, timer);
+    }
+    while (rc != packet_type && rc >= 0);
+
+    return rc;
+}
+
+
+
+
+int MQTTConnectWithResults(MQTTClient* c, MQTTPacket_connectData* options, MQTTConnackData* data)
+{
+    Timer connect_timer;
+    int rc = FAILURE;
+    MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer;
+    int len = 0;
+
+#if defined(MQTT_TASK)
+	  MutexLock(&c->mutex);
+#endif
+	  osMutexAcquire(mqttMutex, osWaitForever);
+	  if (c->isconnected) /* don't send connect packet again if we are already connected */
+		  goto exit;
+
+    TimerInit(&connect_timer);
+    TimerCountdownMS(&connect_timer, c->command_timeout_ms);
+
+    if (options == 0)
+        options = &default_options; /* set default options if none were supplied */
+
+    c->keepAliveInterval = options->keepAliveInterval;
+    c->cleansession = options->cleansession;
+    TimerCountdown(&c->last_received, c->keepAliveInterval);
+    if ((len = MQTTSerialize_connect(c->buf, c->buf_size, options)) <= 0)
+        goto exit;
+    if ((rc = sendPacket(c, len, &connect_timer)) != MQTT_SUCCESS)  // send the connect packet
+        goto exit; // there was a problem
+
+    // this will be a blocking call, wait for the connack
+    if (waitfor(c, CONNACK, &connect_timer) == CONNACK)
+    {
+        data->rc = 0;
+        data->sessionPresent = 0;
+        if (MQTTDeserialize_connack(&data->sessionPresent, &data->rc, c->readbuf, c->readbuf_size) == 1)
+            rc = data->rc;
+//        	rc = MQTT_SUCCESS;
+        else
+            rc = FAILURE;
+    }
+    else
+        rc = FAILURE;
+
+exit:
+    if (rc == MQTT_SUCCESS)
+    {
+        c->isconnected = 1;
+        c->ping_outstanding = 0;
+    }
+
+#if defined(MQTT_TASK)
+	  MutexUnlock(&c->mutex);
+#endif
+	osMutexRelease(mqttMutex);
+    return rc;
+}
+
+
+int MQTTConnect(MQTTClient* c, MQTTPacket_connectData* options)
+{
+    MQTTConnackData data;
+    return MQTTConnectWithResults(c, options, &data);
+}
+
+
+int MQTTSetMessageHandler(MQTTClient* c, const char* topicFilter, messageHandler messageHandler)
+{
+    int rc = FAILURE;
+    int i = -1;
+
+    /* first check for an existing matching slot */
+    for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
+    {
+        if (c->messageHandlers[i].topicFilter != NULL && strcmp(c->messageHandlers[i].topicFilter, topicFilter) == 0)
+        {
+            if (messageHandler == NULL) /* remove existing */
+            {
+                c->messageHandlers[i].topicFilter = NULL;
+                c->messageHandlers[i].fp = NULL;
+            }
+            rc = MQTT_SUCCESS; /* return i when adding new subscription */
+            break;
+        }
+    }
+    /* if no existing, look for empty slot (unless we are removing) */
+    if (messageHandler != NULL) {
+        if (rc == FAILURE)
+        {
+            for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
+            {
+                if (c->messageHandlers[i].topicFilter == NULL)
+                {
+                    rc = MQTT_SUCCESS;
+                    break;
+                }
+            }
+        }
+        if (i < MAX_MESSAGE_HANDLERS)
+        {
+            c->messageHandlers[i].topicFilter = topicFilter;
+            c->messageHandlers[i].fp = messageHandler;
+        }
+    }
+    return rc;
+}
+
+
+int MQTTSubscribeWithResults(MQTTClient* c, const char* topicFilter, enum QoS qos,
+       messageHandler messageHandler, MQTTSubackData* data)
+{
+    int rc = FAILURE;
+    Timer timer;
+    int len = 0;
+    MQTTString topic = MQTTString_initializer;
+    topic.cstring = (char *)topicFilter;
+
+#if defined(MQTT_TASK)
+	  MutexLock(&c->mutex);
+#endif
+	  osMutexAcquire(mqttMutex, osWaitForever);
+	  if (!c->isconnected)
+		    goto exit;
+
+    TimerInit(&timer);
+    TimerCountdownMS(&timer, c->command_timeout_ms);
+
+    len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, (int*)&qos);
+    if (len <= 0)
+        goto exit;
+    if ((rc = sendPacket(c, len, &timer)) != MQTT_SUCCESS) // send the subscribe packet
+        goto exit;             // there was a problem
+
+    if (waitfor(c, SUBACK, &timer) == SUBACK)      // wait for suback
+    {
+        int count = 0;
+        unsigned short mypacketid;
+        data->grantedQoS = QOS0;
+        if (MQTTDeserialize_suback(&mypacketid, 1, &count, (int*)&data->grantedQoS, c->readbuf, c->readbuf_size) == 1)
+        {
+            if (data->grantedQoS != 0x80)
+                rc = MQTTSetMessageHandler(c, topicFilter, messageHandler);
+        }
+    }
+    else
+        rc = FAILURE;
+
+exit:
+    if (rc == FAILURE)
+        MQTTCloseSession(c);
+#if defined(MQTT_TASK)
+	  MutexUnlock(&c->mutex);
+#endif
+	osMutexRelease(mqttMutex);
+    return rc;
+}
+
+
+int MQTTSubscribe(MQTTClient* c, const char* topicFilter, enum QoS qos,
+       messageHandler messageHandler)
+{
+    MQTTSubackData data;
+    return MQTTSubscribeWithResults(c, topicFilter, qos, messageHandler, &data);
+}
+
+
+int MQTTUnsubscribe(MQTTClient* c, const char* topicFilter)
+{
+    int rc = FAILURE;
+    Timer timer;
+    MQTTString topic = MQTTString_initializer;
+    topic.cstring = (char *)topicFilter;
+    int len = 0;
+
+#if defined(MQTT_TASK)
+	  MutexLock(&c->mutex);
+#endif
+	  osMutexAcquire(mqttMutex, osWaitForever);
+	  if (!c->isconnected)
+		  goto exit;
+
+    TimerInit(&timer);
+    TimerCountdownMS(&timer, c->command_timeout_ms);
+
+    if ((len = MQTTSerialize_unsubscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic)) <= 0)
+        goto exit;
+    if ((rc = sendPacket(c, len, &timer)) != MQTT_SUCCESS) // send the subscribe packet
+        goto exit; // there was a problem
+
+    if (waitfor(c, UNSUBACK, &timer) == UNSUBACK)
+    {
+        unsigned short mypacketid;  // should be the same as the packetid above
+        if (MQTTDeserialize_unsuback(&mypacketid, c->readbuf, c->readbuf_size) == 1)
+        {
+            /* remove the subscription message handler associated with this topic, if there is one */
+            MQTTSetMessageHandler(c, topicFilter, NULL);
+        }
+    }
+    else
+        rc = FAILURE;
+
+exit:
+    if (rc == FAILURE)
+        MQTTCloseSession(c);
+#if defined(MQTT_TASK)
+	  MutexUnlock(&c->mutex);
+#endif
+	  osMutexRelease(mqttMutex);
+    return rc;
+}
+
+
+int MQTTPublish(MQTTClient* c, const char* topicName, MQTTMessage* message)
+{
+    int rc = FAILURE;
+    Timer timer;
+    MQTTString topic = MQTTString_initializer;
+    topic.cstring = (char *)topicName;
+    int len = 0;
+
+#if defined(MQTT_TASK)
+	  MutexLock(&c->mutex);
+#endif
+	  osMutexAcquire(mqttMutex, osWaitForever);
+	  if (!c->isconnected)
+		    goto exit;
+
+    TimerInit(&timer);
+    TimerCountdownMS(&timer, c->command_timeout_ms);
+
+    if (message->qos == QOS1 || message->qos == QOS2)
+        message->id = getNextPacketId(c);
+
+    len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id,
+              topic, (unsigned char*)message->payload, message->payloadlen);
+    if (len <= 0)
+        goto exit;
+    if ((rc = sendPacket(c, len, &timer)) != MQTT_SUCCESS) // send the subscribe packet
+        goto exit; // there was a problem
+
+    if (message->qos == QOS1)
+    {
+        if (waitfor(c, PUBACK, &timer) == PUBACK)
+        {
+            unsigned short mypacketid;
+            unsigned char dup, type;
+            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
+                rc = FAILURE;
+        }
+        else
+            rc = FAILURE;
+    }
+    else if (message->qos == QOS2)
+    {
+        if (waitfor(c, PUBCOMP, &timer) == PUBCOMP)
+        {
+            unsigned short mypacketid;
+            unsigned char dup, type;
+            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
+                rc = FAILURE;
+        }
+        else
+            rc = FAILURE;
+    }
+
+exit:
+    if (rc == FAILURE)
+        MQTTCloseSession(c);
+#if defined(MQTT_TASK)
+	  MutexUnlock(&c->mutex);
+#endif
+	  osMutexRelease(mqttMutex);
+    return rc;
+}
+
+
+int MQTTDisconnect(MQTTClient* c)
+{
+    int rc = FAILURE;
+    Timer timer;     // we might wait for incomplete incoming publishes to complete
+    int len = 0;
+
+#if defined(MQTT_TASK)
+	MutexLock(&c->mutex);
+#endif
+	osMutexAcquire(mqttMutex, osWaitForever);
+    TimerInit(&timer);
+    TimerCountdownMS(&timer, c->command_timeout_ms);
+
+	  len = MQTTSerialize_disconnect(c->buf, c->buf_size);
+    if (len > 0)
+        rc = sendPacket(c, len, &timer);            // send the disconnect packet
+    MQTTCloseSession(c);
+
+#if defined(MQTT_TASK)
+	  MutexUnlock(&c->mutex);
+#endif
+	  osMutexRelease(mqttMutex);
+    return rc;
+}

+ 234 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTClient.h

@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 2017 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - documentation and platform specific header
+ *    Ian Craggs - add setMessageHandler function
+ *******************************************************************************/
+
+#if !defined(MQTT_CLIENT_H)
+#define MQTT_CLIENT_H
+
+#if defined(__cplusplus)
+ extern "C" {
+#endif
+
+#if defined(WIN32_DLL) || defined(WIN64_DLL)
+  #define DLLImport __declspec(dllimport)
+  #define DLLExport __declspec(dllexport)
+#elif defined(LINUX_SO)
+  #define DLLImport extern
+  #define DLLExport  __attribute__ ((visibility ("default")))
+#else
+  #define DLLImport
+  #define DLLExport
+#endif
+
+#include <MQTTPacket.h>
+#include <MQTTInterface.h>
+
+#if defined(MQTTCLIENT_PLATFORM_HEADER)
+/* The following sequence of macros converts the MQTTCLIENT_PLATFORM_HEADER value
+ * into a string constant suitable for use with include.
+ */
+#define xstr(s) str(s)
+#define str(s) #s
+#include xstr(MQTTCLIENT_PLATFORM_HEADER)
+#endif
+
+#define MAX_PACKET_ID 65535 /* according to the MQTT specification - do not change! */
+
+#if !defined(MAX_MESSAGE_HANDLERS)
+#define MAX_MESSAGE_HANDLERS 5 /* redefinable - how many subscriptions do you want? */
+#endif
+
+enum QoS { QOS0, QOS1, QOS2, SUBFAIL=0x80 };
+
+/* all failure return codes must be negative */
+enum returnCode { BUFFER_OVERFLOW = -2, FAILURE = -1, MQTT_SUCCESS = 0 };
+
+/* The Platform specific header must define the Network and Timer structures and functions
+ * which operate on them.
+ *
+typedef struct Network
+{
+	int (*mqttread)(Network*, unsigned char* read_buffer, int, int);
+	int (*mqttwrite)(Network*, unsigned char* send_buffer, int, int);
+} Network;*/
+
+/* The Timer structure must be defined in the platform specific header,
+ * and have the following functions to operate on it.  */
+extern void TimerInit(Timer*);
+extern char TimerIsExpired(Timer*);
+extern void TimerCountdownMS(Timer*, unsigned int);
+extern void TimerCountdown(Timer*, unsigned int);
+extern int TimerLeftMS(Timer*);
+
+typedef struct MQTTMessage
+{
+    enum QoS qos;
+    unsigned char retained;
+    unsigned char dup;
+    unsigned short id;
+    void *payload;
+    size_t payloadlen;
+} MQTTMessage;
+
+typedef struct MessageData
+{
+    MQTTMessage* message;
+    MQTTString* topicName;
+} MessageData;
+
+typedef struct MQTTConnackData
+{
+    unsigned char rc;
+    unsigned char sessionPresent;
+} MQTTConnackData;
+
+typedef struct MQTTSubackData
+{
+    enum QoS grantedQoS;
+} MQTTSubackData;
+
+typedef void (*messageHandler)(MessageData*);
+
+typedef struct MQTTClient
+{
+    unsigned int next_packetid,
+      command_timeout_ms;
+    size_t buf_size,
+      readbuf_size;
+    unsigned char *buf,
+      *readbuf;
+    unsigned int keepAliveInterval;
+    char ping_outstanding;
+    int isconnected;
+    int cleansession;
+
+    struct MessageHandlers
+    {
+        const char* topicFilter;
+        void (*fp) (MessageData*);
+    } messageHandlers[MAX_MESSAGE_HANDLERS];      /* Message handlers are indexed by subscription topic */
+
+    void (*defaultMessageHandler) (MessageData*);
+
+    Network* ipstack;
+    Timer last_sent, last_received;
+#if defined(MQTT_TASK)
+    Mutex mutex;
+    Thread thread;
+#endif
+} MQTTClient;
+
+#define DefaultClient {0, 0, 0, 0, NULL, NULL, 0, 0, 0}
+
+
+/**
+ * Create an MQTT client object
+ * @param client
+ * @param network
+ * @param command_timeout_ms
+ * @param
+ */
+DLLExport void MQTTClientInit(MQTTClient* client, Network* network, unsigned int command_timeout_ms,
+		unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size);
+
+/** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack
+ *  The nework object must be connected to the network endpoint before calling this
+ *  @param options - connect options
+ *  @return success code
+ */
+DLLExport int MQTTConnectWithResults(MQTTClient* client, MQTTPacket_connectData* options,
+    MQTTConnackData* data);
+
+/** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack
+ *  The nework object must be connected to the network endpoint before calling this
+ *  @param options - connect options
+ *  @return success code
+ */
+DLLExport int MQTTConnect(MQTTClient* client, MQTTPacket_connectData* options);
+
+/** MQTT Publish - send an MQTT publish packet and wait for all acks to complete for all QoSs
+ *  @param client - the client object to use
+ *  @param topic - the topic to publish to
+ *  @param message - the message to send
+ *  @return success code
+ */
+DLLExport int MQTTPublish(MQTTClient* client, const char*, MQTTMessage*);
+
+/** MQTT SetMessageHandler - set or remove a per topic message handler
+ *  @param client - the client object to use
+ *  @param topicFilter - the topic filter set the message handler for
+ *  @param messageHandler - pointer to the message handler function or NULL to remove
+ *  @return success code
+ */
+DLLExport int MQTTSetMessageHandler(MQTTClient* c, const char* topicFilter, messageHandler messageHandler);
+
+/** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning.
+ *  @param client - the client object to use
+ *  @param topicFilter - the topic filter to subscribe to
+ *  @param message - the message to send
+ *  @return success code
+ */
+DLLExport int MQTTSubscribe(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler);
+
+/** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning.
+ *  @param client - the client object to use
+ *  @param topicFilter - the topic filter to subscribe to
+ *  @param message - the message to send
+ *  @param data - suback granted QoS returned
+ *  @return success code
+ */
+DLLExport int MQTTSubscribeWithResults(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler, MQTTSubackData* data);
+
+/** MQTT Subscribe - send an MQTT unsubscribe packet and wait for unsuback before returning.
+ *  @param client - the client object to use
+ *  @param topicFilter - the topic filter to unsubscribe from
+ *  @return success code
+ */
+DLLExport int MQTTUnsubscribe(MQTTClient* client, const char* topicFilter);
+
+/** MQTT Disconnect - send an MQTT disconnect packet and close the connection
+ *  @param client - the client object to use
+ *  @return success code
+ */
+DLLExport int MQTTDisconnect(MQTTClient* client);
+
+/** MQTT Yield - MQTT background
+ *  @param client - the client object to use
+ *  @param time - the time, in milliseconds, to yield for
+ *  @return success code
+ */
+DLLExport int MQTTYield(MQTTClient* client, int time);
+
+/** MQTT isConnected
+ *  @param client - the client object to use
+ *  @return truth value indicating whether the client is connected to the server
+ */
+DLLExport int MQTTIsConnected(MQTTClient* client);
+
+#if defined(MQTT_TASK)
+/** MQTT start background thread for a client.  After this, MQTTYield should not be called.
+*  @param client - the client object to use
+*  @return success code
+*/
+DLLExport int MQTTStartTask(MQTTClient* client);
+#endif
+
+#if defined(__cplusplus)
+     }
+#endif
+
+#endif

+ 189 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTInterface.c

@@ -0,0 +1,189 @@
+#include "MQTTInterface.h"
+//#include "stm32f4xx_hal.h"
+#include "stm32h7xx_hal.h"
+
+#include <string.h>
+#include "lwip.h"
+#include "lwip/api.h"
+#include "lwip/sockets.h"
+
+#define MQTT_PORT	1883
+#define SERVER_IP1	192
+#define SERVER_IP2	168
+#define SERVER_IP3	1
+#define SERVER_IP4	34
+
+uint32_t MilliTimer;
+
+//Timer functions
+char TimerIsExpired(Timer *timer) {
+	long left = timer->end_time - MilliTimer;
+	return (left < 0);
+}
+
+void TimerCountdownMS(Timer *timer, unsigned int timeout) {
+	timer->end_time = MilliTimer + timeout;
+}
+
+void TimerCountdown(Timer *timer, unsigned int timeout) {
+	timer->end_time = MilliTimer + (timeout * 1000);
+}
+
+int TimerLeftMS(Timer *timer) {
+	long left = timer->end_time - MilliTimer;
+	return (left < 0) ? 0 : left;
+}
+
+void TimerInit(Timer *timer) {
+	timer->end_time = 0;
+}
+
+#ifdef MQTT_LWIP_SOCKET
+void NewNetwork(Network *n) {
+	n->socket = 0; //clear
+	n->mqttread = net_read; //receive function
+	n->mqttwrite = net_write; //send function
+	n->disconnect = net_disconnect; //disconnection function
+}
+
+int ConnectNetwork(Network *n, char *ip, int port) {
+	struct sockaddr_in server_addr;
+
+	if(n->socket)
+	{
+		close(n->socket);
+	}
+
+	n->socket = socket(PF_INET, SOCK_STREAM, 0); //create socket
+	if(n->socket < 0)
+	{
+		n->socket = 0;
+		return -1;
+	}
+
+	memset(&server_addr, 0, sizeof(struct sockaddr_in)); //broker address info
+	server_addr.sin_family = AF_INET;
+	server_addr.sin_addr.s_addr = inet_addr(ip);
+	server_addr.sin_port = htons(port);
+
+	if(connect(n->socket, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_in)) < 0) //connect to the broker
+	{
+		close(n->socket);
+		return -1;
+	}
+	return 0;
+}
+
+int net_read(Network *n, unsigned char *buffer, int len, int timeout_ms) {
+	int available;
+
+	/* !!! LWIP_SO_RCVBUF must be enabled !!! */
+	if(ioctl(n->socket, FIONREAD, &available) < 0) return -1; //check receive buffer
+
+	if(available > 0)
+	{
+		return recv(n->socket, buffer, len, 0);
+	}
+
+	return 0;
+}
+
+int net_write(Network *n, unsigned char *buffer, int len, int timeout_ms) {
+	return send(n->socket, buffer, len, 0);
+}
+
+void net_disconnect(Network *n) {
+	close(n->socket);
+	n->socket = 0;
+}
+
+#elif defined(MQTT_LWIP_NETCONN)
+void NewNetwork(Network *n) {
+	n->conn = NULL;
+	n->buf = NULL;
+	n->offset = 0;
+
+	n->mqttread = net_read;
+	n->mqttwrite = net_write;
+	n->disconnect = net_disconnect;
+}
+
+int ConnectNetwork(Network *n, char *ip, int port) {
+	err_t err;
+	ip_addr_t server_ip;
+//	char data[4] = "DUPA";
+//	uint16_t len = sizeof(data);
+
+	ipaddr_aton(ip, &server_ip);
+//	IP4_ADDR(&server_ip, 192, 168, 1, 34);
+//	IP4_ADDR(&server_ip, 192, 168, 1, 63);
+//	IP4_ADDR(&local_ip, 192, 168, 1, 117);
+
+	n->conn = netconn_new(NETCONN_TCP);
+	if (n->conn != NULL) {
+//		err = netconn_bind(n->conn, NULL, 0);
+		err = netconn_connect(n->conn, &server_ip, port);
+
+		if (err != ERR_OK) {
+			netconn_delete(n->conn); //free memory
+			return -1;
+		}
+		n->conn->recv_timeout = 100;
+//		netconn_write(n->conn, data, len, NETCONN_COPY);
+//		netconn_delete(n->conn); //free memory
+	}
+	return 0;
+}
+
+int net_read(Network *n, unsigned char *buffer, int len, int timeout_ms) {
+	int rc;
+	struct netbuf *inbuf;
+	int offset = 0;
+	int bytes = 0;
+
+	while(bytes < len) {
+		if(n->buf != NULL) {
+			inbuf = n->buf;
+			offset = n->offset;
+			rc = ERR_OK;
+		} else {
+			rc = netconn_recv(n->conn, &inbuf);
+			offset = 0;
+		}
+
+		if(rc != ERR_OK) {
+			if(rc != ERR_TIMEOUT) {
+				bytes = -1;
+			}
+			break;
+		} else {
+			int nblen = netbuf_len(inbuf) - offset;
+			if((bytes+nblen) > len) {
+				netbuf_copy_partial(inbuf, buffer+bytes, len-bytes,offset);
+				n->buf = inbuf;
+				n->offset = offset + len - bytes;
+				bytes = len;
+			} else {
+				netbuf_copy_partial(inbuf, buffer+bytes, nblen, offset);
+				bytes += nblen;
+				netbuf_delete(inbuf);
+				n->buf = NULL;
+				n->offset = 0;
+			}
+		}
+	}
+	return bytes;
+}
+
+int net_write(Network *n, unsigned char *buffer, int len, int timeout_ms) {
+	int rc = netconn_write(n->conn, buffer, len, NETCONN_NOCOPY);
+	if(rc != ERR_OK) return -1;
+	return len;
+}
+
+void net_disconnect(Network *n) {
+	netconn_close(n->conn); //close session
+	netconn_delete(n->conn); //free memory
+	n->conn = NULL;
+}
+#endif

+ 50 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTInterface.h

@@ -0,0 +1,50 @@
+/*
+ * MQTTInterface.h
+ *
+ *  Created on: 2020. 4. 29.
+ *      Author: https://github.com/eziya
+ */
+
+#ifndef __MQTT_INTERFACE_H_
+#define __MQTT_INTERFACE_H_
+
+#define MQTT_LWIP_SOCKET	//Use SOCKET API
+//#define MQTT_LWIP_NETCONN //Use NETCONN API
+
+typedef struct Timer Timer;
+
+struct Timer {
+	unsigned long systick_period;
+	unsigned long end_time;
+};
+
+typedef struct Network Network;
+
+struct Network
+{
+#ifdef MQTT_LWIP_SOCKET
+	int socket;
+#elif defined(MQTT_LWIP_NETCONN)
+	struct netconn *conn;
+	struct netbuf *buf;
+	int offset;
+#endif
+	int (*mqttread) (Network*, unsigned char*, int, int);
+	int (*mqttwrite) (Network*, unsigned char*, int, int);
+	void (*disconnect) (Network*);
+};
+
+
+void InitTimer(Timer*);
+char TimerIsExpired(Timer*);
+void TimerCountdownMS(Timer*, unsigned int);
+void TimerCountdown(Timer*, unsigned int);
+int  TimerLeftMS(Timer*);
+
+int  net_read(Network*, unsigned char*, int, int);
+int  net_write(Network*, unsigned char*, int, int);
+void net_disconnect(Network*);
+void NewNetwork(Network*);
+int  ConnectNetwork(Network*, char*, int);
+
+#endif

+ 148 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTConnect.h

@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 2017 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - add connack return code definitions 
+ *    Xiang Rong - 442039 Add makefile to Embedded C client
+ *    Ian Craggs - fix for issue #64, bit order in connack response
+ *******************************************************************************/
+
+#ifndef MQTTCONNECT_H_
+#define MQTTCONNECT_H_
+
+enum connack_return_codes
+{
+    MQTT_CONNECTION_ACCEPTED = 0,
+    MQTT_UNNACCEPTABLE_PROTOCOL = 1,
+    MQTT_CLIENTID_REJECTED = 2,
+    MQTT_SERVER_UNAVAILABLE = 3,
+    MQTT_BAD_USERNAME_OR_PASSWORD = 4,
+    MQTT_NOT_AUTHORIZED = 5,
+};
+
+#if !defined(DLLImport)
+  #define DLLImport
+#endif
+#if !defined(DLLExport)
+  #define DLLExport
+#endif
+
+
+typedef union
+{
+	unsigned char all;	/**< all connect flags */
+#if defined(REVERSED)
+	struct
+	{
+		unsigned int username : 1;			/**< 3.1 user name */
+		unsigned int password : 1; 			/**< 3.1 password */
+		unsigned int willRetain : 1;		/**< will retain setting */
+		unsigned int willQoS : 2;				/**< will QoS value */
+		unsigned int will : 1;			    /**< will flag */
+		unsigned int cleansession : 1;	  /**< clean session flag */
+		unsigned int : 1;	  	          /**< unused */
+	} bits;
+#else
+	struct
+	{
+		unsigned int : 1;	     					/**< unused */
+		unsigned int cleansession : 1;	  /**< cleansession flag */
+		unsigned int will : 1;			    /**< will flag */
+		unsigned int willQoS : 2;				/**< will QoS value */
+		unsigned int willRetain : 1;		/**< will retain setting */
+		unsigned int password : 1; 			/**< 3.1 password */
+		unsigned int username : 1;			/**< 3.1 user name */
+	} bits;
+#endif
+} MQTTConnectFlags;	/**< connect flags byte */
+
+
+
+/**
+ * Defines the MQTT "Last Will and Testament" (LWT) settings for
+ * the connect packet.
+ */
+typedef struct
+{
+	/** The eyecatcher for this structure.  must be MQTW. */
+	char struct_id[4];
+	/** The version number of this structure.  Must be 0 */
+	int struct_version;
+	/** The LWT topic to which the LWT message will be published. */
+	MQTTString topicName;
+	/** The LWT payload. */
+	MQTTString message;
+	/**
+      * The retained flag for the LWT message (see MQTTAsync_message.retained).
+      */
+	unsigned char retained;
+	/**
+      * The quality of service setting for the LWT message (see
+      * MQTTAsync_message.qos and @ref qos).
+      */
+	char qos;
+} MQTTPacket_willOptions;
+
+
+#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 }
+
+
+typedef struct
+{
+	/** The eyecatcher for this structure.  must be MQTC. */
+	char struct_id[4];
+	/** The version number of this structure.  Must be 0 */
+	int struct_version;
+	/** Version of MQTT to be used.  3 = 3.1 4 = 3.1.1
+	  */
+	unsigned char MQTTVersion;
+	MQTTString clientID;
+	unsigned short keepAliveInterval;
+	unsigned char cleansession;
+	unsigned char willFlag;
+	MQTTPacket_willOptions will;
+	MQTTString username;
+	MQTTString password;
+} MQTTPacket_connectData;
+
+typedef union
+{
+	unsigned char all;	/**< all connack flags */
+#if defined(REVERSED)
+	struct
+	{
+    unsigned int reserved : 7;	  	    /**< unused */
+		unsigned int sessionpresent : 1;    /**< session present flag */
+	} bits;
+#else
+	struct
+	{
+		unsigned int sessionpresent : 1;    /**< session present flag */
+    unsigned int reserved: 7;	     			/**< unused */
+	} bits;
+#endif
+} MQTTConnackFlags;	/**< connack flags byte */
+
+#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \
+		MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }
+
+DLLExport int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options);
+DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len);
+
+DLLExport int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent);
+DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen);
+
+DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int buflen);
+DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int buflen);
+
+#endif /* MQTTCONNECT_H_ */

+ 213 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTConnectClient.c

@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+#include <MQTTPacket.h>
+#include <string.h>
+#include <StackTrace.h>
+
+/**
+  * Determines the length of the MQTT connect packet that would be produced using the supplied connect options.
+  * @param options the options to be used to build the connect packet
+  * @return the length of buffer needed to contain the serialized version of the packet
+  */
+int MQTTSerialize_connectLength(MQTTPacket_connectData* options)
+{
+	int len = 0;
+
+	FUNC_ENTRY;
+
+	if (options->MQTTVersion == 3)
+		len = 12; /* variable depending on MQTT or MQIsdp */
+	else if (options->MQTTVersion == 4)
+		len = 10;
+
+	len += MQTTstrlen(options->clientID)+2;
+	if (options->willFlag)
+		len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2;
+	if (options->username.cstring || options->username.lenstring.data)
+		len += MQTTstrlen(options->username)+2;
+	if (options->password.cstring || options->password.lenstring.data)
+		len += MQTTstrlen(options->password)+2;
+
+	FUNC_EXIT_RC(len);
+	return len;
+}
+
+
+/**
+  * Serializes the connect options into the buffer.
+  * @param buf the buffer into which the packet will be serialized
+  * @param len the length in bytes of the supplied buffer
+  * @param options the options to be used to build the connect packet
+  * @return serialized length, or error if 0
+  */
+int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options)
+{
+	unsigned char *ptr = buf;
+	MQTTHeader header = {0};
+	MQTTConnectFlags flags = {0};
+	int len = 0;
+	int rc = -1;
+
+	FUNC_ENTRY;
+	if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen)
+	{
+		rc = MQTTPACKET_BUFFER_TOO_SHORT;
+		goto exit;
+	}
+
+	header.byte = 0;
+	header.bits.type = CONNECT;
+	writeChar(&ptr, header.byte); /* write header */
+
+	ptr += MQTTPacket_encode(ptr, len); /* write remaining length */
+
+	if (options->MQTTVersion == 4)
+	{
+		writeCString(&ptr, "MQTT");
+		writeChar(&ptr, (char) 4);
+	}
+	else
+	{
+		writeCString(&ptr, "MQIsdp");
+		writeChar(&ptr, (char) 3);
+	}
+
+	flags.all = 0;
+	flags.bits.cleansession = options->cleansession;
+	flags.bits.will = (options->willFlag) ? 1 : 0;
+	if (flags.bits.will)
+	{
+		flags.bits.willQoS = options->will.qos;
+		flags.bits.willRetain = options->will.retained;
+	}
+
+	if (options->username.cstring || options->username.lenstring.data)
+		flags.bits.username = 1;
+	if (options->password.cstring || options->password.lenstring.data)
+		flags.bits.password = 1;
+
+	writeChar(&ptr, flags.all);
+	writeInt(&ptr, options->keepAliveInterval);
+	writeMQTTString(&ptr, options->clientID);
+	if (options->willFlag)
+	{
+		writeMQTTString(&ptr, options->will.topicName);
+		writeMQTTString(&ptr, options->will.message);
+	}
+	if (flags.bits.username)
+		writeMQTTString(&ptr, options->username);
+	if (flags.bits.password)
+		writeMQTTString(&ptr, options->password);
+
+	rc = ptr - buf;
+
+	exit: FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+/**
+  * Deserializes the supplied (wire) buffer into connack data - return code
+  * @param sessionPresent the session present flag returned (only for MQTT 3.1.1)
+  * @param connack_rc returned integer value of the connack return code
+  * @param buf the raw buffer data, of the correct length determined by the remaining length field
+  * @param len the length in bytes of the data in the supplied buffer
+  * @return error code.  1 is success, 0 is failure
+  */
+int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen)
+{
+	MQTTHeader header = {0};
+	unsigned char* curdata = buf;
+	unsigned char* enddata = NULL;
+	int rc = 0;
+	int mylen;
+	MQTTConnackFlags flags = {0};
+
+	FUNC_ENTRY;
+	header.byte = readChar(&curdata);
+	if (header.bits.type != CONNACK)
+		goto exit;
+
+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
+	enddata = curdata + mylen;
+	if (enddata - curdata < 2)
+		goto exit;
+
+	flags.all = readChar(&curdata);
+	*sessionPresent = flags.bits.sessionpresent;
+	*connack_rc = readChar(&curdata);
+
+	rc = 1;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+/**
+  * Serializes a 0-length packet into the supplied buffer, ready for writing to a socket
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer, to avoid overruns
+  * @param packettype the message type
+  * @return serialized length, or error if 0
+  */
+int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype)
+{
+	MQTTHeader header = {0};
+	int rc = -1;
+	unsigned char *ptr = buf;
+
+	FUNC_ENTRY;
+	if (buflen < 2)
+	{
+		rc = MQTTPACKET_BUFFER_TOO_SHORT;
+		goto exit;
+	}
+	header.byte = 0;
+	header.bits.type = packettype;
+	writeChar(&ptr, header.byte); /* write header */
+
+	ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */
+	rc = ptr - buf;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+/**
+  * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer, to avoid overruns
+  * @return serialized length, or error if 0
+  */
+int MQTTSerialize_disconnect(unsigned char* buf, int buflen)
+{
+	return MQTTSerialize_zero(buf, buflen, DISCONNECT);
+}
+
+
+/**
+  * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer, to avoid overruns
+  * @return serialized length, or error if 0
+  */
+int MQTTSerialize_pingreq(unsigned char* buf, int buflen)
+{
+	return MQTTSerialize_zero(buf, buflen, PINGREQ);
+}

+ 148 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTConnectServer.c

@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+#include <MQTTPacket.h>
+#include <string.h>
+#include <StackTrace.h>
+
+#define min(a, b) ((a < b) ? a : b)
+
+
+/**
+  * Validates MQTT protocol name and version combinations
+  * @param protocol the MQTT protocol name as an MQTTString
+  * @param version the MQTT protocol version number, as in the connect packet
+  * @return correct MQTT combination?  1 is true, 0 is false
+  */
+int MQTTPacket_checkVersion(MQTTString* protocol, int version)
+{
+	int rc = 0;
+
+	if (version == 3 && memcmp(protocol->lenstring.data, "MQIsdp",
+			min(6, protocol->lenstring.len)) == 0)
+		rc = 1;
+	else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT",
+			min(4, protocol->lenstring.len)) == 0)
+		rc = 1;
+	return rc;
+}
+
+
+/**
+  * Deserializes the supplied (wire) buffer into connect data structure
+  * @param data the connect data structure to be filled out
+  * @param buf the raw buffer data, of the correct length determined by the remaining length field
+  * @param len the length in bytes of the data in the supplied buffer
+  * @return error code.  1 is success, 0 is failure
+  */
+int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len)
+{
+	MQTTHeader header = {0};
+	MQTTConnectFlags flags = {0};
+	unsigned char* curdata = buf;
+	unsigned char* enddata = &buf[len];
+	int rc = 0;
+	MQTTString Protocol;
+	int version;
+	int mylen = 0;
+
+	FUNC_ENTRY;
+	header.byte = readChar(&curdata);
+	if (header.bits.type != CONNECT)
+		goto exit;
+
+	curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */
+
+	if (!readMQTTLenString(&Protocol, &curdata, enddata) ||
+		enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
+		goto exit;
+
+	version = (int)readChar(&curdata); /* Protocol version */
+	/* If we don't recognize the protocol version, we don't parse the connect packet on the
+	 * basis that we don't know what the format will be.
+	 */
+	if (MQTTPacket_checkVersion(&Protocol, version))
+	{
+		flags.all = readChar(&curdata);
+		data->cleansession = flags.bits.cleansession;
+		data->keepAliveInterval = readInt(&curdata);
+		if (!readMQTTLenString(&data->clientID, &curdata, enddata))
+			goto exit;
+		data->willFlag = flags.bits.will;
+		if (flags.bits.will)
+		{
+			data->will.qos = flags.bits.willQoS;
+			data->will.retained = flags.bits.willRetain;
+			if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) ||
+				  !readMQTTLenString(&data->will.message, &curdata, enddata))
+				goto exit;
+		}
+		if (flags.bits.username)
+		{
+			if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata))
+				goto exit; /* username flag set, but no username supplied - invalid */
+			if (flags.bits.password &&
+				(enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata)))
+				goto exit; /* password flag set, but no password supplied - invalid */
+		}
+		else if (flags.bits.password)
+			goto exit; /* password flag set without username - invalid */
+		rc = 1;
+	}
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+/**
+  * Serializes the connack packet into the supplied buffer.
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer
+  * @param connack_rc the integer connack return code to be used 
+  * @param sessionPresent the MQTT 3.1.1 sessionPresent flag
+  * @return serialized length, or error if 0
+  */
+int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent)
+{
+	MQTTHeader header = {0};
+	int rc = 0;
+	unsigned char *ptr = buf;
+	MQTTConnackFlags flags = {0};
+
+	FUNC_ENTRY;
+	if (buflen < 2)
+	{
+		rc = MQTTPACKET_BUFFER_TOO_SHORT;
+		goto exit;
+	}
+	header.byte = 0;
+	header.bits.type = CONNACK;
+	writeChar(&ptr, header.byte); /* write header */
+
+	ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
+
+	flags.all = 0;
+	flags.bits.sessionpresent = sessionPresent;
+	writeChar(&ptr, flags.all); 
+	writeChar(&ptr, connack_rc);
+
+	rc = ptr - buf;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+

+ 107 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTDeserializePublish.c

@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+#include <MQTTPacket.h>
+#include <string.h>
+#include <StackTrace.h>
+
+#define min(a, b) ((a < b) ? 1 : 0)
+
+/**
+  * Deserializes the supplied (wire) buffer into publish data
+  * @param dup returned integer - the MQTT dup flag
+  * @param qos returned integer - the MQTT QoS value
+  * @param retained returned integer - the MQTT retained flag
+  * @param packetid returned integer - the MQTT packet identifier
+  * @param topicName returned MQTTString - the MQTT topic in the publish
+  * @param payload returned byte buffer - the MQTT publish payload
+  * @param payloadlen returned integer - the length of the MQTT payload
+  * @param buf the raw buffer data, of the correct length determined by the remaining length field
+  * @param buflen the length in bytes of the data in the supplied buffer
+  * @return error code.  1 is success
+  */
+int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
+		unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen)
+{
+	MQTTHeader header = {0};
+	unsigned char* curdata = buf;
+	unsigned char* enddata = NULL;
+	int rc = 0;
+	int mylen = 0;
+
+	FUNC_ENTRY;
+	header.byte = readChar(&curdata);
+	if (header.bits.type != PUBLISH)
+		goto exit;
+	*dup = header.bits.dup;
+	*qos = header.bits.qos;
+	*retained = header.bits.retain;
+
+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
+	enddata = curdata + mylen;
+
+	if (!readMQTTLenString(topicName, &curdata, enddata) ||
+		enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
+		goto exit;
+
+	if (*qos > 0)
+		*packetid = readInt(&curdata);
+
+	*payloadlen = enddata - curdata;
+	*payload = curdata;
+	rc = 1;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+
+/**
+  * Deserializes the supplied (wire) buffer into an ack
+  * @param packettype returned integer - the MQTT packet type
+  * @param dup returned integer - the MQTT dup flag
+  * @param packetid returned integer - the MQTT packet identifier
+  * @param buf the raw buffer data, of the correct length determined by the remaining length field
+  * @param buflen the length in bytes of the data in the supplied buffer
+  * @return error code.  1 is success, 0 is failure
+  */
+int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen)
+{
+	MQTTHeader header = {0};
+	unsigned char* curdata = buf;
+	unsigned char* enddata = NULL;
+	int rc = 0;
+	int mylen;
+
+	FUNC_ENTRY;
+	header.byte = readChar(&curdata);
+	*dup = header.bits.dup;
+	*packettype = header.bits.type;
+
+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
+	enddata = curdata + mylen;
+
+	if (enddata - curdata < 2)
+		goto exit;
+	*packetid = readInt(&curdata);
+
+	rc = 1;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+

+ 261 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTFormat.c

@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+#include <MQTTPacket.h>
+#include <string.h>
+#include <StackTrace.h>
+
+
+const char* MQTTPacket_names[] =
+{
+	"RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL",
+	"PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK",
+	"PINGREQ", "PINGRESP", "DISCONNECT"
+};
+
+
+const char* MQTTPacket_getName(unsigned short packetid)
+{
+	return MQTTPacket_names[packetid];
+}
+
+
+int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data)
+{
+	int strindex = 0;
+
+	strindex = snprintf(strbuf, strbuflen,
+			"CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d",
+			(int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data,
+			(int)data->cleansession, data->keepAliveInterval);
+	if (data->willFlag)
+		strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
+				", will QoS %d, will retain %d, will topic %.*s, will message %.*s",
+				data->will.qos, data->will.retained,
+				data->will.topicName.lenstring.len, data->will.topicName.lenstring.data,
+				data->will.message.lenstring.len, data->will.message.lenstring.data);
+	if (data->username.lenstring.data && data->username.lenstring.len > 0)
+		strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
+				", user name %.*s", data->username.lenstring.len, data->username.lenstring.data);
+	if (data->password.lenstring.data && data->password.lenstring.len > 0)
+		strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
+				", password %.*s", data->password.lenstring.len, data->password.lenstring.data);
+	return strindex;
+}
+
+
+int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent)
+{
+	int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc);
+	return strindex;
+}
+
+
+int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
+		unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen)
+{
+	int strindex = snprintf(strbuf, strbuflen,
+				"PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s",
+				dup, qos, retained, packetid,
+				(topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data,
+				payloadlen, (payloadlen < 20) ? payloadlen : 20, payload);
+	return strindex;
+}
+
+
+int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
+{
+	int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid);
+	if (dup)
+		strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup);
+	return strindex;
+}
+
+
+int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
+		MQTTString topicFilters[], int requestedQoSs[])
+{
+	return snprintf(strbuf, strbuflen,
+		"SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d",
+		dup, packetid, count,
+		topicFilters[0].lenstring.len, topicFilters[0].lenstring.data,
+		requestedQoSs[0]);
+}
+
+
+int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs)
+{
+	return snprintf(strbuf, strbuflen,
+		"SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]);
+}
+
+
+int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
+		int count, MQTTString topicFilters[])
+{
+	return snprintf(strbuf, strbuflen,
+					"UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s",
+					dup, packetid, count,
+					topicFilters[0].lenstring.len, topicFilters[0].lenstring.data);
+}
+
+
+#if defined(MQTT_CLIENT)
+char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
+{
+	int index = 0;
+	int rem_length = 0;
+	MQTTHeader header = {0};
+	int strindex = 0;
+
+	header.byte = buf[index++];
+	index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
+
+	switch (header.bits.type)
+	{
+
+	case CONNACK:
+	{
+		unsigned char sessionPresent, connack_rc;
+		if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1)
+			strindex = MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent);
+	}
+	break;
+	case PUBLISH:
+	{
+		unsigned char dup, retained, *payload;
+		unsigned short packetid;
+		int qos, payloadlen;
+		MQTTString topicName = MQTTString_initializer;
+		if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
+				&payload, &payloadlen, buf, buflen) == 1)
+			strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
+					topicName, payload, payloadlen);
+	}
+	break;
+	case PUBACK:
+	case PUBREC:
+	case PUBREL:
+	case PUBCOMP:
+	{
+		unsigned char packettype, dup;
+		unsigned short packetid;
+		if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
+			strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
+	}
+	break;
+	case SUBACK:
+	{
+		unsigned short packetid;
+		int maxcount = 1, count = 0;
+		int grantedQoSs[1];
+		if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1)
+			strindex = MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs);
+	}
+	break;
+	case UNSUBACK:
+	{
+		unsigned short packetid;
+		if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1)
+			strindex = MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid);
+	}
+	break;
+	case PINGREQ:
+	case PINGRESP:
+	case DISCONNECT:
+		strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
+		break;
+	}
+	return strbuf;
+}
+#endif
+
+#if defined(MQTT_SERVER)
+char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
+{
+	int index = 0;
+	int rem_length = 0;
+	MQTTHeader header = {0};
+	int strindex = 0;
+
+	header.byte = buf[index++];
+	index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
+
+	switch (header.bits.type)
+	{
+	case CONNECT:
+	{
+		MQTTPacket_connectData data;
+		int rc;
+		if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1)
+			strindex = MQTTStringFormat_connect(strbuf, strbuflen, &data);
+	}
+	break;
+	case PUBLISH:
+	{
+		unsigned char dup, retained, *payload;
+		unsigned short packetid;
+		int qos, payloadlen;
+		MQTTString topicName = MQTTString_initializer;
+		if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
+				&payload, &payloadlen, buf, buflen) == 1)
+			strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
+					topicName, payload, payloadlen);
+	}
+	break;
+	case PUBACK:
+	case PUBREC:
+	case PUBREL:
+	case PUBCOMP:
+	{
+		unsigned char packettype, dup;
+		unsigned short packetid;
+		if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
+			strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
+	}
+	break;
+	case SUBSCRIBE:
+	{
+		unsigned char dup;
+		unsigned short packetid;
+		int maxcount = 1, count = 0;
+		MQTTString topicFilters[1];
+		int requestedQoSs[1];
+		if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count,
+				topicFilters, requestedQoSs, buf, buflen) == 1)
+			strindex = MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);;
+	}
+	break;
+	case UNSUBSCRIBE:
+	{
+		unsigned char dup;
+		unsigned short packetid;
+		int maxcount = 1, count = 0;
+		MQTTString topicFilters[1];
+		if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1)
+			strindex =  MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters);
+	}
+	break;
+	case PINGREQ:
+	case PINGRESP:
+	case DISCONNECT:
+		strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
+		break;
+	}
+	strbuf[strbuflen] = '\0';
+	return strbuf;
+}
+#endif

+ 37 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTFormat.h

@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+#if !defined(MQTTFORMAT_H)
+#define MQTTFORMAT_H
+
+#include <MQTTPacket.h>
+#include <StackTrace.h>
+
+const char* MQTTPacket_getName(unsigned short packetid);
+int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data);
+int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent);
+int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
+		unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen);
+int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid);
+int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
+		MQTTString topicFilters[], int requestedQoSs[]);
+int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs);
+int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
+		int count, MQTTString topicFilters[]);
+char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
+char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
+
+#endif

+ 411 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTPacket.c

@@ -0,0 +1,411 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Sergio R. Caprile - non-blocking packet read functions for stream transport
+ *******************************************************************************/
+
+#include <MQTTPacket.h>
+#include <string.h>
+#include <StackTrace.h>
+
+/**
+ * Encodes the message length according to the MQTT algorithm
+ * @param buf the buffer into which the encoded data is written
+ * @param length the length to be encoded
+ * @return the number of bytes written to buffer
+ */
+int MQTTPacket_encode(unsigned char* buf, int length)
+{
+	int rc = 0;
+
+	FUNC_ENTRY;
+	do
+	{
+		char d = length % 128;
+		length /= 128;
+		/* if there are more digits to encode, set the top bit of this digit */
+		if (length > 0)
+			d |= 0x80;
+		buf[rc++] = d;
+	} while (length > 0);
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+/**
+ * Decodes the message length according to the MQTT algorithm
+ * @param getcharfn pointer to function to read the next character from the data source
+ * @param value the decoded length returned
+ * @return the number of bytes read from the socket
+ */
+int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value)
+{
+	unsigned char c;
+	int multiplier = 1;
+	int len = 0;
+#define MAX_NO_OF_REMAINING_LENGTH_BYTES 4
+
+	FUNC_ENTRY;
+	*value = 0;
+	do
+	{
+		int rc = MQTTPACKET_READ_ERROR;
+
+		if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
+		{
+			rc = MQTTPACKET_READ_ERROR;	/* bad data */
+			goto exit;
+		}
+		rc = (*getcharfn)(&c, 1);
+		if (rc != 1)
+			goto exit;
+		*value += (c & 127) * multiplier;
+		multiplier *= 128;
+	} while ((c & 128) != 0);
+exit:
+	FUNC_EXIT_RC(len);
+	return len;
+}
+
+
+int MQTTPacket_len(int rem_len)
+{
+	rem_len += 1; /* header byte */
+
+	/* now remaining_length field */
+	if (rem_len < 128)
+		rem_len += 1;
+	else if (rem_len < 16384)
+		rem_len += 2;
+	else if (rem_len < 2097151)
+		rem_len += 3;
+	else
+		rem_len += 4;
+	return rem_len;
+}
+
+
+static unsigned char* bufptr;
+
+int bufchar(unsigned char* c, int count)
+{
+	int i;
+
+	for (i = 0; i < count; ++i)
+		*c = *bufptr++;
+	return count;
+}
+
+
+int MQTTPacket_decodeBuf(unsigned char* buf, int* value)
+{
+	bufptr = buf;
+	return MQTTPacket_decode(bufchar, value);
+}
+
+
+/**
+ * Calculates an integer from two bytes read from the input buffer
+ * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
+ * @return the integer value calculated
+ */
+int readInt(unsigned char** pptr)
+{
+	unsigned char* ptr = *pptr;
+	int len = 256*(*ptr) + (*(ptr+1));
+	*pptr += 2;
+	return len;
+}
+
+
+/**
+ * Reads one character from the input buffer.
+ * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
+ * @return the character read
+ */
+char readChar(unsigned char** pptr)
+{
+	char c = **pptr;
+	(*pptr)++;
+	return c;
+}
+
+
+/**
+ * Writes one character to an output buffer.
+ * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
+ * @param c the character to write
+ */
+void writeChar(unsigned char** pptr, char c)
+{
+	**pptr = c;
+	(*pptr)++;
+}
+
+
+/**
+ * Writes an integer as 2 bytes to an output buffer.
+ * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
+ * @param anInt the integer to write
+ */
+void writeInt(unsigned char** pptr, int anInt)
+{
+	**pptr = (unsigned char)(anInt / 256);
+	(*pptr)++;
+	**pptr = (unsigned char)(anInt % 256);
+	(*pptr)++;
+}
+
+
+/**
+ * Writes a "UTF" string to an output buffer.  Converts C string to length-delimited.
+ * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
+ * @param string the C string to write
+ */
+void writeCString(unsigned char** pptr, const char* string)
+{
+	int len = strlen(string);
+	writeInt(pptr, len);
+	memcpy(*pptr, string, len);
+	*pptr += len;
+}
+
+
+int getLenStringLen(char* ptr)
+{
+	int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1));
+	return len;
+}
+
+
+void writeMQTTString(unsigned char** pptr, MQTTString mqttstring)
+{
+	if (mqttstring.lenstring.len > 0)
+	{
+		writeInt(pptr, mqttstring.lenstring.len);
+		memcpy(*pptr, mqttstring.lenstring.data, mqttstring.lenstring.len);
+		*pptr += mqttstring.lenstring.len;
+	}
+	else if (mqttstring.cstring)
+		writeCString(pptr, mqttstring.cstring);
+	else
+		writeInt(pptr, 0);
+}
+
+
+/**
+ * @param mqttstring the MQTTString structure into which the data is to be read
+ * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
+ * @param enddata pointer to the end of the data: do not read beyond
+ * @return 1 if successful, 0 if not
+ */
+int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata)
+{
+	int rc = 0;
+
+	FUNC_ENTRY;
+	/* the first two bytes are the length of the string */
+	if (enddata - (*pptr) > 1) /* enough length to read the integer? */
+	{
+		mqttstring->lenstring.len = readInt(pptr); /* increments pptr to point past length */
+		if (&(*pptr)[mqttstring->lenstring.len] <= enddata)
+		{
+			mqttstring->lenstring.data = (char*)*pptr;
+			*pptr += mqttstring->lenstring.len;
+			rc = 1;
+		}
+	}
+	mqttstring->cstring = NULL;
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+/**
+ * Return the length of the MQTTstring - C string if there is one, otherwise the length delimited string
+ * @param mqttstring the string to return the length of
+ * @return the length of the string
+ */
+int MQTTstrlen(MQTTString mqttstring)
+{
+	int rc = 0;
+
+	if (mqttstring.cstring)
+		rc = strlen(mqttstring.cstring);
+	else
+		rc = mqttstring.lenstring.len;
+	return rc;
+}
+
+
+/**
+ * Compares an MQTTString to a C string
+ * @param a the MQTTString to compare
+ * @param bptr the C string to compare
+ * @return boolean - equal or not
+ */
+int MQTTPacket_equals(MQTTString* a, char* bptr)
+{
+	int alen = 0,
+		blen = 0;
+	char *aptr;
+	
+	if (a->cstring)
+	{
+		aptr = a->cstring;
+		alen = strlen(a->cstring);
+	}
+	else
+	{
+		aptr = a->lenstring.data;
+		alen = a->lenstring.len;
+	}
+	blen = strlen(bptr);
+	
+	return (alen == blen) && (strncmp(aptr, bptr, alen) == 0);
+}
+
+
+/**
+ * Helper function to read packet data from some source into a buffer
+ * @param buf the buffer into which the packet will be serialized
+ * @param buflen the length in bytes of the supplied buffer
+ * @param getfn pointer to a function which will read any number of bytes from the needed source
+ * @return integer MQTT packet type, or -1 on error
+ * @note  the whole message must fit into the caller's buffer
+ */
+int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int))
+{
+	int rc = -1;
+	MQTTHeader header = {0};
+	int len = 0;
+	int rem_len = 0;
+
+	/* 1. read the header byte.  This has the packet type in it */
+	if ((*getfn)(buf, 1) != 1)
+		goto exit;
+
+	len = 1;
+	/* 2. read the remaining length.  This is variable in itself */
+	MQTTPacket_decode(getfn, &rem_len);
+	len += MQTTPacket_encode(buf + 1, rem_len); /* put the original remaining length back into the buffer */
+
+	/* 3. read the rest of the buffer using a callback to supply the rest of the data */
+	if((rem_len + len) > buflen)
+		goto exit;
+	if (rem_len && ((*getfn)(buf + len, rem_len) != rem_len))
+		goto exit;
+
+	header.byte = buf[0];
+	rc = header.bits.type;
+exit:
+	return rc;
+}
+
+/**
+ * Decodes the message length according to the MQTT algorithm, non-blocking
+ * @param trp pointer to a transport structure holding what is needed to solve getting data from it
+ * @param value the decoded length returned
+ * @return integer the number of bytes read from the socket, 0 for call again, or -1 on error
+ */
+static int MQTTPacket_decodenb(MQTTTransport *trp)
+{
+	unsigned char c;
+	int rc = MQTTPACKET_READ_ERROR;
+
+	FUNC_ENTRY;
+	if(trp->len == 0){		/* initialize on first call */
+		trp->multiplier = 1;
+		trp->rem_len = 0;
+	}
+	do {
+		int frc;
+		if (trp->len >= MAX_NO_OF_REMAINING_LENGTH_BYTES)
+			goto exit;
+		if ((frc=(*trp->getfn)(trp->sck, &c, 1)) == -1)
+			goto exit;
+		if (frc == 0){
+			rc = 0;
+			goto exit;
+		}
+		++(trp->len);
+		trp->rem_len += (c & 127) * trp->multiplier;
+		trp->multiplier *= 128;
+	} while ((c & 128) != 0);
+	rc = trp->len;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+/**
+ * Helper function to read packet data from some source into a buffer, non-blocking
+ * @param buf the buffer into which the packet will be serialized
+ * @param buflen the length in bytes of the supplied buffer
+ * @param trp pointer to a transport structure holding what is needed to solve getting data from it
+ * @return integer MQTT packet type, 0 for call again, or -1 on error
+ * @note  the whole message must fit into the caller's buffer
+ */
+int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp)
+{
+	int rc = -1, frc;
+	MQTTHeader header = {0};
+
+	switch(trp->state){
+	default:
+		trp->state = 0;
+		/*FALLTHROUGH*/
+	case 0:
+		/* read the header byte.  This has the packet type in it */
+		if ((frc=(*trp->getfn)(trp->sck, buf, 1)) == -1)
+			goto exit;
+		if (frc == 0)
+			return 0;
+		trp->len = 0;
+		++trp->state;
+		/*FALLTHROUGH*/
+		/* read the remaining length.  This is variable in itself */
+	case 1:
+		if((frc=MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR)
+			goto exit;
+		if(frc == 0)
+			return 0;
+		trp->len = 1 + MQTTPacket_encode(buf + 1, trp->rem_len); /* put the original remaining length back into the buffer */
+		if((trp->rem_len + trp->len) > buflen)
+			goto exit;
+		++trp->state;
+		/*FALLTHROUGH*/
+	case 2:
+		if(trp->rem_len){
+			/* read the rest of the buffer using a callback to supply the rest of the data */
+			if ((frc=(*trp->getfn)(trp->sck, buf + trp->len, trp->rem_len)) == -1)
+				goto exit;
+			if (frc == 0)
+				return 0;
+			trp->rem_len -= frc;
+			trp->len += frc;
+			if(trp->rem_len)
+				return 0;
+		}
+		header.byte = buf[0];
+		rc = header.bits.type;
+		break;
+	}
+
+exit:
+	trp->state = 0;
+	return rc;
+}
+

+ 133 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTPacket.h

@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Xiang Rong - 442039 Add makefile to Embedded C client
+ *******************************************************************************/
+
+#ifndef MQTTPACKET_H_
+#define MQTTPACKET_H_
+
+#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
+extern "C" {
+#endif
+
+#if defined(WIN32_DLL) || defined(WIN64_DLL)
+  #define DLLImport __declspec(dllimport)
+  #define DLLExport __declspec(dllexport)
+#elif defined(LINUX_SO)
+  #define DLLImport extern
+  #define DLLExport  __attribute__ ((visibility ("default")))
+#else
+  #define DLLImport
+  #define DLLExport  
+#endif
+
+enum errors
+{
+	MQTTPACKET_BUFFER_TOO_SHORT = -2,
+	MQTTPACKET_READ_ERROR = -1,
+	MQTTPACKET_READ_COMPLETE
+};
+
+enum msgTypes
+{
+	CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL,
+	PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK,
+	PINGREQ, PINGRESP, DISCONNECT
+};
+
+/**
+ * Bitfields for the MQTT header byte.
+ */
+typedef union
+{
+	unsigned char byte;	                /**< the whole byte */
+#if defined(REVERSED)
+	struct
+	{
+		unsigned int type : 4;			/**< message type nibble */
+		unsigned int dup : 1;				/**< DUP flag bit */
+		unsigned int qos : 2;				/**< QoS value, 0, 1 or 2 */
+		unsigned int retain : 1;		/**< retained flag bit */
+	} bits;
+#else
+	struct
+	{
+		unsigned int retain : 1;		/**< retained flag bit */
+		unsigned int qos : 2;				/**< QoS value, 0, 1 or 2 */
+		unsigned int dup : 1;				/**< DUP flag bit */
+		unsigned int type : 4;			/**< message type nibble */
+	} bits;
+#endif
+} MQTTHeader;
+
+typedef struct
+{
+	int len;
+	char* data;
+} MQTTLenString;
+
+typedef struct
+{
+	char* cstring;
+	MQTTLenString lenstring;
+} MQTTString;
+
+#define MQTTString_initializer {NULL, {0, NULL}}
+
+int MQTTstrlen(MQTTString mqttstring);
+
+#include <MQTTConnect.h>
+#include <MQTTPublish.h>
+#include <MQTTSubscribe.h>
+#include <MQTTUnsubscribe.h>
+#include <MQTTFormat.h>
+
+DLLExport int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char type, unsigned char dup, unsigned short packetid);
+DLLExport int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen);
+
+int MQTTPacket_len(int rem_len);
+DLLExport int MQTTPacket_equals(MQTTString* a, char* b);
+
+DLLExport int MQTTPacket_encode(unsigned char* buf, int length);
+int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value);
+int MQTTPacket_decodeBuf(unsigned char* buf, int* value);
+
+int readInt(unsigned char** pptr);
+char readChar(unsigned char** pptr);
+void writeChar(unsigned char** pptr, char c);
+void writeInt(unsigned char** pptr, int anInt);
+int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata);
+void writeCString(unsigned char** pptr, const char* string);
+void writeMQTTString(unsigned char** pptr, MQTTString mqttstring);
+
+DLLExport int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int));
+
+typedef struct {
+	int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */
+	void *sck;	/* pointer to whatever the system may use to identify the transport */
+	int multiplier;
+	int rem_len;
+	int len;
+	char state;
+}MQTTTransport;
+
+int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp);
+
+#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
+}
+#endif
+
+
+#endif /* MQTTPACKET_H_ */

+ 38 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTPublish.h

@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Xiang Rong - 442039 Add makefile to Embedded C client
+ *******************************************************************************/
+
+#ifndef MQTTPUBLISH_H_
+#define MQTTPUBLISH_H_
+
+#if !defined(DLLImport)
+  #define DLLImport 
+#endif
+#if !defined(DLLExport)
+  #define DLLExport
+#endif
+
+DLLExport int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
+		MQTTString topicName, unsigned char* payload, int payloadlen);
+
+DLLExport int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
+		unsigned char** payload, int* payloadlen, unsigned char* buf, int len);
+
+DLLExport int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid);
+DLLExport int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid);
+DLLExport int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid);
+
+#endif /* MQTTPUBLISH_H_ */

+ 168 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSerializePublish.c

@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=453144
+ *******************************************************************************/
+
+#include <MQTTPacket.h>
+#include <string.h>
+#include <StackTrace.h>
+
+
+/**
+  * Determines the length of the MQTT publish packet that would be produced using the supplied parameters
+  * @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0)
+  * @param topicName the topic name to be used in the publish  
+  * @param payloadlen the length of the payload to be sent
+  * @return the length of buffer needed to contain the serialized version of the packet
+  */
+int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen)
+{
+	int len = 0;
+
+	len += 2 + MQTTstrlen(topicName) + payloadlen;
+	if (qos > 0)
+		len += 2; /* packetid */
+	return len;
+}
+
+
+/**
+  * Serializes the supplied publish data into the supplied buffer, ready for sending
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer
+  * @param dup integer - the MQTT dup flag
+  * @param qos integer - the MQTT QoS value
+  * @param retained integer - the MQTT retained flag
+  * @param packetid integer - the MQTT packet identifier
+  * @param topicName MQTTString - the MQTT topic in the publish
+  * @param payload byte buffer - the MQTT publish payload
+  * @param payloadlen integer - the length of the MQTT payload
+  * @return the length of the serialized data.  <= 0 indicates error
+  */
+int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
+		MQTTString topicName, unsigned char* payload, int payloadlen)
+{
+	unsigned char *ptr = buf;
+	MQTTHeader header = {0};
+	int rem_len = 0;
+	int rc = 0;
+
+	FUNC_ENTRY;
+	if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen)
+	{
+		rc = MQTTPACKET_BUFFER_TOO_SHORT;
+		goto exit;
+	}
+
+	header.bits.type = PUBLISH;
+	header.bits.dup = dup;
+	header.bits.qos = qos;
+	header.bits.retain = retained;
+	writeChar(&ptr, header.byte); /* write header */
+
+	ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
+
+	writeMQTTString(&ptr, topicName);
+
+	if (qos > 0)
+		writeInt(&ptr, packetid);
+
+	memcpy(ptr, payload, payloadlen);
+	ptr += payloadlen;
+
+	rc = ptr - buf;
+
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+
+/**
+  * Serializes the ack packet into the supplied buffer.
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer
+  * @param type the MQTT packet type
+  * @param dup the MQTT dup flag
+  * @param packetid the MQTT packet identifier
+  * @return serialized length, or error if 0
+  */
+int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
+{
+	MQTTHeader header = {0};
+	int rc = 0;
+	unsigned char *ptr = buf;
+
+	FUNC_ENTRY;
+	if (buflen < 4)
+	{
+		rc = MQTTPACKET_BUFFER_TOO_SHORT;
+		goto exit;
+	}
+	header.bits.type = packettype;
+	header.bits.dup = dup;
+	header.bits.qos = (packettype == PUBREL) ? 1 : 0;
+	writeChar(&ptr, header.byte); /* write header */
+
+	ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
+	writeInt(&ptr, packetid);
+	rc = ptr - buf;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+/**
+  * Serializes a puback packet into the supplied buffer.
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer
+  * @param packetid integer - the MQTT packet identifier
+  * @return serialized length, or error if 0
+  */
+int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid)
+{
+	return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid);
+}
+
+
+/**
+  * Serializes a pubrel packet into the supplied buffer.
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer
+  * @param dup integer - the MQTT dup flag
+  * @param packetid integer - the MQTT packet identifier
+  * @return serialized length, or error if 0
+  */
+int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid)
+{
+	return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid);
+}
+
+
+/**
+  * Serializes a pubrel packet into the supplied buffer.
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer
+  * @param packetid integer - the MQTT packet identifier
+  * @return serialized length, or error if 0
+  */
+int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid)
+{
+	return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid);
+}
+
+

+ 39 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSubscribe.h

@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Xiang Rong - 442039 Add makefile to Embedded C client
+ *******************************************************************************/
+
+#ifndef MQTTSUBSCRIBE_H_
+#define MQTTSUBSCRIBE_H_
+
+#if !defined(DLLImport)
+  #define DLLImport 
+#endif
+#if !defined(DLLExport)
+  #define DLLExport
+#endif
+
+DLLExport int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
+		int count, MQTTString topicFilters[], int requestedQoSs[]);
+
+DLLExport int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid,
+		int maxcount, int* count, MQTTString topicFilters[], int requestedQoSs[], unsigned char* buf, int len);
+
+DLLExport int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs);
+
+DLLExport int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int len);
+
+
+#endif /* MQTTSUBSCRIBE_H_ */

+ 136 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSubscribeClient.c

@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+#include <MQTTPacket.h>
+#include <string.h>
+#include <StackTrace.h>
+
+/**
+  * Determines the length of the MQTT subscribe packet that would be produced using the supplied parameters
+  * @param count the number of topic filter strings in topicFilters
+  * @param topicFilters the array of topic filter strings to be used in the publish
+  * @return the length of buffer needed to contain the serialized version of the packet
+  */
+int MQTTSerialize_subscribeLength(int count, MQTTString topicFilters[])
+{
+	int i;
+	int len = 2; /* packetid */
+
+	for (i = 0; i < count; ++i)
+		len += 2 + MQTTstrlen(topicFilters[i]) + 1; /* length + topic + req_qos */
+	return len;
+}
+
+
+/**
+  * Serializes the supplied subscribe data into the supplied buffer, ready for sending
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied bufferr
+  * @param dup integer - the MQTT dup flag
+  * @param packetid integer - the MQTT packet identifier
+  * @param count - number of members in the topicFilters and reqQos arrays
+  * @param topicFilters - array of topic filter names
+  * @param requestedQoSs - array of requested QoS
+  * @return the length of the serialized data.  <= 0 indicates error
+  */
+int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, int count,
+		MQTTString topicFilters[], int requestedQoSs[])
+{
+	unsigned char *ptr = buf;
+	MQTTHeader header = {0};
+	int rem_len = 0;
+	int rc = 0;
+	int i = 0;
+
+	FUNC_ENTRY;
+	if (MQTTPacket_len(rem_len = MQTTSerialize_subscribeLength(count, topicFilters)) > buflen)
+	{
+		rc = MQTTPACKET_BUFFER_TOO_SHORT;
+		goto exit;
+	}
+
+	header.byte = 0;
+	header.bits.type = SUBSCRIBE;
+	header.bits.dup = dup;
+	header.bits.qos = 1;
+	writeChar(&ptr, header.byte); /* write header */
+
+	ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
+
+	writeInt(&ptr, packetid);
+
+	for (i = 0; i < count; ++i)
+	{
+		writeMQTTString(&ptr, topicFilters[i]);
+		writeChar(&ptr, requestedQoSs[i]);
+	}
+
+	rc = ptr - buf;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+
+/**
+  * Deserializes the supplied (wire) buffer into suback data
+  * @param packetid returned integer - the MQTT packet identifier
+  * @param maxcount - the maximum number of members allowed in the grantedQoSs array
+  * @param count returned integer - number of members in the grantedQoSs array
+  * @param grantedQoSs returned array of integers - the granted qualities of service
+  * @param buf the raw buffer data, of the correct length determined by the remaining length field
+  * @param buflen the length in bytes of the data in the supplied buffer
+  * @return error code.  1 is success, 0 is failure
+  */
+int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int buflen)
+{
+	MQTTHeader header = {0};
+	unsigned char* curdata = buf;
+	unsigned char* enddata = NULL;
+	int rc = 0;
+	int mylen;
+
+	FUNC_ENTRY;
+	header.byte = readChar(&curdata);
+	if (header.bits.type != SUBACK)
+		goto exit;
+
+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
+	enddata = curdata + mylen;
+	if (enddata - curdata < 2)
+		goto exit;
+
+	*packetid = readInt(&curdata);
+
+	*count = 0;
+	while (curdata < enddata)
+	{
+		if (*count > maxcount)
+		{
+			rc = -1;
+			goto exit;
+		}
+		grantedQoSs[(*count)++] = readChar(&curdata);
+	}
+
+	rc = 1;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+

+ 111 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSubscribeServer.c

@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+#include <MQTTPacket.h>
+#include <string.h>
+#include <StackTrace.h>
+
+
+/**
+  * Deserializes the supplied (wire) buffer into subscribe data
+  * @param dup integer returned - the MQTT dup flag
+  * @param packetid integer returned - the MQTT packet identifier
+  * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
+  * @param count - number of members in the topicFilters and requestedQoSs arrays
+  * @param topicFilters - array of topic filter names
+  * @param requestedQoSs - array of requested QoS
+  * @param buf the raw buffer data, of the correct length determined by the remaining length field
+  * @param buflen the length in bytes of the data in the supplied buffer
+  * @return the length of the serialized data.  <= 0 indicates error
+  */
+int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
+	int requestedQoSs[], unsigned char* buf, int buflen)
+{
+	MQTTHeader header = {0};
+	unsigned char* curdata = buf;
+	unsigned char* enddata = NULL;
+	int rc = -1;
+	int mylen = 0;
+
+	FUNC_ENTRY;
+	header.byte = readChar(&curdata);
+	if (header.bits.type != SUBSCRIBE)
+		goto exit;
+	*dup = header.bits.dup;
+
+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
+	enddata = curdata + mylen;
+
+	*packetid = readInt(&curdata);
+
+	*count = 0;
+	while (curdata < enddata)
+	{
+		if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
+			goto exit;
+		if (curdata >= enddata) /* do we have enough data to read the req_qos version byte? */
+			goto exit;
+		requestedQoSs[*count] = readChar(&curdata);
+		(*count)++;
+	}
+
+	rc = 1;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+/**
+  * Serializes the supplied suback data into the supplied buffer, ready for sending
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer
+  * @param packetid integer - the MQTT packet identifier
+  * @param count - number of members in the grantedQoSs array
+  * @param grantedQoSs - array of granted QoS
+  * @return the length of the serialized data.  <= 0 indicates error
+  */
+int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs)
+{
+	MQTTHeader header = {0};
+	int rc = -1;
+	unsigned char *ptr = buf;
+	int i;
+
+	FUNC_ENTRY;
+	if (buflen < 2 + count)
+	{
+		rc = MQTTPACKET_BUFFER_TOO_SHORT;
+		goto exit;
+	}
+	header.byte = 0;
+	header.bits.type = SUBACK;
+	writeChar(&ptr, header.byte); /* write header */
+
+	ptr += MQTTPacket_encode(ptr, 2 + count); /* write remaining length */
+
+	writeInt(&ptr, packetid);
+
+	for (i = 0; i < count; ++i)
+		writeChar(&ptr, grantedQoSs[i]);
+
+	rc = ptr - buf;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+

+ 38 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTUnsubscribe.h

@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Xiang Rong - 442039 Add makefile to Embedded C client
+ *******************************************************************************/
+
+#ifndef MQTTUNSUBSCRIBE_H_
+#define MQTTUNSUBSCRIBE_H_
+
+#if !defined(DLLImport)
+  #define DLLImport 
+#endif
+#if !defined(DLLExport)
+  #define DLLExport
+#endif
+
+DLLExport int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
+		int count, MQTTString topicFilters[]);
+
+DLLExport int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int max_count, int* count, MQTTString topicFilters[],
+		unsigned char* buf, int len);
+
+DLLExport int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid);
+
+DLLExport int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int len);
+
+#endif /* MQTTUNSUBSCRIBE_H_ */

+ 105 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTUnsubscribeClient.c

@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+#include <MQTTPacket.h>
+#include <string.h>
+#include <StackTrace.h>
+
+/**
+  * Determines the length of the MQTT unsubscribe packet that would be produced using the supplied parameters
+  * @param count the number of topic filter strings in topicFilters
+  * @param topicFilters the array of topic filter strings to be used in the publish
+  * @return the length of buffer needed to contain the serialized version of the packet
+  */
+int MQTTSerialize_unsubscribeLength(int count, MQTTString topicFilters[])
+{
+	int i;
+	int len = 2; /* packetid */
+
+	for (i = 0; i < count; ++i)
+		len += 2 + MQTTstrlen(topicFilters[i]); /* length + topic*/
+	return len;
+}
+
+
+/**
+  * Serializes the supplied unsubscribe data into the supplied buffer, ready for sending
+  * @param buf the raw buffer data, of the correct length determined by the remaining length field
+  * @param buflen the length in bytes of the data in the supplied buffer
+  * @param dup integer - the MQTT dup flag
+  * @param packetid integer - the MQTT packet identifier
+  * @param count - number of members in the topicFilters array
+  * @param topicFilters - array of topic filter names
+  * @return the length of the serialized data.  <= 0 indicates error
+  */
+int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
+		int count, MQTTString topicFilters[])
+{
+	unsigned char *ptr = buf;
+	MQTTHeader header = {0};
+	int rem_len = 0;
+	int rc = -1;
+	int i = 0;
+
+	FUNC_ENTRY;
+	if (MQTTPacket_len(rem_len = MQTTSerialize_unsubscribeLength(count, topicFilters)) > buflen)
+	{
+		rc = MQTTPACKET_BUFFER_TOO_SHORT;
+		goto exit;
+	}
+
+	header.byte = 0;
+	header.bits.type = UNSUBSCRIBE;
+	header.bits.dup = dup;
+	header.bits.qos = 1;
+	writeChar(&ptr, header.byte); /* write header */
+
+	ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
+
+	writeInt(&ptr, packetid);
+
+	for (i = 0; i < count; ++i)
+		writeMQTTString(&ptr, topicFilters[i]);
+
+	rc = ptr - buf;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+/**
+  * Deserializes the supplied (wire) buffer into unsuback data
+  * @param packetid returned integer - the MQTT packet identifier
+  * @param buf the raw buffer data, of the correct length determined by the remaining length field
+  * @param buflen the length in bytes of the data in the supplied buffer
+  * @return error code.  1 is success, 0 is failure
+  */
+int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen)
+{
+	unsigned char type = 0;
+	unsigned char dup = 0;
+	int rc = 0;
+
+	FUNC_ENTRY;
+	rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen);
+	if (type == UNSUBACK)
+		rc = 1;
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+

+ 101 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/MQTTUnsubscribeServer.c

@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+#include <MQTTPacket.h>
+#include <string.h>
+#include <StackTrace.h>
+
+
+/**
+  * Deserializes the supplied (wire) buffer into unsubscribe data
+  * @param dup integer returned - the MQTT dup flag
+  * @param packetid integer returned - the MQTT packet identifier
+  * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
+  * @param count - number of members in the topicFilters and requestedQoSs arrays
+  * @param topicFilters - array of topic filter names
+  * @param buf the raw buffer data, of the correct length determined by the remaining length field
+  * @param buflen the length in bytes of the data in the supplied buffer
+  * @return the length of the serialized data.  <= 0 indicates error
+  */
+int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
+		unsigned char* buf, int len)
+{
+	MQTTHeader header = {0};
+	unsigned char* curdata = buf;
+	unsigned char* enddata = NULL;
+	int rc = 0;
+	int mylen = 0;
+
+	FUNC_ENTRY;
+	header.byte = readChar(&curdata);
+	if (header.bits.type != UNSUBSCRIBE)
+		goto exit;
+	*dup = header.bits.dup;
+
+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
+	enddata = curdata + mylen;
+
+	*packetid = readInt(&curdata);
+
+	*count = 0;
+	while (curdata < enddata)
+	{
+		if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
+			goto exit;
+		(*count)++;
+	}
+
+	rc = 1;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+
+/**
+  * Serializes the supplied unsuback data into the supplied buffer, ready for sending
+  * @param buf the buffer into which the packet will be serialized
+  * @param buflen the length in bytes of the supplied buffer
+  * @param packetid integer - the MQTT packet identifier
+  * @return the length of the serialized data.  <= 0 indicates error
+  */
+int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid)
+{
+	MQTTHeader header = {0};
+	int rc = 0;
+	unsigned char *ptr = buf;
+
+	FUNC_ENTRY;
+	if (buflen < 2)
+	{
+		rc = MQTTPACKET_BUFFER_TOO_SHORT;
+		goto exit;
+	}
+	header.byte = 0;
+	header.bits.type = UNSUBACK;
+	writeChar(&ptr, header.byte); /* write header */
+
+	ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
+
+	writeInt(&ptr, packetid);
+
+	rc = ptr - buf;
+exit:
+	FUNC_EXIT_RC(rc);
+	return rc;
+}
+
+

+ 78 - 0
CM7/Middlewares/Third_Party/MQTT/MQTTPacket/StackTrace.h

@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Ian Craggs - initial API and implementation and/or initial documentation
+ *    Ian Craggs - fix for bug #434081
+ *******************************************************************************/
+
+#ifndef STACKTRACE_H_
+#define STACKTRACE_H_
+
+#include <stdio.h>
+#define NOSTACKTRACE 1
+
+#if defined(NOSTACKTRACE)
+#define FUNC_ENTRY
+#define FUNC_ENTRY_NOLOG
+#define FUNC_ENTRY_MED
+#define FUNC_ENTRY_MAX
+#define FUNC_EXIT
+#define FUNC_EXIT_NOLOG
+#define FUNC_EXIT_MED
+#define FUNC_EXIT_MAX
+#define FUNC_EXIT_RC(x)
+#define FUNC_EXIT_MED_RC(x)
+#define FUNC_EXIT_MAX_RC(x)
+
+#else
+
+#if defined(WIN32)
+#define inline __inline
+#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM)
+#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1)
+#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM)
+#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM)
+#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM)
+#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1)
+#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM)
+#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM)
+#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM)
+#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM)
+#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM)
+#else
+#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM)
+#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1)
+#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM)
+#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM)
+#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM)
+#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1)
+#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM)
+#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM)
+#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM)
+#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM)
+#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM)
+
+void StackTrace_entry(const char* name, int line, int trace);
+void StackTrace_exit(const char* name, int line, void* return_value, int trace);
+
+void StackTrace_printStack(FILE* dest);
+char* StackTrace_get(unsigned long);
+
+#endif
+
+#endif
+
+
+
+
+#endif /* STACKTRACE_H_ */

File diff suppressed because it is too large
+ 54 - 0
CM7/Release/Core/Src/subdir.mk


+ 27 - 0
CM7/Release/Core/Startup/subdir.mk

@@ -0,0 +1,27 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables 
+S_SRCS += \
+../Core/Startup/startup_stm32h745xihx.s 
+
+OBJS += \
+./Core/Startup/startup_stm32h745xihx.o 
+
+S_DEPS += \
+./Core/Startup/startup_stm32h745xihx.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Core/Startup/%.o: ../Core/Startup/%.s Core/Startup/subdir.mk
+	arm-none-eabi-gcc -mcpu=cortex-m7 -c -x assembler-with-cpp -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -o "$@" "$<"
+
+clean: clean-Core-2f-Startup
+
+clean-Core-2f-Startup:
+	-$(RM) ./Core/Startup/startup_stm32h745xihx.d ./Core/Startup/startup_stm32h745xihx.o
+
+.PHONY: clean-Core-2f-Startup
+

File diff suppressed because it is too large
+ 27 - 0
CM7/Release/Drivers/BSP/Components/subdir.mk


File diff suppressed because it is too large
+ 122 - 0
CM7/Release/Drivers/STM32H7xx_HAL_Driver/subdir.mk


File diff suppressed because it is too large
+ 27 - 0
CM7/Release/LWIP/App/subdir.mk


File diff suppressed because it is too large
+ 27 - 0
CM7/Release/LWIP/Target/subdir.mk


File diff suppressed because it is too large
+ 72 - 0
CM7/Release/Middlewares/Third_Party/FreeRTOS/subdir.mk


File diff suppressed because it is too large
+ 429 - 0
CM7/Release/Middlewares/Third_Party/LwIP/subdir.mk


File diff suppressed because it is too large
+ 54 - 0
CM7/Release/Middlewares/Third_Party/MQTT/MQTTPacket/subdir.mk


File diff suppressed because it is too large
+ 30 - 0
CM7/Release/Middlewares/Third_Party/MQTT/subdir.mk


+ 101 - 0
CM7/Release/makefile

@@ -0,0 +1,101 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+-include ../makefile.init
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include Middlewares/Third_Party/MQTT/MQTTPacket/subdir.mk
+-include Middlewares/Third_Party/MQTT/subdir.mk
+-include Middlewares/Third_Party/LwIP/subdir.mk
+-include Middlewares/Third_Party/FreeRTOS/subdir.mk
+-include LWIP/Target/subdir.mk
+-include LWIP/App/subdir.mk
+-include Drivers/STM32H7xx_HAL_Driver/subdir.mk
+-include Drivers/BSP/Components/subdir.mk
+-include Core/Startup/subdir.mk
+-include Core/Src/subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(S_DEPS)),)
+-include $(S_DEPS)
+endif
+ifneq ($(strip $(S_UPPER_DEPS)),)
+-include $(S_UPPER_DEPS)
+endif
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+OPTIONAL_TOOL_DEPS := \
+$(wildcard ../makefile.defs) \
+$(wildcard ../makefile.init) \
+$(wildcard ../makefile.targets) \
+
+
+BUILD_ARTIFACT_NAME := STM32H7-node-red-CM7
+BUILD_ARTIFACT_EXTENSION := elf
+BUILD_ARTIFACT_PREFIX :=
+BUILD_ARTIFACT := $(BUILD_ARTIFACT_PREFIX)$(BUILD_ARTIFACT_NAME)$(if $(BUILD_ARTIFACT_EXTENSION),.$(BUILD_ARTIFACT_EXTENSION),)
+
+# Add inputs and outputs from these tool invocations to the build variables 
+EXECUTABLES += \
+STM32H7-node-red-CM7.elf \
+
+MAP_FILES += \
+STM32H7-node-red-CM7.map \
+
+SIZE_OUTPUT += \
+default.size.stdout \
+
+OBJDUMP_LIST += \
+STM32H7-node-red-CM7.list \
+
+
+# All Target
+all: main-build
+
+# Main-build Target
+main-build: STM32H7-node-red-CM7.elf secondary-outputs
+
+# Tool invocations
+STM32H7-node-red-CM7.elf STM32H7-node-red-CM7.map: $(OBJS) $(USER_OBJS) /home/jakubski/Projects/node-red/STM32H7-node-red/CM7/STM32H745XIHX_FLASH.ld makefile objects.list $(OPTIONAL_TOOL_DEPS)
+	arm-none-eabi-gcc -o "STM32H7-node-red-CM7.elf" @"objects.list" $(USER_OBJS) $(LIBS) -mcpu=cortex-m7 -T"/home/jakubski/Projects/node-red/STM32H7-node-red/CM7/STM32H745XIHX_FLASH.ld" --specs=nosys.specs -Wl,-Map="STM32H7-node-red-CM7.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
+	@echo 'Finished building target: $@'
+	@echo ' '
+
+default.size.stdout: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)
+	arm-none-eabi-size  $(EXECUTABLES)
+	@echo 'Finished building: $@'
+	@echo ' '
+
+STM32H7-node-red-CM7.list: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)
+	arm-none-eabi-objdump -h -S $(EXECUTABLES) > "STM32H7-node-red-CM7.list"
+	@echo 'Finished building: $@'
+	@echo ' '
+
+# Other Targets
+clean:
+	-$(RM) STM32H7-node-red-CM7.elf STM32H7-node-red-CM7.list STM32H7-node-red-CM7.map default.size.stdout
+	-@echo ' '
+
+secondary-outputs: $(SIZE_OUTPUT) $(OBJDUMP_LIST)
+
+fail-specified-linker-script-missing:
+	@echo 'Error: Cannot find the specified linker script. Check the linker settings in the build configuration.'
+	@exit 2
+
+warn-no-linker-script-specified:
+	@echo 'Warning: No linker script specified. Check the linker settings in the build configuration.'
+
+.PHONY: all clean dependents main-build fail-specified-linker-script-missing warn-no-linker-script-specified
+
+-include ../makefile.targets

+ 137 - 0
CM7/Release/objects.list

@@ -0,0 +1,137 @@
+"./Core/Src/echo_server.o"
+"./Core/Src/freertos.o"
+"./Core/Src/lwiperf.o"
+"./Core/Src/main.o"
+"./Core/Src/mqtt_client.o"
+"./Core/Src/stm32h7xx_hal_msp.o"
+"./Core/Src/stm32h7xx_hal_timebase_tim.o"
+"./Core/Src/stm32h7xx_it.o"
+"./Core/Src/syscalls.o"
+"./Core/Src/sysmem.o"
+"./Core/Startup/startup_stm32h745xihx.o"
+"./Drivers/BSP/Components/lan8742.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_cortex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_dma.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_dma_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_exti.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_flash.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_flash_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_gpio.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_hsem.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_i2c.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_i2c_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_mdma.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_pwr.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_pwr_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_rcc.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_rcc_ex.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_tim.o"
+"./Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_tim_ex.o"
+"./LWIP/App/lwip.o"
+"./LWIP/Target/ethernetif.o"
+"./Middlewares/Third_Party/FreeRTOS/cmsis_os2.o"
+"./Middlewares/Third_Party/FreeRTOS/croutine.o"
+"./Middlewares/Third_Party/FreeRTOS/event_groups.o"
+"./Middlewares/Third_Party/FreeRTOS/heap_4.o"
+"./Middlewares/Third_Party/FreeRTOS/list.o"
+"./Middlewares/Third_Party/FreeRTOS/port.o"
+"./Middlewares/Third_Party/FreeRTOS/queue.o"
+"./Middlewares/Third_Party/FreeRTOS/stream_buffer.o"
+"./Middlewares/Third_Party/FreeRTOS/tasks.o"
+"./Middlewares/Third_Party/FreeRTOS/timers.o"
+"./Middlewares/Third_Party/LwIP/altcp.o"
+"./Middlewares/Third_Party/LwIP/altcp_alloc.o"
+"./Middlewares/Third_Party/LwIP/altcp_tcp.o"
+"./Middlewares/Third_Party/LwIP/api_lib.o"
+"./Middlewares/Third_Party/LwIP/api_msg.o"
+"./Middlewares/Third_Party/LwIP/auth.o"
+"./Middlewares/Third_Party/LwIP/autoip.o"
+"./Middlewares/Third_Party/LwIP/bridgeif.o"
+"./Middlewares/Third_Party/LwIP/bridgeif_fdb.o"
+"./Middlewares/Third_Party/LwIP/ccp.o"
+"./Middlewares/Third_Party/LwIP/chap-md5.o"
+"./Middlewares/Third_Party/LwIP/chap-new.o"
+"./Middlewares/Third_Party/LwIP/chap_ms.o"
+"./Middlewares/Third_Party/LwIP/def.o"
+"./Middlewares/Third_Party/LwIP/demand.o"
+"./Middlewares/Third_Party/LwIP/dhcp.o"
+"./Middlewares/Third_Party/LwIP/dhcp6.o"
+"./Middlewares/Third_Party/LwIP/dns.o"
+"./Middlewares/Third_Party/LwIP/eap.o"
+"./Middlewares/Third_Party/LwIP/ecp.o"
+"./Middlewares/Third_Party/LwIP/err.o"
+"./Middlewares/Third_Party/LwIP/etharp.o"
+"./Middlewares/Third_Party/LwIP/ethernet.o"
+"./Middlewares/Third_Party/LwIP/ethip6.o"
+"./Middlewares/Third_Party/LwIP/eui64.o"
+"./Middlewares/Third_Party/LwIP/fsm.o"
+"./Middlewares/Third_Party/LwIP/icmp.o"
+"./Middlewares/Third_Party/LwIP/icmp6.o"
+"./Middlewares/Third_Party/LwIP/if_api.o"
+"./Middlewares/Third_Party/LwIP/igmp.o"
+"./Middlewares/Third_Party/LwIP/inet6.o"
+"./Middlewares/Third_Party/LwIP/inet_chksum.o"
+"./Middlewares/Third_Party/LwIP/init.o"
+"./Middlewares/Third_Party/LwIP/ip.o"
+"./Middlewares/Third_Party/LwIP/ip4.o"
+"./Middlewares/Third_Party/LwIP/ip4_addr.o"
+"./Middlewares/Third_Party/LwIP/ip4_frag.o"
+"./Middlewares/Third_Party/LwIP/ip6.o"
+"./Middlewares/Third_Party/LwIP/ip6_addr.o"
+"./Middlewares/Third_Party/LwIP/ip6_frag.o"
+"./Middlewares/Third_Party/LwIP/ipcp.o"
+"./Middlewares/Third_Party/LwIP/ipv6cp.o"
+"./Middlewares/Third_Party/LwIP/lcp.o"
+"./Middlewares/Third_Party/LwIP/lowpan6.o"
+"./Middlewares/Third_Party/LwIP/lowpan6_ble.o"
+"./Middlewares/Third_Party/LwIP/lowpan6_common.o"
+"./Middlewares/Third_Party/LwIP/magic.o"
+"./Middlewares/Third_Party/LwIP/mem.o"
+"./Middlewares/Third_Party/LwIP/memp.o"
+"./Middlewares/Third_Party/LwIP/mld6.o"
+"./Middlewares/Third_Party/LwIP/mppe.o"
+"./Middlewares/Third_Party/LwIP/mqtt.o"
+"./Middlewares/Third_Party/LwIP/multilink.o"
+"./Middlewares/Third_Party/LwIP/nd6.o"
+"./Middlewares/Third_Party/LwIP/netbuf.o"
+"./Middlewares/Third_Party/LwIP/netdb.o"
+"./Middlewares/Third_Party/LwIP/netif.o"
+"./Middlewares/Third_Party/LwIP/netifapi.o"
+"./Middlewares/Third_Party/LwIP/pbuf.o"
+"./Middlewares/Third_Party/LwIP/ppp.o"
+"./Middlewares/Third_Party/LwIP/pppapi.o"
+"./Middlewares/Third_Party/LwIP/pppcrypt.o"
+"./Middlewares/Third_Party/LwIP/pppoe.o"
+"./Middlewares/Third_Party/LwIP/pppol2tp.o"
+"./Middlewares/Third_Party/LwIP/pppos.o"
+"./Middlewares/Third_Party/LwIP/raw.o"
+"./Middlewares/Third_Party/LwIP/slipif.o"
+"./Middlewares/Third_Party/LwIP/sockets.o"
+"./Middlewares/Third_Party/LwIP/stats.o"
+"./Middlewares/Third_Party/LwIP/sys.o"
+"./Middlewares/Third_Party/LwIP/sys_arch.o"
+"./Middlewares/Third_Party/LwIP/tcp.o"
+"./Middlewares/Third_Party/LwIP/tcp_in.o"
+"./Middlewares/Third_Party/LwIP/tcp_out.o"
+"./Middlewares/Third_Party/LwIP/tcpip.o"
+"./Middlewares/Third_Party/LwIP/timeouts.o"
+"./Middlewares/Third_Party/LwIP/udp.o"
+"./Middlewares/Third_Party/LwIP/upap.o"
+"./Middlewares/Third_Party/LwIP/utils.o"
+"./Middlewares/Third_Party/LwIP/vj.o"
+"./Middlewares/Third_Party/LwIP/zepif.o"
+"./Middlewares/Third_Party/MQTT/MQTTClient.o"
+"./Middlewares/Third_Party/MQTT/MQTTInterface.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTConnectClient.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTConnectServer.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTDeserializePublish.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTFormat.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTPacket.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSerializePublish.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSubscribeClient.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTSubscribeServer.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTUnsubscribeClient.o"
+"./Middlewares/Third_Party/MQTT/MQTTPacket/MQTTUnsubscribeServer.o"

+ 9 - 0
CM7/Release/objects.mk

@@ -0,0 +1,9 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+

+ 35 - 0
CM7/Release/sources.mk

@@ -0,0 +1,35 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (12.3.rel1)
+################################################################################
+
+ELF_SRCS := 
+OBJ_SRCS := 
+S_SRCS := 
+C_SRCS := 
+S_UPPER_SRCS := 
+O_SRCS := 
+CYCLO_FILES := 
+SIZE_OUTPUT := 
+OBJDUMP_LIST := 
+SU_FILES := 
+EXECUTABLES := 
+OBJS := 
+MAP_FILES := 
+S_DEPS := 
+S_UPPER_DEPS := 
+C_DEPS := 
+
+# Every subdirectory with source files must be described here
+SUBDIRS := \
+Core/Src \
+Core/Startup \
+Drivers/BSP/Components \
+Drivers/STM32H7xx_HAL_Driver \
+LWIP/App \
+LWIP/Target \
+Middlewares/Third_Party/FreeRTOS \
+Middlewares/Third_Party/LwIP \
+Middlewares/Third_Party/MQTT \
+Middlewares/Third_Party/MQTT/MQTTPacket \
+

+ 202 - 0
CM7/STM32H745XIHX_FLASH.ld

@@ -0,0 +1,202 @@
+/*
+******************************************************************************
+**
+**  File        : LinkerScript.ld
+**
+**  Author      : STM32CubeIDE
+**
+**  Abstract    : Linker script for STM32H7 series
+**                      1024Kbytes FLASH
+**                       800Kbytes RAM
+**
+**                Set heap size, stack size and stack location according
+**                to application requirements.
+**
+**                Set memory bank area and size if external memory is used.
+**
+**  Target      : STMicroelectronics STM32
+**
+**  Distribution: The file is distributed as is without any warranty
+**                of any kind.
+**
+*****************************************************************************
+** @attention
+**
+** Copyright (c) 2022 STMicroelectronics.
+** All rights reserved.
+**
+** This software is licensed under terms that can be found in the LICENSE file
+** in the root directory of this software component.
+** If no LICENSE file comes with this software, it is provided AS-IS.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of "RAM_D1" Ram type memory */
+
+_Min_Heap_Size = 0x200; /* required amount of heap  */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Memories definition */
+MEMORY
+{
+  RAM_D1 (xrw)   : ORIGIN = 0x24000000, LENGTH =  512K
+  FLASH  (rx)    : ORIGIN = 0x08000000, LENGTH = 1024K    /* Memory is divided. Actual start is 0x08000000 and actual length is 2048K */
+  DTCMRAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 128K
+  /* ETH_CODE: change offset & reduce size of RAM_D2 to not collide with M4 */
+  RAM_D2 (xrw)   : ORIGIN = 0x30020000, LENGTH = 160K
+  RAM_D3 (xrw)   : ORIGIN = 0x38000000, LENGTH = 64K
+  ITCMRAM (xrw)  : ORIGIN = 0x00000000, LENGTH = 64K
+}
+
+/* Sections */
+SECTIONS
+{
+  /* The startup code into "FLASH" Rom type memory */
+  .isr_vector :
+  {
+    . = ALIGN(4);
+    KEEP(*(.isr_vector)) /* Startup code */
+    . = ALIGN(4);
+  } >FLASH
+
+  /* The program code and other data into "FLASH" Rom type memory */
+  .text :
+  {
+    . = ALIGN(4);
+    *(.text)           /* .text sections (code) */
+    *(.text*)          /* .text* sections (code) */
+    *(.glue_7)         /* glue arm to thumb code */
+    *(.glue_7t)        /* glue thumb to arm code */
+    *(.eh_frame)
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    . = ALIGN(4);
+    _etext = .;        /* define a global symbols at end of code */
+  } >FLASH
+
+  /* Constant data into "FLASH" Rom type memory */
+  .rodata :
+  {
+    . = ALIGN(4);
+    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
+    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
+    . = ALIGN(4);
+  } >FLASH
+
+  .ARM.extab(READONLY)   : { 
+    . = ALIGN(4);
+    *(.ARM.extab* .gnu.linkonce.armextab.*)
+    . = ALIGN(4);
+  } >FLASH
+  
+  .ARM : {
+    . = ALIGN(4);
+    __exidx_start = .;
+    *(.ARM.exidx*)
+    __exidx_end = .;
+    . = ALIGN(4);
+  } >FLASH
+
+  .preinit_array(READONLY) :
+  {
+    . = ALIGN(4);
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array*))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+    . = ALIGN(4);
+  } >FLASH
+  
+  .init_array(READONLY) :
+  {
+    . = ALIGN(4);
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array*))
+    PROVIDE_HIDDEN (__init_array_end = .);
+    . = ALIGN(4);
+  } >FLASH
+  
+  .fini_array(READONLY) :
+  {
+    . = ALIGN(4);
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(SORT(.fini_array.*)))
+    KEEP (*(.fini_array*))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+    . = ALIGN(4);
+  } >FLASH
+
+  /* Used by the startup to initialize data */
+  _sidata = LOADADDR(.data);
+
+  /* Initialized data sections into "RAM" Ram type memory */
+  .data : 
+  {
+    . = ALIGN(4);
+    _sdata = .;        /* create a global symbol at data start */
+    *(.data)           /* .data sections */
+    *(.data*)          /* .data* sections */
+    *(.RamFunc)        /* .RamFunc sections */
+    *(.RamFunc*)       /* .RamFunc* sections */
+
+    . = ALIGN(4);
+    _edata = .;        /* define a global symbol at data end */
+  } >RAM_D1 AT> FLASH
+
+  /* Uninitialized data section into "RAM" Ram type memory */
+  . = ALIGN(4);
+  .bss :
+  {
+    /* This is used by the startup in order to initialize the .bss section */
+    _sbss = .;         /* define a global symbol at bss start */
+    __bss_start__ = _sbss;
+    *(.bss)
+    *(.bss*)
+    *(COMMON)
+
+    . = ALIGN(4);
+    _ebss = .;         /* define a global symbol at bss end */
+    __bss_end__ = _ebss;
+  } >RAM_D1
+
+  /* User_heap_stack section, used to check that there is enough "RAM" Ram  type memory left */
+  ._user_heap_stack :
+  {
+    . = ALIGN(8);
+    PROVIDE ( end = . );
+    PROVIDE ( _end = . );
+    . = . + _Min_Heap_Size;
+    . = . + _Min_Stack_Size;
+    . = ALIGN(8);
+  } >RAM_D1
+
+  /* ETH_CODE: add placement of DMA descriptors and RX buffers */
+  .lwip_sec (NOLOAD) :
+  {
+    . = ABSOLUTE(0x30040000);
+    *(.RxDecripSection) 
+    
+    . = ABSOLUTE(0x30040100);
+    *(.TxDecripSection)
+    
+    . = ABSOLUTE(0x30040200);
+    *(.Rx_PoolSection)  
+  } >RAM_D2
+
+  /* Remove information from the compiler libraries */
+  /DISCARD/ :
+  {
+    libc.a ( * )
+    libm.a ( * )
+    libgcc.a ( * )
+  }
+
+  .ARM.attributes 0 : { *(.ARM.attributes) }
+}

+ 0 - 0
CM7/STM32H745XIHX_RAM.ld


Some files were not shown because too many files changed in this diff