/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file app_azure_rtos.c * @author MCD Application Team * @brief app_azure_rtos application implementation file ****************************************************************************** * @attention * * Copyright (c) 2020-2021 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 "app_azure_rtos.h" #include "stm32h7xx.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "app.h" #include "app_touchgfx.h" #include "leds.h" #include "main.h" #include "tx_api.h" #include "tx_port.h" #include "ui.h" #include "vehicle.h" /* 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 ---------------------------------------------------------*/ #if (USE_STATIC_ALLOCATION == 1) /* USER CODE BEGIN TX_Pool_Buffer */ /* USER CODE END TX_Pool_Buffer */ #if defined(__ICCARM__) #pragma data_alignment = 4 #endif __ALIGN_BEGIN static UCHAR tx_byte_pool_buffer[TX_APP_MEM_POOL_SIZE] __ALIGN_END; static TX_BYTE_POOL tx_app_byte_pool; #endif /* USER CODE BEGIN PV */ TX_THREAD app_thread; TX_THREAD ui_thread; TX_THREAD vehicle_thread; TX_THREAD led_thread; TX_THREAD params_thread; TX_QUEUE gui_button_queue; TX_EVENT_FLAGS_GROUP gui_update_events; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /** * @brief Define the initial system. * @param first_unused_memory : Pointer to the first unused memory * @retval None */ VOID tx_application_define(VOID *first_unused_memory) { /* USER CODE BEGIN tx_application_define_1*/ /* USER CODE END tx_application_define_1 */ #if (USE_STATIC_ALLOCATION == 1) UINT status = TX_SUCCESS; VOID *memory_ptr; if (tx_byte_pool_create(&tx_app_byte_pool, "Tx App memory pool", tx_byte_pool_buffer, TX_APP_MEM_POOL_SIZE) != TX_SUCCESS) { /* USER CODE BEGIN TX_Byte_Pool_Error */ /* USER CODE END TX_Byte_Pool_Error */ } else { /* USER CODE BEGIN TX_Byte_Pool_Success */ /* USER CODE END TX_Byte_Pool_Success */ memory_ptr = (VOID *)&tx_app_byte_pool; status = App_ThreadX_Init(memory_ptr); if (status != TX_SUCCESS) { /* USER CODE BEGIN App_ThreadX_Init_Error */ while (1) { } /* USER CODE END App_ThreadX_Init_Error */ } /* USER CODE BEGIN App_ThreadX_Init_Success */ /* USER CODE END App_ThreadX_Init_Success */ } #else /* * Using dynamic memory allocation requires to apply some changes to the linker file. * ThreadX needs to pass a pointer to the first free memory location in RAM to the tx_application_define() function, * using the "first_unused_memory" argument. * This require changes in the linker files to expose this memory location. * For EWARM add the following section into the .icf file: place in RAM_region { last section FREE_MEM }; * For MDK-ARM - either define the RW_IRAM1 region in the ".sct" file - or modify the line below in "tx_initialize_low_level.S to match the memory region being used LDR r1, =|Image$$RW_IRAM1$$ZI$$Limit| * For STM32CubeIDE add the following section into the .ld file: ._threadx_heap : { . = ALIGN(8); __RAM_segment_used_end__ = .; . = . + 64K; . = ALIGN(8); } >RAM_D1 AT> RAM_D1 * The simplest way to provide memory for ThreadX is to define a new section, see ._threadx_heap above. * In the example above the ThreadX heap size is set to 64KBytes. * The ._threadx_heap must be located between the .bss and the ._user_heap_stack sections in the linker script. * Caution: Make sure that ThreadX does not need more than the provided heap memory (64KBytes in this example). * Read more in STM32CubeIDE User Guide, chapter: "Linker script". * The "tx_initialize_low_level.S" should be also modified to enable the "USE_DYNAMIC_MEMORY_ALLOCATION" flag. */ /* USER CODE BEGIN DYNAMIC_MEM_ALLOC */ void *mem = first_unused_memory; void *app_thread_stack = mem; mem += THREAD_STACK_SIZE; if (tx_thread_create(&app_thread, "Main Thread", app_thread_entry, 0, app_thread_stack, THREAD_STACK_SIZE, THREAD_PRIO_APP, THREAD_PRIO_APP, TX_NO_TIME_SLICE, TX_AUTO_START) != TX_SUCCESS) { Error_Handler(); } void *ui_queue_start = mem; ULONG ui_queue_msg_size = sizeof(ButtonMessage) / sizeof(ULONG); if (sizeof(ButtonMessage) % sizeof(ULONG) != 0) { ui_queue_msg_size++; } mem += UI_QUEUE_SIZE * ui_queue_msg_size; if (tx_queue_create(&gui_button_queue, "UI Queue", ui_queue_msg_size, ui_queue_start, UI_QUEUE_SIZE * ui_queue_msg_size) != TX_SUCCESS) { Error_Handler(); } void *ui_thread_stack = mem; mem += THREAD_STACK_SIZE; if (tx_thread_create(&ui_thread, "UI Thread", ui_thread_entry, 0, ui_thread_stack, THREAD_STACK_SIZE, THREAD_PRIO_UI, THREAD_PRIO_UI, TX_NO_TIME_SLICE, TX_AUTO_START) != TX_SUCCESS) { Error_Handler(); } if (tx_event_flags_create(&gui_update_events, "GUI Update Events") != TX_SUCCESS) { Error_Handler(); } void *vehicle_thread_stack = mem; mem += THREAD_STACK_SIZE; ULONG hfdcan_addr = (ULONG)&hfdcan1; if (tx_thread_create(&vehicle_thread, "Vehicle Thread", vehicle_thread_entry, hfdcan_addr, vehicle_thread_stack, THREAD_STACK_SIZE, THREAD_PRIO_VEHICLE, THREAD_PRIO_VEHICLE, 0, TX_AUTO_START) != TX_SUCCESS) { Error_Handler(); } void *led_thread_stack = mem; mem += THREAD_STACK_SIZE; void *led_child_thread_stack = mem; mem += THREAD_STACK_SIZE; if (tx_thread_create(&led_thread, "LED Thread", led_thread_entry, (ULONG)led_child_thread_stack, led_thread_stack, THREAD_STACK_SIZE, THREAD_PRIO_LED, THREAD_PRIO_LED, 0, TX_AUTO_START) != TX_SUCCESS) { Error_Handler(); } void *params_thread_stack = mem; mem += THREAD_STACK_SIZE; if (tx_thread_create(¶ms_thread, "Params Thread", params_thread_entry, 0, params_thread_stack, THREAD_STACK_SIZE, THREAD_PRIO_PARAMS, THREAD_PRIO_UI, TX_NO_TIME_SLICE, TX_AUTO_START) != TX_SUCCESS) { Error_Handler(); } if (MX_TouchGFX_Init(mem) != TX_SUCCESS) { Error_Handler(); } // TODO: Use TOUCHGFX_BYTE_POOL_SIZE? This is only defined in app_touchgfx.c mem += 4096; /* USER CODE END DYNAMIC_MEM_ALLOC */ #endif }