--some updates
This commit is contained in:
2
.idea/runConfigurations/OCD_Boot.xml
generated
2
.idea/runConfigurations/OCD_Boot.xml
generated
@@ -1,5 +1,5 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="OCD Boot" type="com.jetbrains.cidr.embedded.openocd.conf.type" factoryName="com.jetbrains.cidr.embedded.openocd.conf.factory" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="myProject" TARGET_NAME="boot.elf" CONFIG_NAME="BOOT_DEBUG" version="1" RUN_TARGET_PROJECT_NAME="myProject" RUN_TARGET_NAME="boot.elf">
|
<configuration default="false" name="OCD Boot" type="com.jetbrains.cidr.embedded.openocd.conf.type" factoryName="com.jetbrains.cidr.embedded.openocd.conf.factory" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="myProject" TARGET_NAME="boot.elf" CONFIG_NAME="BOOT" version="1" RUN_TARGET_PROJECT_NAME="myProject" RUN_TARGET_NAME="boot.elf">
|
||||||
<openocd version="1" gdb-port="3333" telnet-port="4444" board-config="board/st_nucleo_g0.cfg" reset-type="RUN" download-type="UPDATED_ONLY">
|
<openocd version="1" gdb-port="3333" telnet-port="4444" board-config="board/st_nucleo_g0.cfg" reset-type="RUN" download-type="UPDATED_ONLY">
|
||||||
<debugger kind="GDB" isBundled="true" />
|
<debugger kind="GDB" isBundled="true" />
|
||||||
</openocd>
|
</openocd>
|
||||||
|
|||||||
16
App/app.cpp
16
App/app.cpp
@@ -62,13 +62,27 @@ void AppInit(void)
|
|||||||
** \return none.
|
** \return none.
|
||||||
**
|
**
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
|
uint8_t temp[2];
|
||||||
void AppTask(void)
|
void AppTask(void)
|
||||||
{
|
{
|
||||||
|
if (!bridge.uart1Buf->is_empty() && (__HAL_UART_GET_FLAG(bridge.getHuart2(), UART_FLAG_TC)))
|
||||||
|
{
|
||||||
|
temp[1] = bridge.uart1Buf->dequeue();
|
||||||
|
HAL_UART_Transmit_IT(bridge.getHuart2(), &temp[1], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bridge.uart2Buf->is_empty() && (__HAL_UART_GET_FLAG(bridge.getHuart1(), UART_FLAG_TC)))
|
||||||
|
{
|
||||||
|
temp[2] = bridge.uart2Buf->dequeue();
|
||||||
|
HAL_UART_Transmit_IT(bridge.getHuart1(), &temp[2], 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* check for bootloader activation request */
|
/* check for bootloader activation request */
|
||||||
/*
|
/*
|
||||||
BootComCheckActivationRequest();
|
BootComCheckActivationRequest();
|
||||||
*/
|
*/
|
||||||
} /*** end of AppTask ***/
|
/*** end of AppTask ***/
|
||||||
|
|
||||||
|
|
||||||
/*********************************** end of app.c **************************************/
|
/*********************************** end of app.c **************************************/
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
|
|||||||
target_include_directories(${PROJECT_NAME}.elf PRIVATE ${INCLUDE_DIR} )
|
target_include_directories(${PROJECT_NAME}.elf PRIVATE ${INCLUDE_DIR} )
|
||||||
target_link_libraries(${PROJECT_NAME}.elf PUBLIC $ENV{MCU_SERIES}_HAL_DRIVER CMSIS)
|
target_link_libraries(${PROJECT_NAME}.elf PUBLIC $ENV{MCU_SERIES}_HAL_DRIVER CMSIS)
|
||||||
add_custom_command(TARGET ${PROJECT_NAME}.elf PRE_BUILD
|
add_custom_command(TARGET ${PROJECT_NAME}.elf PRE_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/${MEM_MAP_FILE}" ${PROJECT_BINARY_DIR}/${MEM_MAP_FILE}
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/${MEM_MAP_FILE}" ${PROJECT_BINARY_DIR}/../${MEM_MAP_FILE}
|
||||||
)
|
)
|
||||||
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
|
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
|
||||||
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
|
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
/* Entry Point */
|
/* Entry Point */
|
||||||
ENTRY(Reset_Handler)
|
ENTRY(Reset_Handler)
|
||||||
INCLUDE Boot/memory_map.inc
|
INCLUDE memory_map.inc
|
||||||
|
|
||||||
/* Highest address of the user mode stack */
|
/* Highest address of the user mode stack */
|
||||||
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
|
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
|
||||||
|
|||||||
7
Boot/memory_map.inc
Normal file
7
Boot/memory_map.inc
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
_flash_eeprom_emu_size = 0x1000;
|
||||||
|
_flash_eeprom_emu_address = 0x801f000;
|
||||||
|
_flash_main_prog_size = 0x1d000;
|
||||||
|
_flash_main_prog_address = 0x8002000;
|
||||||
|
_flash_boot_size = 0x2000;
|
||||||
|
_flash_boot_address = 0x8000000;
|
||||||
@@ -6,9 +6,9 @@ cmake_minimum_required(VERSION 3.23)
|
|||||||
set (ENV{HAL_DRIVER_CONFIG} ${CMAKE_CURRENT_SOURCE_DIR}/main_prog/Core/Inc/stm32g0xx_hal_conf.h)
|
set (ENV{HAL_DRIVER_CONFIG} ${CMAKE_CURRENT_SOURCE_DIR}/main_prog/Core/Inc/stm32g0xx_hal_conf.h)
|
||||||
set(ENV{MCU} "STM32G070xx")
|
set(ENV{MCU} "STM32G070xx")
|
||||||
if(BOOT)
|
if(BOOT)
|
||||||
set (ENV{LINKER_SCRIPT} ${CMAKE_SOURCE_DIR}/Boot/STM32G070CBTX_FLASH.ld)
|
set (LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/Boot/STM32G070CBTX_FLASH.ld)
|
||||||
else()
|
else()
|
||||||
set(ENV{LINKER_SCRIPT} ${CMAKE_SOURCE_DIR}/STM32G070CBTX_FLASH.ld )
|
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/main_prog/STM32G070CBTX_FLASH.ld )
|
||||||
endif()
|
endif()
|
||||||
set(ENV{FREERTOS_CONFIG} "${CMAKE_CURRENT_SOURCE_DIR}/main_prog/Core/Inc/FreeRTOSConfig.h")
|
set(ENV{FREERTOS_CONFIG} "${CMAKE_CURRENT_SOURCE_DIR}/main_prog/Core/Inc/FreeRTOSConfig.h")
|
||||||
#/////////////////////////////////////////////
|
#/////////////////////////////////////////////
|
||||||
@@ -93,7 +93,7 @@ else()
|
|||||||
-mcpu=cortex-m$ENV{CORTEX-M}
|
-mcpu=cortex-m$ENV{CORTEX-M}
|
||||||
-mthumb
|
-mthumb
|
||||||
-mthumb-interwork
|
-mthumb-interwork
|
||||||
-T $ENV{LINKER_SCRIPT}
|
-T ${LINKER_SCRIPT}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(COMPILE_DEF
|
set(COMPILE_DEF
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
/* Entry Point */
|
/* Entry Point */
|
||||||
ENTRY(Reset_Handler)
|
ENTRY(Reset_Handler)
|
||||||
INCLUDE main_prog/memory_map.inc
|
INCLUDE memory_map.inc
|
||||||
|
|
||||||
/* Highest address of the user mode stack */
|
/* Highest address of the user mode stack */
|
||||||
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
|
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
|
||||||
|
|||||||
@@ -91,11 +91,11 @@ add_link_options(-specs=nano.specs -specs=nosys.specs)
|
|||||||
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
|
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
|
||||||
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||||
add_custom_command(TARGET ${PROJECT_NAME}.elf PRE_BUILD
|
add_custom_command(TARGET ${PROJECT_NAME}.elf PRE_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/${MEM_MAP_FILE_DEBUG}" ${PROJECT_BINARY_DIR}/${MEM_MAP_FILE}
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/${MEM_MAP_FILE_DEBUG}" ${PROJECT_BINARY_DIR}/../${MEM_MAP_FILE}
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
add_custom_command(TARGET ${PROJECT_NAME}.elf PRE_BUILD
|
add_custom_command(TARGET ${PROJECT_NAME}.elf PRE_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/${MEM_MAP_FILE}" ${PROJECT_BINARY_DIR}/${MEM_MAP_FILE}
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/${MEM_MAP_FILE}" ${PROJECT_BINARY_DIR}/../${MEM_MAP_FILE}
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
|
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ public:
|
|||||||
Circular_Buffer<uint8_t> *uart1Buf;
|
Circular_Buffer<uint8_t> *uart1Buf;
|
||||||
Circular_Buffer<uint8_t> *uart2Buf;
|
Circular_Buffer<uint8_t> *uart2Buf;
|
||||||
bool isTurnOn() const;
|
bool isTurnOn() const;
|
||||||
void setIsTurnOn(bool isTurnOn);
|
void setTurnOn(bool isTurnOn);
|
||||||
static volatile uint8_t dataFromUart1;
|
volatile uint8_t dataFromUart1;
|
||||||
static volatile uint8_t dataFromUart2;
|
volatile uint8_t dataFromUart2;
|
||||||
void init(void);
|
void init(void);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -11,26 +11,7 @@ UartBridge* bridgePnt;
|
|||||||
|
|
||||||
uint8_t data[2];
|
uint8_t data[2];
|
||||||
|
|
||||||
extern "C" void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart){
|
|
||||||
|
|
||||||
if (huart == bridgePnt->getHuart1())
|
|
||||||
{
|
|
||||||
if (!bridgePnt->uart1Buf->is_empty() && (__HAL_UART_GET_FLAG(bridgePnt->getHuart2(), UART_FLAG_TC)))
|
|
||||||
{
|
|
||||||
data[1] = bridgePnt->uart1Buf->dequeue();
|
|
||||||
HAL_UART_Transmit_IT(bridgePnt->getHuart2(), &data[1], 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (huart == bridgePnt->getHuart2())
|
|
||||||
{
|
|
||||||
if (!bridgePnt->uart2Buf->is_empty() && (__HAL_UART_GET_FLAG(bridgePnt->getHuart1(), UART_FLAG_TC)))
|
|
||||||
{
|
|
||||||
data[2] = bridgePnt->uart2Buf->dequeue();
|
|
||||||
HAL_UART_Transmit_IT(bridgePnt->getHuart1(), &data[2], 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
|
extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
|
||||||
|
|
||||||
@@ -75,7 +56,7 @@ bool UartBridge::isTurnOn() const {
|
|||||||
return turnOn;
|
return turnOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UartBridge::setIsTurnOn(bool isTurnOn) {
|
void UartBridge::setTurnOn(bool isTurnOn) {
|
||||||
UartBridge::turnOn = isTurnOn;
|
UartBridge::turnOn = isTurnOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +111,7 @@ extern "C" void USART1_IRQHandler(void)
|
|||||||
/**
|
/**
|
||||||
* @brief This function handles USART2 global interrupt / USART2 wake-up interrupt through EXTI line 26.
|
* @brief This function handles USART2 global interrupt / USART2 wake-up interrupt through EXTI line 26.
|
||||||
*/
|
*/
|
||||||
void USART2_IRQHandler(void)
|
extern "C" void USART2_IRQHandler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN USART2_IRQn 0 */
|
/* USER CODE BEGIN USART2_IRQn 0 */
|
||||||
|
|
||||||
|
|||||||
186
main_prog/STM32G070CBTX_FLASH.ld
Normal file
186
main_prog/STM32G070CBTX_FLASH.ld
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
******************************************************************************
|
||||||
|
**
|
||||||
|
** @file : LinkerScript.ld
|
||||||
|
**
|
||||||
|
** @author : Auto-generated by STM32CubeIDE
|
||||||
|
**
|
||||||
|
** @brief : Linker script for STM32G070CBTx Device from STM32G0 series
|
||||||
|
** 128Kbytes FLASH
|
||||||
|
** 36Kbytes 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) 2023 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)
|
||||||
|
INCLUDE memory_map.inc
|
||||||
|
|
||||||
|
/* Highest address of the user mode stack */
|
||||||
|
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
|
||||||
|
|
||||||
|
_Min_Heap_Size = 0x1000; /* required amount of heap */
|
||||||
|
_Min_Stack_Size = 0x1000; /* required amount of stack */
|
||||||
|
|
||||||
|
/* Memories definition */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 36K
|
||||||
|
USER_PROG_FLASH_AREA(rx) : ORIGIN = _flash_main_prog_address , LENGTH = _flash_main_prog_size
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sections */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* The startup code into "FLASH" Rom type memory */
|
||||||
|
.isr_vector :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.isr_vector)) /* Startup code */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >USER_PROG_FLASH_AREA
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
} >USER_PROG_FLASH_AREA
|
||||||
|
|
||||||
|
/* Constant data into "FLASH" Rom type memory */
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||||
|
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >USER_PROG_FLASH_AREA
|
||||||
|
|
||||||
|
.ARM.extab : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >USER_PROG_FLASH_AREA
|
||||||
|
|
||||||
|
.ARM : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
__exidx_start = .;
|
||||||
|
*(.ARM.exidx*)
|
||||||
|
__exidx_end = .;
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >USER_PROG_FLASH_AREA
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array*))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >USER_PROG_FLASH_AREA
|
||||||
|
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array*))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >USER_PROG_FLASH_AREA
|
||||||
|
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
KEEP (*(.fini_array*))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >USER_PROG_FLASH_AREA
|
||||||
|
|
||||||
|
/* 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 AT> USER_PROG_FLASH_AREA
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
/* Remove information from the compiler libraries */
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
libc.a ( * )
|
||||||
|
libm.a ( * )
|
||||||
|
libgcc.a ( * )
|
||||||
|
}
|
||||||
|
|
||||||
|
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user