feat(school_stm32): 添加基础的 STM32F103RCT6 项目结构
- 创建了项目的基本目录结构和文件 - 添加了 CMakeLists.txt 和 Makefile 构建配置 - 创建了 main.c 文件,实现了简单的 LED 闪烁和按键检测功能 - 集成了 SEGGER RTT 库 - 添加了 .gitignore 文件,排除了不必要的生成文件
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,7 @@
|
|||||||
*
|
*
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
!Core/
|
||||||
|
!Core/Src/
|
||||||
!Core/Src/main.c
|
!Core/Src/main.c
|
||||||
!libs/
|
!libs/
|
||||||
!libs/**/*
|
!libs/**/*
|
||||||
|
76
CMakeLists.txt
Normal file
76
CMakeLists.txt
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
|
#
|
||||||
|
# This file is generated only once,
|
||||||
|
# and is not re-generated if converter is called multiple times.
|
||||||
|
#
|
||||||
|
# User is free to modify the file as much as necessary
|
||||||
|
#
|
||||||
|
|
||||||
|
# Setup compiler settings
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_C_EXTENSIONS ON)
|
||||||
|
|
||||||
|
|
||||||
|
# Define the build type
|
||||||
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE "Debug")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set the project name
|
||||||
|
set(CMAKE_PROJECT_NAME embedding)
|
||||||
|
|
||||||
|
# Include toolchain file
|
||||||
|
include("cmake/gcc-arm-none-eabi.cmake")
|
||||||
|
|
||||||
|
# Enable compile command to ease indexing with e.g. clangd
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
|
||||||
|
|
||||||
|
# Core project settings
|
||||||
|
project(${CMAKE_PROJECT_NAME})
|
||||||
|
message("Build type: " ${CMAKE_BUILD_TYPE})
|
||||||
|
|
||||||
|
# Enable CMake support for ASM and C languages
|
||||||
|
enable_language(C ASM)
|
||||||
|
|
||||||
|
# Create an executable object type
|
||||||
|
add_executable(${CMAKE_PROJECT_NAME})
|
||||||
|
|
||||||
|
# Add STM32CubeMX generated sources
|
||||||
|
add_subdirectory(cmake/stm32cubemx)
|
||||||
|
|
||||||
|
# Link directories setup
|
||||||
|
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
|
||||||
|
# Add user defined library search paths
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add sources to executable
|
||||||
|
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
|
||||||
|
# Add user sources here
|
||||||
|
libs/SEGGER_RTT/RTT/SEGGER_RTT.c
|
||||||
|
libs/SEGGER_RTT/RTT/SEGGER_RTT_printf.c
|
||||||
|
libs/SEGGER_RTT/RTT/SEGGER_RTT_ASM_ARMv7M.S
|
||||||
|
# SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_GCC.c
|
||||||
|
libs/ge_interface/ge_input.c
|
||||||
|
libs/ge_interface/ge_render.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add include paths
|
||||||
|
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
|
||||||
|
# Add user defined include paths
|
||||||
|
libs
|
||||||
|
# Core/Inc
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add project symbols (macros)
|
||||||
|
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
|
||||||
|
# Add user defined symbols
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add linked libraries
|
||||||
|
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||||
|
stm32cubemx
|
||||||
|
|
||||||
|
# Add user defined libraries
|
||||||
|
)
|
233
Core/Src/main.c
Normal file
233
Core/Src/main.c
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : main.c
|
||||||
|
* @brief : Main program body
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 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 "gpio.h"
|
||||||
|
|
||||||
|
/* Private includes ----------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
#define __PYNIC_LOG_IMPLIMENT__
|
||||||
|
#include <logger.h>
|
||||||
|
#include <ge_interface/ge_interface.h>
|
||||||
|
|
||||||
|
#define RED 0xf800
|
||||||
|
#define GREEN 0x07e0
|
||||||
|
#define BLUE 0x001f
|
||||||
|
#define WHITE 0xffff
|
||||||
|
#define BLACK 0x0000
|
||||||
|
#define YELLOW 0xFFE0
|
||||||
|
#define GRAY0 0xEF7D
|
||||||
|
#define GRAY1 0x8410
|
||||||
|
#define GRAY2 0x4208
|
||||||
|
|
||||||
|
/* 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 PV */
|
||||||
|
|
||||||
|
/* USER CODE END PV */
|
||||||
|
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
void SystemClock_Config(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 */
|
||||||
|
|
||||||
|
/* 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 SysInit */
|
||||||
|
|
||||||
|
/* USER CODE END SysInit */
|
||||||
|
|
||||||
|
/* Initialize all configured peripherals */
|
||||||
|
MX_GPIO_Init();
|
||||||
|
/* USER CODE BEGIN 2 */
|
||||||
|
INIT_LOGGER();
|
||||||
|
ge_render.init_func(&ge_render, 0);
|
||||||
|
ge_render_rect_t full_screen_rect = {
|
||||||
|
.pos.x = 0,
|
||||||
|
.pos.y = 0,
|
||||||
|
.size = ge_render.screen_size,
|
||||||
|
};
|
||||||
|
ge_render.func_draw_rect(&ge_render, &full_screen_rect, WHITE);
|
||||||
|
// Assert(0);
|
||||||
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
|
/* Infinite loop */
|
||||||
|
/* USER CODE BEGIN WHILE */
|
||||||
|
ge_input_event_t ievent;
|
||||||
|
ge_render_rect_t player = {
|
||||||
|
.pos.x = 0,
|
||||||
|
.pos.y = 0,
|
||||||
|
.size.x = 10,
|
||||||
|
.size.y = 10,
|
||||||
|
};
|
||||||
|
int speed = 5;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
input_btn_func(&ge_input);
|
||||||
|
while (ge_input.func_recv(&ge_input, &ievent) == 0) {
|
||||||
|
switch (ievent.num) {
|
||||||
|
case GE_ITYPE_KEY_1:
|
||||||
|
player.pos.x += speed;
|
||||||
|
break;
|
||||||
|
case GE_ITYPE_KEY_2:
|
||||||
|
player.pos.y -= speed;
|
||||||
|
break;
|
||||||
|
case GE_ITYPE_KEY_3:
|
||||||
|
player.pos.y += speed;
|
||||||
|
break;
|
||||||
|
case GE_ITYPE_KEY_4:
|
||||||
|
player.pos.x -= speed;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_INFO("%d pressd", ievent.num);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ge_render.func_draw_rect(&ge_render, &full_screen_rect, WHITE);
|
||||||
|
ge_render.func_draw_rect(&ge_render, &player, RED);
|
||||||
|
ge_render.func_flush(&ge_render);
|
||||||
|
HAL_Delay(33); // 去抖动延时
|
||||||
|
/* 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};
|
||||||
|
|
||||||
|
/** 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.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
|
||||||
|
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||||
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||||
|
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
|
||||||
|
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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||||
|
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||||
|
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||||
|
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||||
|
|
||||||
|
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
HAL_GPIO_TogglePin(SOND_GPIO_Port, SOND_Pin);
|
||||||
|
HAL_Delay(100);
|
||||||
|
HAL_GPIO_TogglePin(SOND_GPIO_Port, SOND_Pin);
|
||||||
|
__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 */
|
23
Makefile
Normal file
23
Makefile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Makefile 配置
|
||||||
|
FLASH_TOOL = "D:/Programs/_compiler/ST/JLink/JFlash.exe"
|
||||||
|
FLASH_PRJ = "/Git_Code/school_stm32/embedding/jflash.jflash"
|
||||||
|
CMAKE = "cmake"
|
||||||
|
|
||||||
|
TARGET = build/embedding.elf
|
||||||
|
|
||||||
|
build:
|
||||||
|
$(CMAKE) -B build -G "MinGW Makefiles"
|
||||||
|
$(CMAKE) --build build
|
||||||
|
|
||||||
|
$(TARGET):
|
||||||
|
$(CMAKE) --build build
|
||||||
|
|
||||||
|
flash: $(TARGET)
|
||||||
|
$(FLASH_TOOL) -openprj$(FLASH_PRJ) -auto -startapp -exit
|
||||||
|
|
||||||
|
flash_not_exit: $(TARGET)
|
||||||
|
$(FLASH_TOOL) -openprj$(FLASH_PRJ) -auto -startapp
|
||||||
|
|
||||||
|
all: build flash
|
||||||
|
|
||||||
|
.PHONY: flash build all flash_not_exit
|
256
embedding.ioc
Normal file
256
embedding.ioc
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
#MicroXplorer Configuration settings - do not modify
|
||||||
|
CAD.formats=
|
||||||
|
CAD.pinconfig=
|
||||||
|
CAD.provider=
|
||||||
|
File.Version=6
|
||||||
|
GPIO.groupedBy=Group By Peripherals
|
||||||
|
KeepUserPlacement=false
|
||||||
|
Mcu.CPN=STM32F103RCT6
|
||||||
|
Mcu.Family=STM32F1
|
||||||
|
Mcu.IP0=NVIC
|
||||||
|
Mcu.IP1=RCC
|
||||||
|
Mcu.IP2=SYS
|
||||||
|
Mcu.IPNb=3
|
||||||
|
Mcu.Name=STM32F103R(C-D-E)Tx
|
||||||
|
Mcu.Package=LQFP64
|
||||||
|
Mcu.Pin0=PC14-OSC32_IN
|
||||||
|
Mcu.Pin1=PC15-OSC32_OUT
|
||||||
|
Mcu.Pin10=PB10
|
||||||
|
Mcu.Pin11=PB11
|
||||||
|
Mcu.Pin12=PB12
|
||||||
|
Mcu.Pin13=PB13
|
||||||
|
Mcu.Pin14=PB14
|
||||||
|
Mcu.Pin15=PB15
|
||||||
|
Mcu.Pin16=PC6
|
||||||
|
Mcu.Pin17=PC7
|
||||||
|
Mcu.Pin18=PC8
|
||||||
|
Mcu.Pin19=PC9
|
||||||
|
Mcu.Pin2=PD0-OSC_IN
|
||||||
|
Mcu.Pin20=PA13
|
||||||
|
Mcu.Pin21=PA14
|
||||||
|
Mcu.Pin22=PC10
|
||||||
|
Mcu.Pin23=PC11
|
||||||
|
Mcu.Pin24=PD2
|
||||||
|
Mcu.Pin25=PB3
|
||||||
|
Mcu.Pin26=PB4
|
||||||
|
Mcu.Pin27=PB9
|
||||||
|
Mcu.Pin28=VP_SYS_VS_Systick
|
||||||
|
Mcu.Pin3=PD1-OSC_OUT
|
||||||
|
Mcu.Pin4=PC0
|
||||||
|
Mcu.Pin5=PC1
|
||||||
|
Mcu.Pin6=PC2
|
||||||
|
Mcu.Pin7=PC3
|
||||||
|
Mcu.Pin8=PC4
|
||||||
|
Mcu.Pin9=PC5
|
||||||
|
Mcu.PinsNb=29
|
||||||
|
Mcu.ThirdPartyNb=0
|
||||||
|
Mcu.UserConstants=
|
||||||
|
Mcu.UserName=STM32F103RCTx
|
||||||
|
MxCube.Version=6.14.1
|
||||||
|
MxDb.Version=DB.6.0.141
|
||||||
|
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
|
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
|
NVIC.ForceEnableDMAVector=true
|
||||||
|
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
|
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
|
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
|
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
|
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
|
||||||
|
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
|
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
|
||||||
|
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
|
PA13.Mode=Serial_Wire
|
||||||
|
PA13.Signal=SYS_JTMS-SWDIO
|
||||||
|
PA14.Mode=Serial_Wire
|
||||||
|
PA14.Signal=SYS_JTCK-SWCLK
|
||||||
|
PB10.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
|
||||||
|
PB10.GPIO_Label=LCD_BL
|
||||||
|
PB10.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||||
|
PB10.Locked=true
|
||||||
|
PB10.PinState=GPIO_PIN_SET
|
||||||
|
PB10.Signal=GPIO_Output
|
||||||
|
PB11.GPIOParameters=GPIO_Speed,GPIO_Label
|
||||||
|
PB11.GPIO_Label=LCD_CS
|
||||||
|
PB11.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||||
|
PB11.Locked=true
|
||||||
|
PB11.Signal=GPIO_Output
|
||||||
|
PB12.GPIOParameters=GPIO_Speed,GPIO_Label
|
||||||
|
PB12.GPIO_Label=LCD_DC
|
||||||
|
PB12.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||||
|
PB12.Locked=true
|
||||||
|
PB12.Signal=GPIO_Output
|
||||||
|
PB13.GPIOParameters=GPIO_Speed,GPIO_Label
|
||||||
|
PB13.GPIO_Label=LCD_RES
|
||||||
|
PB13.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||||
|
PB13.Locked=true
|
||||||
|
PB13.Signal=GPIO_Output
|
||||||
|
PB14.GPIOParameters=GPIO_Speed,GPIO_Label
|
||||||
|
PB14.GPIO_Label=LCD_SDA
|
||||||
|
PB14.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||||
|
PB14.Locked=true
|
||||||
|
PB14.Signal=GPIO_Output
|
||||||
|
PB15.GPIOParameters=GPIO_Speed,GPIO_Label
|
||||||
|
PB15.GPIO_Label=LCD_SCL
|
||||||
|
PB15.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||||
|
PB15.Locked=true
|
||||||
|
PB15.Signal=GPIO_Output
|
||||||
|
PB3.GPIOParameters=PinState,GPIO_Label
|
||||||
|
PB3.GPIO_Label=LED_R
|
||||||
|
PB3.Locked=true
|
||||||
|
PB3.PinState=GPIO_PIN_SET
|
||||||
|
PB3.Signal=GPIO_Output
|
||||||
|
PB4.GPIOParameters=PinState,GPIO_Label
|
||||||
|
PB4.GPIO_Label=LED_G
|
||||||
|
PB4.Locked=true
|
||||||
|
PB4.PinState=GPIO_PIN_SET
|
||||||
|
PB4.Signal=GPIO_Output
|
||||||
|
PB9.GPIOParameters=GPIO_Label
|
||||||
|
PB9.GPIO_Label=SOND
|
||||||
|
PB9.Locked=true
|
||||||
|
PB9.Signal=GPIO_Output
|
||||||
|
PC0.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
|
||||||
|
PC0.GPIO_Label=KEY_L1
|
||||||
|
PC0.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
|
||||||
|
PC0.GPIO_PuPd=GPIO_NOPULL
|
||||||
|
PC0.GPIO_Speed=GPIO_SPEED_FREQ_LOW
|
||||||
|
PC0.Locked=true
|
||||||
|
PC0.PinState=GPIO_PIN_SET
|
||||||
|
PC0.Signal=GPIO_Output
|
||||||
|
PC1.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
|
||||||
|
PC1.GPIO_Label=KEY_L2
|
||||||
|
PC1.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
|
||||||
|
PC1.GPIO_PuPd=GPIO_NOPULL
|
||||||
|
PC1.GPIO_Speed=GPIO_SPEED_FREQ_LOW
|
||||||
|
PC1.Locked=true
|
||||||
|
PC1.PinState=GPIO_PIN_SET
|
||||||
|
PC1.Signal=GPIO_Output
|
||||||
|
PC10.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||||
|
PC10.GPIO_Label=KEY_3
|
||||||
|
PC10.GPIO_PuPd=GPIO_PULLUP
|
||||||
|
PC10.Locked=true
|
||||||
|
PC10.Signal=GPIO_Input
|
||||||
|
PC11.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||||
|
PC11.GPIO_Label=KEY_4
|
||||||
|
PC11.GPIO_PuPd=GPIO_PULLUP
|
||||||
|
PC11.Locked=true
|
||||||
|
PC11.Signal=GPIO_Input
|
||||||
|
PC14-OSC32_IN.Mode=LSE-External-Oscillator
|
||||||
|
PC14-OSC32_IN.Signal=RCC_OSC32_IN
|
||||||
|
PC15-OSC32_OUT.Mode=LSE-External-Oscillator
|
||||||
|
PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
|
||||||
|
PC2.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
|
||||||
|
PC2.GPIO_Label=KEY_L3
|
||||||
|
PC2.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
|
||||||
|
PC2.GPIO_PuPd=GPIO_NOPULL
|
||||||
|
PC2.GPIO_Speed=GPIO_SPEED_FREQ_LOW
|
||||||
|
PC2.Locked=true
|
||||||
|
PC2.PinState=GPIO_PIN_SET
|
||||||
|
PC2.Signal=GPIO_Output
|
||||||
|
PC3.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
|
||||||
|
PC3.GPIO_Label=KEY_L4
|
||||||
|
PC3.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
|
||||||
|
PC3.GPIO_PuPd=GPIO_NOPULL
|
||||||
|
PC3.GPIO_Speed=GPIO_SPEED_FREQ_LOW
|
||||||
|
PC3.Locked=true
|
||||||
|
PC3.PinState=GPIO_PIN_SET
|
||||||
|
PC3.Signal=GPIO_Output
|
||||||
|
PC4.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||||
|
PC4.GPIO_Label=KEY_H1
|
||||||
|
PC4.GPIO_PuPd=GPIO_PULLUP
|
||||||
|
PC4.Locked=true
|
||||||
|
PC4.Signal=GPIO_Input
|
||||||
|
PC5.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||||
|
PC5.GPIO_Label=KEY_H2
|
||||||
|
PC5.GPIO_PuPd=GPIO_PULLUP
|
||||||
|
PC5.Locked=true
|
||||||
|
PC5.Signal=GPIO_Input
|
||||||
|
PC6.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||||
|
PC6.GPIO_Label=KEY_H3
|
||||||
|
PC6.GPIO_PuPd=GPIO_PULLUP
|
||||||
|
PC6.Locked=true
|
||||||
|
PC6.Signal=GPIO_Input
|
||||||
|
PC7.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||||
|
PC7.GPIO_Label=KEY_H4
|
||||||
|
PC7.GPIO_PuPd=GPIO_PULLUP
|
||||||
|
PC7.Locked=true
|
||||||
|
PC7.Signal=GPIO_Input
|
||||||
|
PC8.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||||
|
PC8.GPIO_Label=KEY_1
|
||||||
|
PC8.GPIO_PuPd=GPIO_PULLUP
|
||||||
|
PC8.Locked=true
|
||||||
|
PC8.Signal=GPIO_Input
|
||||||
|
PC9.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||||
|
PC9.GPIO_Label=KEY_2
|
||||||
|
PC9.GPIO_PuPd=GPIO_PULLUP
|
||||||
|
PC9.Locked=true
|
||||||
|
PC9.Signal=GPIO_Input
|
||||||
|
PD0-OSC_IN.Mode=HSE-External-Oscillator
|
||||||
|
PD0-OSC_IN.Signal=RCC_OSC_IN
|
||||||
|
PD1-OSC_OUT.Mode=HSE-External-Oscillator
|
||||||
|
PD1-OSC_OUT.Signal=RCC_OSC_OUT
|
||||||
|
PD2.GPIOParameters=PinState,GPIO_Label
|
||||||
|
PD2.GPIO_Label=LED_B
|
||||||
|
PD2.Locked=true
|
||||||
|
PD2.PinState=GPIO_PIN_SET
|
||||||
|
PD2.Signal=GPIO_Output
|
||||||
|
PinOutPanel.RotationAngle=0
|
||||||
|
ProjectManager.AskForMigrate=true
|
||||||
|
ProjectManager.BackupPrevious=true
|
||||||
|
ProjectManager.CompilerLinker=GCC
|
||||||
|
ProjectManager.CompilerOptimize=6
|
||||||
|
ProjectManager.ComputerToolchain=false
|
||||||
|
ProjectManager.CoupleFile=true
|
||||||
|
ProjectManager.CustomerFirmwarePackage=
|
||||||
|
ProjectManager.DefaultFWLocation=true
|
||||||
|
ProjectManager.DeletePrevious=true
|
||||||
|
ProjectManager.DeviceId=STM32F103RCTx
|
||||||
|
ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.8.6
|
||||||
|
ProjectManager.FreePins=false
|
||||||
|
ProjectManager.HalAssertFull=false
|
||||||
|
ProjectManager.HeapSize=0x200
|
||||||
|
ProjectManager.KeepUserCode=true
|
||||||
|
ProjectManager.LastFirmware=true
|
||||||
|
ProjectManager.LibraryCopy=1
|
||||||
|
ProjectManager.MainLocation=Core/Src
|
||||||
|
ProjectManager.NoMain=false
|
||||||
|
ProjectManager.PreviousToolchain=
|
||||||
|
ProjectManager.ProjectBuild=false
|
||||||
|
ProjectManager.ProjectFileName=embedding.ioc
|
||||||
|
ProjectManager.ProjectName=embedding
|
||||||
|
ProjectManager.ProjectStructure=
|
||||||
|
ProjectManager.RegisterCallBack=
|
||||||
|
ProjectManager.StackSize=0x400
|
||||||
|
ProjectManager.TargetToolchain=CMake
|
||||||
|
ProjectManager.ToolChainLocation=
|
||||||
|
ProjectManager.UAScriptAfterPath=
|
||||||
|
ProjectManager.UAScriptBeforePath=
|
||||||
|
ProjectManager.UnderRoot=false
|
||||||
|
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true
|
||||||
|
RCC.ADCFreqValue=36000000
|
||||||
|
RCC.AHBFreq_Value=72000000
|
||||||
|
RCC.APB1CLKDivider=RCC_HCLK_DIV2
|
||||||
|
RCC.APB1Freq_Value=36000000
|
||||||
|
RCC.APB1TimFreq_Value=72000000
|
||||||
|
RCC.APB2Freq_Value=72000000
|
||||||
|
RCC.APB2TimFreq_Value=72000000
|
||||||
|
RCC.FCLKCortexFreq_Value=72000000
|
||||||
|
RCC.FamilyName=M
|
||||||
|
RCC.HCLKFreq_Value=72000000
|
||||||
|
RCC.I2S2Freq_Value=72000000
|
||||||
|
RCC.I2S3Freq_Value=72000000
|
||||||
|
RCC.IPParameters=ADCFreqValue,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,I2S2Freq_Value,I2S3Freq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,PLLSourceVirtual,SDIOFreq_Value,SDIOHCLKDiv2FreqValue,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USBFreq_Value,VCOOutput2Freq_Value
|
||||||
|
RCC.MCOFreq_Value=72000000
|
||||||
|
RCC.PLLCLKFreq_Value=72000000
|
||||||
|
RCC.PLLMCOFreq_Value=36000000
|
||||||
|
RCC.PLLMUL=RCC_PLL_MUL9
|
||||||
|
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
|
||||||
|
RCC.SDIOFreq_Value=72000000
|
||||||
|
RCC.SDIOHCLKDiv2FreqValue=36000000
|
||||||
|
RCC.SYSCLKFreq_VALUE=72000000
|
||||||
|
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
|
||||||
|
RCC.TimSysFreq_Value=72000000
|
||||||
|
RCC.USBFreq_Value=72000000
|
||||||
|
RCC.VCOOutput2Freq_Value=8000000
|
||||||
|
VP_SYS_VS_Systick.Mode=SysTick
|
||||||
|
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
|
||||||
|
board=custom
|
21
libs/SEGGER_RTT/CMakeLists.txt
Normal file
21
libs/SEGGER_RTT/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# SEGGER_RTT/CMakeLists.txt
|
||||||
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
|
# 创建静态库目标
|
||||||
|
add_library(SEGGER_RTT STATIC
|
||||||
|
RTT/SEGGER_RTT.c
|
||||||
|
RTT/SEGGER_RTT_printf.c
|
||||||
|
# 添加其他需要的源文件
|
||||||
|
)
|
||||||
|
|
||||||
|
# 设置库的包含目录
|
||||||
|
target_include_directories(SEGGER_RTT PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Config
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/RTT
|
||||||
|
)
|
||||||
|
|
||||||
|
# 设置库的属性(可选)
|
||||||
|
set_target_properties(SEGGER_RTT PROPERTIES
|
||||||
|
POSITION_INDEPENDENT_CODE ON
|
||||||
|
OUTPUT_NAME "segger_rtt"
|
||||||
|
)
|
440
libs/SEGGER_RTT/Config/SEGGER_RTT_Conf.h
Normal file
440
libs/SEGGER_RTT/Config/SEGGER_RTT_Conf.h
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
---------------------------END-OF-HEADER------------------------------
|
||||||
|
File : SEGGER_RTT_Conf.h
|
||||||
|
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||||
|
allows real-time communication on targets which support
|
||||||
|
debugger memory accesses while the CPU is running.
|
||||||
|
Revision: $Rev: 24316 $
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_CONF_H
|
||||||
|
#define SEGGER_RTT_CONF_H
|
||||||
|
|
||||||
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
|
#include <intrinsics.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Defines, configurable
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Take in and set to correct values for Cortex-A systems with CPU cache
|
||||||
|
//
|
||||||
|
//#define SEGGER_RTT_CPU_CACHE_LINE_SIZE (32) // Largest cache line size (in bytes) in the current system
|
||||||
|
//#define SEGGER_RTT_UNCACHED_OFF (0xFB000000) // Address alias where RTT CB and buffers can be accessed uncached
|
||||||
|
//
|
||||||
|
// Most common case:
|
||||||
|
// Up-channel 0: RTT
|
||||||
|
// Up-channel 1: SystemView
|
||||||
|
//
|
||||||
|
#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS
|
||||||
|
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// Most common case:
|
||||||
|
// Down-channel 0: RTT
|
||||||
|
// Down-channel 1: SystemView
|
||||||
|
//
|
||||||
|
#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
|
||||||
|
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUFFER_SIZE_UP
|
||||||
|
#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUFFER_SIZE_DOWN
|
||||||
|
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
|
||||||
|
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_MODE_DEFAULT
|
||||||
|
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT memcpy configuration
|
||||||
|
*
|
||||||
|
* memcpy() is good for large amounts of data,
|
||||||
|
* but the overhead is big for small amounts, which are usually stored via RTT.
|
||||||
|
* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead.
|
||||||
|
*
|
||||||
|
* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions.
|
||||||
|
* This is may be required with memory access restrictions,
|
||||||
|
* such as on Cortex-A devices with MMU.
|
||||||
|
*/
|
||||||
|
#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||||
|
#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets
|
||||||
|
//
|
||||||
|
//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__))
|
||||||
|
// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes))
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
|
||||||
|
// Otherwise we would probably end up with a mixed string in the buffer.
|
||||||
|
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
|
||||||
|
//
|
||||||
|
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
|
||||||
|
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
|
||||||
|
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
|
||||||
|
// (Higher priority = lower priority number)
|
||||||
|
// Default value for embOS: 128u
|
||||||
|
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||||
|
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
|
||||||
|
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
|
||||||
|
//
|
||||||
|
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||||
|
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for SEGGER Embedded Studio,
|
||||||
|
* Rowley CrossStudio and GCC
|
||||||
|
*/
|
||||||
|
#if ((defined(__SES_ARM) || defined(__SES_RISCV) || defined(__CROSSWORKS_ARM) || defined(__GNUC__) || defined(__clang__)) && !defined (__CC_ARM) && !defined(WIN32))
|
||||||
|
#if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
__asm volatile ("mrs %0, primask \n\t" \
|
||||||
|
"movs r1, #1 \n\t" \
|
||||||
|
"msr primask, r1 \n\t" \
|
||||||
|
: "=r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
: "r1", "cc" \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
|
||||||
|
: \
|
||||||
|
: "r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__))
|
||||||
|
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||||
|
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||||
|
#endif
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
__asm volatile ("mrs %0, basepri \n\t" \
|
||||||
|
"mov r1, %1 \n\t" \
|
||||||
|
"msr basepri, r1 \n\t" \
|
||||||
|
: "=r" (_SEGGER_RTT__LockState) \
|
||||||
|
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
|
||||||
|
: "r1", "cc" \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
|
||||||
|
: \
|
||||||
|
: "r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif (defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__))
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
__asm volatile ("mrs r1, CPSR \n\t" \
|
||||||
|
"mov %0, r1 \n\t" \
|
||||||
|
"orr r1, r1, #0xC0 \n\t" \
|
||||||
|
"msr CPSR_c, r1 \n\t" \
|
||||||
|
: "=r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
: "r1", "cc" \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
|
||||||
|
"mrs r1, CPSR \n\t" \
|
||||||
|
"bic r1, r1, #0xC0 \n\t" \
|
||||||
|
"and r0, r0, #0xC0 \n\t" \
|
||||||
|
"orr r1, r1, r0 \n\t" \
|
||||||
|
"msr CPSR_c, r1 \n\t" \
|
||||||
|
: \
|
||||||
|
: "r" (_SEGGER_RTT__LockState) \
|
||||||
|
: "r0", "r1", "cc" \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
#elif defined(__riscv) || defined(__riscv_xlen)
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
__asm volatile ("csrr %0, mstatus \n\t" \
|
||||||
|
"csrci mstatus, 8 \n\t" \
|
||||||
|
"andi %0, %0, 8 \n\t" \
|
||||||
|
: "=r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
: \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __asm volatile ("csrr a1, mstatus \n\t" \
|
||||||
|
"or %0, %0, a1 \n\t" \
|
||||||
|
"csrs mstatus, %0 \n\t" \
|
||||||
|
: \
|
||||||
|
: "r" (_SEGGER_RTT__LockState) \
|
||||||
|
: "a1" \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define SEGGER_RTT_LOCK()
|
||||||
|
#define SEGGER_RTT_UNLOCK()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for IAR EWARM
|
||||||
|
*/
|
||||||
|
#ifdef __ICCARM__
|
||||||
|
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) || \
|
||||||
|
(defined (__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__))
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = __get_PRIMASK(); \
|
||||||
|
__set_PRIMASK(1);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || \
|
||||||
|
(defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || \
|
||||||
|
(defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) || \
|
||||||
|
(defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__))
|
||||||
|
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||||
|
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||||
|
#endif
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = __get_BASEPRI(); \
|
||||||
|
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#elif (defined (__ARM7A__) && (__CORE__ == __ARM7A__)) || \
|
||||||
|
(defined (__ARM7R__) && (__CORE__ == __ARM7R__))
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
__asm volatile ("mrs r1, CPSR \n\t" \
|
||||||
|
"mov %0, r1 \n\t" \
|
||||||
|
"orr r1, r1, #0xC0 \n\t" \
|
||||||
|
"msr CPSR_c, r1 \n\t" \
|
||||||
|
: "=r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
: "r1", "cc" \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
|
||||||
|
"mrs r1, CPSR \n\t" \
|
||||||
|
"bic r1, r1, #0xC0 \n\t" \
|
||||||
|
"and r0, r0, #0xC0 \n\t" \
|
||||||
|
"orr r1, r1, r0 \n\t" \
|
||||||
|
"msr CPSR_c, r1 \n\t" \
|
||||||
|
: \
|
||||||
|
: "r" (_SEGGER_RTT__LockState) \
|
||||||
|
: "r0", "r1", "cc" \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for IAR RX
|
||||||
|
*/
|
||||||
|
#ifdef __ICCRX__
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned long _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = __get_interrupt_state(); \
|
||||||
|
__disable_interrupt();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for IAR RL78
|
||||||
|
*/
|
||||||
|
#ifdef __ICCRL78__
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
__istate_t _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = __get_interrupt_state(); \
|
||||||
|
__disable_interrupt();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for KEIL ARM
|
||||||
|
*/
|
||||||
|
#ifdef __CC_ARM
|
||||||
|
#if (defined __TARGET_ARCH_6S_M)
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
register unsigned char _SEGGER_RTT__PRIMASK __asm( "primask"); \
|
||||||
|
_SEGGER_RTT__LockState = _SEGGER_RTT__PRIMASK; \
|
||||||
|
_SEGGER_RTT__PRIMASK = 1u; \
|
||||||
|
__schedule_barrier();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() _SEGGER_RTT__PRIMASK = _SEGGER_RTT__LockState; \
|
||||||
|
__schedule_barrier(); \
|
||||||
|
}
|
||||||
|
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||||
|
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||||
|
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||||
|
#endif
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
register unsigned char BASEPRI __asm( "basepri"); \
|
||||||
|
_SEGGER_RTT__LockState = BASEPRI; \
|
||||||
|
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
|
||||||
|
__schedule_barrier();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() BASEPRI = _SEGGER_RTT__LockState; \
|
||||||
|
__schedule_barrier(); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for TI ARM
|
||||||
|
*/
|
||||||
|
#ifdef __TI_ARM__
|
||||||
|
#if defined (__TI_ARM_V6M0__)
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = __get_PRIMASK(); \
|
||||||
|
__set_PRIMASK(1);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
|
||||||
|
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||||
|
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||||
|
#endif
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = _set_interrupt_priority(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() _set_interrupt_priority(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for CCRX
|
||||||
|
*/
|
||||||
|
#ifdef __RX
|
||||||
|
#include <machine.h>
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned long _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = get_psw() & 0x010000; \
|
||||||
|
clrpsw_i();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() set_psw(get_psw() | _SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for embOS Simulation on Windows
|
||||||
|
* (Can also be used for generic RTT locking with embOS)
|
||||||
|
*/
|
||||||
|
#if defined(WIN32) || defined(SEGGER_RTT_LOCK_EMBOS)
|
||||||
|
|
||||||
|
void OS_SIM_EnterCriticalSection(void);
|
||||||
|
void OS_SIM_LeaveCriticalSection(void);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
OS_SIM_EnterCriticalSection();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() OS_SIM_LeaveCriticalSection(); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration fallback
|
||||||
|
*/
|
||||||
|
#ifndef SEGGER_RTT_LOCK
|
||||||
|
#define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_UNLOCK
|
||||||
|
#define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* If SEGGER_RTT_SECTION is defined but SEGGER_RTT_BUFFER_SECTION
|
||||||
|
* is not, use the same section for SEGGER_RTT_BUFFER_SECTION.
|
||||||
|
*/
|
||||||
|
#ifndef SEGGER_RTT_BUFFER_SECTION
|
||||||
|
#if defined(SEGGER_RTT_SECTION)
|
||||||
|
#define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*************************** End of file ****************************/
|
80
libs/SEGGER_RTT/Examples/Main_RTT_InputEchoApp.c
Normal file
80
libs/SEGGER_RTT/Examples/Main_RTT_InputEchoApp.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
--------- END-OF-HEADER --------------------------------------------
|
||||||
|
File : Main_RTT_MenuApp.c
|
||||||
|
Purpose : Sample application to demonstrate RTT bi-directional functionality
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAIN_C
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
|
|
||||||
|
volatile int _Cnt;
|
||||||
|
volatile int _Delay;
|
||||||
|
|
||||||
|
static char r;
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* main
|
||||||
|
*/
|
||||||
|
void main(void) {
|
||||||
|
|
||||||
|
SEGGER_RTT_WriteString(0, "SEGGER Real-Time-Terminal Sample\r\n");
|
||||||
|
SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
|
||||||
|
do {
|
||||||
|
r = SEGGER_RTT_WaitKey();
|
||||||
|
SEGGER_RTT_Write(0, &r, 1);
|
||||||
|
r++;
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** End of file ****************************/
|
108
libs/SEGGER_RTT/Examples/Main_RTT_MenuApp.c
Normal file
108
libs/SEGGER_RTT/Examples/Main_RTT_MenuApp.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
--------- END-OF-HEADER --------------------------------------------
|
||||||
|
File : Main_RTT_MenuApp.c
|
||||||
|
Purpose : Sample application to demonstrate RTT bi-directional functionality
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAIN_C
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
|
|
||||||
|
volatile int _Cnt;
|
||||||
|
volatile int _Delay;
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* main
|
||||||
|
*/
|
||||||
|
void main(void) {
|
||||||
|
int r;
|
||||||
|
int CancelOp;
|
||||||
|
|
||||||
|
do {
|
||||||
|
_Cnt = 0;
|
||||||
|
|
||||||
|
SEGGER_RTT_WriteString(0, "SEGGER Real-Time-Terminal Sample\r\n");
|
||||||
|
SEGGER_RTT_WriteString(0, "Press <1> to continue in blocking mode (Application waits if necessary, no data lost)\r\n");
|
||||||
|
SEGGER_RTT_WriteString(0, "Press <2> to continue in non-blocking mode (Application does not wait, data lost if fifo full)\r\n");
|
||||||
|
do {
|
||||||
|
r = SEGGER_RTT_WaitKey();
|
||||||
|
} while ((r != '1') && (r != '2'));
|
||||||
|
if (r == '1') {
|
||||||
|
SEGGER_RTT_WriteString(0, "\r\nSelected <1>. Configuring RTT and starting...\r\n");
|
||||||
|
SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
|
||||||
|
} else {
|
||||||
|
SEGGER_RTT_WriteString(0, "\r\nSelected <2>. Configuring RTT and starting...\r\n");
|
||||||
|
SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
|
||||||
|
}
|
||||||
|
CancelOp = 0;
|
||||||
|
do {
|
||||||
|
//for (_Delay = 0; _Delay < 10000; _Delay++);
|
||||||
|
SEGGER_RTT_printf(0, "Count: %d. Press <Space> to get back to menu.\r\n", _Cnt++);
|
||||||
|
r = SEGGER_RTT_HasKey();
|
||||||
|
if (r) {
|
||||||
|
CancelOp = (SEGGER_RTT_GetKey() == ' ') ? 1 : 0;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check if user selected to cancel the current operation
|
||||||
|
//
|
||||||
|
if (CancelOp) {
|
||||||
|
SEGGER_RTT_WriteString(0, "Operation cancelled, going back to menu...\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
SEGGER_RTT_GetKey();
|
||||||
|
SEGGER_RTT_WriteString(0, "\r\n");
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** End of file ****************************/
|
155
libs/SEGGER_RTT/Examples/Main_RTT_PrintfTest.c
Normal file
155
libs/SEGGER_RTT/Examples/Main_RTT_PrintfTest.c
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
--------- END-OF-HEADER --------------------------------------------
|
||||||
|
File : Main_RTT_MenuApp.c
|
||||||
|
Purpose : Sample application to demonstrate RTT bi-directional functionality
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAIN_C
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
|
|
||||||
|
volatile int _Cnt;
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* main
|
||||||
|
*/
|
||||||
|
void main(void) {
|
||||||
|
|
||||||
|
SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
|
||||||
|
|
||||||
|
SEGGER_RTT_WriteString(0, "SEGGER Real-Time-Terminal Sample\r\n\r\n");
|
||||||
|
SEGGER_RTT_WriteString(0, "###### Testing SEGGER_printf() ######\r\n");
|
||||||
|
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%c, 'S' : %c.\r\n", 'S');
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%5c, 'E' : %5c.\r\n", 'E');
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-5c, 'G' : %-5c.\r\n", 'G');
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%5.3c, 'G' : %-5c.\r\n", 'G');
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%.3c, 'E' : %-5c.\r\n", 'E');
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%c, 'R' : %c.\r\n", 'R');
|
||||||
|
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%s, \"RTT\" : %s.\r\n", "RTT");
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%s, \"RTT\\r\\nRocks.\" : %s.\r\n", "RTT\r\nRocks.");
|
||||||
|
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%u, 12345 : %u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%+u, 12345 : %+u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%.3u, 12345 : %.3u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%.6u, 12345 : %.6u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%6.3u, 12345 : %6.3u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%8.6u, 12345 : %8.6u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%08u, 12345 : %08u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%08.6u, 12345 : %08.6u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%0u, 12345 : %0u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-.6u, 12345 : %-.6u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-6.3u, 12345 : %-6.3u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-8.6u, 12345 : %-8.6u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-08u, 12345 : %-08u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-08.6u, 12345 : %-08.6u.\r\n", 12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-0u, 12345 : %-0u.\r\n", 12345);
|
||||||
|
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%u, -12345 : %u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%+u, -12345 : %+u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%.3u, -12345 : %.3u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%.6u, -12345 : %.6u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%6.3u, -12345 : %6.3u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%8.6u, -12345 : %8.6u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%08u, -12345 : %08u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%08.6u, -12345 : %08.6u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%0u, -12345 : %0u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-.6u, -12345 : %-.6u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-6.3u, -12345 : %-6.3u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-8.6u, -12345 : %-8.6u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-08u, -12345 : %-08u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-08.6u, -12345 : %-08.6u.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-0u, -12345 : %-0u.\r\n", -12345);
|
||||||
|
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%d, -12345 : %d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%+d, -12345 : %+d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%.3d, -12345 : %.3d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%.6d, -12345 : %.6d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%6.3d, -12345 : %6.3d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%8.6d, -12345 : %8.6d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%08d, -12345 : %08d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%08.6d, -12345 : %08.6d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%0d, -12345 : %0d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-.6d, -12345 : %-.6d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-6.3d, -12345 : %-6.3d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-8.6d, -12345 : %-8.6d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-08d, -12345 : %-08d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-08.6d, -12345 : %-08.6d.\r\n", -12345);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-0d, -12345 : %-0d.\r\n", -12345);
|
||||||
|
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%x, 0x1234ABC : %x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%+x, 0x1234ABC : %+x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%.3x, 0x1234ABC : %.3x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%.6x, 0x1234ABC : %.6x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%6.3x, 0x1234ABC : %6.3x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%8.6x, 0x1234ABC : %8.6x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%08x, 0x1234ABC : %08x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%08.6x, 0x1234ABC : %08.6x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%0x, 0x1234ABC : %0x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-.6x, 0x1234ABC : %-.6x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-6.3x, 0x1234ABC : %-6.3x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-8.6x, 0x1234ABC : %-8.6x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-08x, 0x1234ABC : %-08x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-08.6x, 0x1234ABC : %-08.6x.\r\n", 0x1234ABC);
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%-0x, 0x1234ABC : %-0x.\r\n", 0x1234ABC);
|
||||||
|
|
||||||
|
SEGGER_RTT_printf(0, "printf Test: %%p, &_Cnt : %p.\r\n", &_Cnt);
|
||||||
|
|
||||||
|
SEGGER_RTT_WriteString(0, "###### SEGGER_printf() Tests done. ######\r\n");
|
||||||
|
do {
|
||||||
|
_Cnt++;
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** End of file ****************************/
|
106
libs/SEGGER_RTT/Examples/Main_RTT_SpeedTestApp.c
Normal file
106
libs/SEGGER_RTT/Examples/Main_RTT_SpeedTestApp.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
--------- END-OF-HEADER --------------------------------------------
|
||||||
|
File : Main_RTT_SpeedTestApp.c
|
||||||
|
Purpose : Sample program for measuring RTT performance.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "RTOS.h"
|
||||||
|
#include "BSP.h"
|
||||||
|
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
OS_STACKPTR int StackHP[128], StackLP[128]; /* Task stacks */
|
||||||
|
OS_TASK TCBHP, TCBLP; /* Task-control-blocks */
|
||||||
|
|
||||||
|
static void HPTask(void) {
|
||||||
|
while (1) {
|
||||||
|
//
|
||||||
|
// Measure time needed for RTT output
|
||||||
|
// Perform dummy write with 0 characters, so we know the overhead of toggling LEDs and RTT in general
|
||||||
|
//
|
||||||
|
// Set BP here. Then start sampling on scope
|
||||||
|
BSP_ClrLED(0);
|
||||||
|
SEGGER_RTT_Write(0, 0, 0);
|
||||||
|
BSP_SetLED(0);
|
||||||
|
BSP_ClrLED(0);
|
||||||
|
SEGGER_RTT_Write(0, "01234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n", 82);
|
||||||
|
BSP_SetLED(0);
|
||||||
|
// Set BP here. Then stop sampling on scope
|
||||||
|
OS_Delay(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LPTask(void) {
|
||||||
|
while (1) {
|
||||||
|
BSP_ToggleLED(1);
|
||||||
|
OS_Delay (500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* main
|
||||||
|
*
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
OS_IncDI(); /* Initially disable interrupts */
|
||||||
|
OS_InitKern(); /* Initialize OS */
|
||||||
|
OS_InitHW(); /* Initialize Hardware for OS */
|
||||||
|
BSP_Init(); /* Initialize LED ports */
|
||||||
|
BSP_SetLED(0);
|
||||||
|
/* You need to create at least one task before calling OS_Start() */
|
||||||
|
OS_CREATETASK(&TCBHP, "HP Task", HPTask, 100, StackHP);
|
||||||
|
OS_CREATETASK(&TCBLP, "LP Task", LPTask, 50, StackLP);
|
||||||
|
OS_Start(); /* Start multitasking */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
36
libs/SEGGER_RTT/LICENSE.md
Normal file
36
libs/SEGGER_RTT/LICENSE.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
SEGGER Microcontroller GmbH
|
||||||
|
The Embedded Experts
|
||||||
|
|
||||||
|
(c) 1995 - 2021 SEGGER Microcontroller GmbH
|
||||||
|
www.segger.com Support: support@segger.com
|
||||||
|
|
||||||
|
SEGGER RTT Real Time Transfer for embedded targets
|
||||||
|
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
SEGGER strongly recommends to not make any changes
|
||||||
|
to or modify the source code of this software in order to stay
|
||||||
|
compatible with the RTT protocol and J-Link.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or
|
||||||
|
without modification, are permitted provided that the following
|
||||||
|
condition is met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this condition and the following disclaimer.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "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 SEGGER Microcontroller 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.
|
24
libs/SEGGER_RTT/README.md
Normal file
24
libs/SEGGER_RTT/README.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
RTT
|
||||||
|
===
|
||||||
|
|
||||||
|
SEGGER RTT Sources
|
||||||
|
|
||||||
|
https://www.segger.com/products/debug-probes/j-link/technology/about-real-time-transfer
|
||||||
|
https://wiki.segger.com/RTT
|
||||||
|
|
||||||
|
## Included files
|
||||||
|
|
||||||
|
* `RTT/`
|
||||||
|
* `SEGGER_RTT.c` - Main module for RTT.
|
||||||
|
* `SEGGER_RTT.h` - Main header for RTT.
|
||||||
|
* `SEGGER_RTT_ASM_ARMv7M.S` - Assembly-optimized implementation of RTT functions for ARMv7M processors.
|
||||||
|
* `SEGGER_RTT_Printf.c` - Simple implementation of printf (`SEGGER_RTT_Printf()`) to write formatted strings via RTT.
|
||||||
|
* `Syscalls/`
|
||||||
|
* `SEGGER_RTT_Syscalls_*.c` - Low-level syscalls to retarget `printf()` to RTT with different toolchains.
|
||||||
|
* `Config/`
|
||||||
|
* `SEGGER_RTT_Conf.h` - RTT configuration file.
|
||||||
|
* `Examples/`
|
||||||
|
* `Main_RTT_InputEchoApp.c` - Example application which echoes input on Channel 0.
|
||||||
|
* `Main_RTT_MenuApp.c` - Example application to demonstrate RTT bi-directional functionality.
|
||||||
|
* `Main_RTT_PrintfTest.c` - Example application to test RTT's simple printf implementation.
|
||||||
|
* `Main_RTT_SpeedTestApp.c` - Example application to measure RTT performance. (Requires embOS)
|
2093
libs/SEGGER_RTT/RTT/SEGGER_RTT.c
Normal file
2093
libs/SEGGER_RTT/RTT/SEGGER_RTT.c
Normal file
File diff suppressed because it is too large
Load Diff
520
libs/SEGGER_RTT/RTT/SEGGER_RTT.h
Normal file
520
libs/SEGGER_RTT/RTT/SEGGER_RTT.h
Normal file
@ -0,0 +1,520 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
---------------------------END-OF-HEADER------------------------------
|
||||||
|
File : SEGGER_RTT.h
|
||||||
|
Purpose : Implementation of SEGGER real-time transfer which allows
|
||||||
|
real-time communication on targets which support debugger
|
||||||
|
memory accesses while the CPU is running.
|
||||||
|
Revision: $Rev: 25842 $
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_H
|
||||||
|
#define SEGGER_RTT_H
|
||||||
|
|
||||||
|
#include "SEGGER_RTT_Conf.h"
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Defines, defaults
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RTT_USE_ASM
|
||||||
|
//
|
||||||
|
// Some cores support out-of-order memory accesses (reordering of memory accesses in the core)
|
||||||
|
// For such cores, we need to define a memory barrier to guarantee the order of certain accesses to the RTT ring buffers.
|
||||||
|
// Needed for:
|
||||||
|
// Cortex-M7 (ARMv7-M)
|
||||||
|
// Cortex-M23 (ARM-v8M)
|
||||||
|
// Cortex-M33 (ARM-v8M)
|
||||||
|
// Cortex-A/R (ARM-v7A/R)
|
||||||
|
//
|
||||||
|
// We do not explicitly check for "Embedded Studio" as the compiler in use determines what we support.
|
||||||
|
// You can use an external toolchain like IAR inside ES. So there is no point in checking for "Embedded Studio"
|
||||||
|
//
|
||||||
|
#if (defined __CROSSWORKS_ARM) // Rowley Crossworks
|
||||||
|
#define _CC_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#if (defined __ARM_ARCH_7M__) // Cortex-M3
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 0
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif (defined(__ARM_ARCH_8_1M_MAIN__)) // Cortex-M85
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#else
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 0
|
||||||
|
#endif
|
||||||
|
#elif (defined __ARMCC_VERSION)
|
||||||
|
//
|
||||||
|
// ARM compiler
|
||||||
|
// ARM compiler V6.0 and later is clang based.
|
||||||
|
// Our ASM part is compatible to clang.
|
||||||
|
//
|
||||||
|
#if (__ARMCC_VERSION >= 6000000)
|
||||||
|
#define _CC_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#else
|
||||||
|
#define _CC_HAS_RTT_ASM_SUPPORT 0
|
||||||
|
#endif
|
||||||
|
#if (defined __ARM_ARCH_6M__) // Cortex-M0 / M1
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 0 // No ASM support for this architecture
|
||||||
|
#elif (defined __ARM_ARCH_7M__) // Cortex-M3
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 0
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif (defined __ARM_ARCH_8_1M_MAIN__) // Cortex-M85
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif \
|
||||||
|
((defined __ARM_ARCH_7A__) || (defined __ARM_ARCH_7R__)) || \
|
||||||
|
((defined __ARM_ARCH_8A__) || (defined __ARM_ARCH_8R__))
|
||||||
|
//
|
||||||
|
// Cortex-A/R ARMv7-A/R & ARMv8-A/R
|
||||||
|
//
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#else
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 0
|
||||||
|
#endif
|
||||||
|
#elif ((defined __GNUC__) || (defined __clang__))
|
||||||
|
//
|
||||||
|
// GCC / Clang
|
||||||
|
//
|
||||||
|
#define _CC_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
// ARM 7/9: __ARM_ARCH_5__ / __ARM_ARCH_5E__ / __ARM_ARCH_5T__ / __ARM_ARCH_5T__ / __ARM_ARCH_5TE__
|
||||||
|
#if (defined __ARM_ARCH_7M__) // Cortex-M3
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#elif (defined __ARM_ARCH_7EM__) // Cortex-M4/M7
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1 // Only Cortex-M7 needs a DMB but we cannot distinguish M4 and M7 here...
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif (defined __ARM_ARCH_8M_BASE__) // Cortex-M23
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 0
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif (defined __ARM_ARCH_8M_MAIN__) // Cortex-M33
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif (defined __ARM_ARCH_8_1M_MAIN__) // Cortex-M85
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#elif \
|
||||||
|
(defined __ARM_ARCH_7A__) || (defined __ARM_ARCH_7R__) || \
|
||||||
|
(defined __ARM_ARCH_8A__) || (defined __ARM_ARCH_8R__)
|
||||||
|
//
|
||||||
|
// Cortex-A/R ARMv7-A/R & ARMv8-A/R
|
||||||
|
//
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() __asm volatile ("dmb\n" : : :);
|
||||||
|
#else
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 0
|
||||||
|
#endif
|
||||||
|
#elif ((defined __IASMARM__) || (defined __ICCARM__))
|
||||||
|
//
|
||||||
|
// IAR assembler/compiler
|
||||||
|
//
|
||||||
|
#define _CC_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#if (__VER__ < 6300000)
|
||||||
|
#define VOLATILE
|
||||||
|
#else
|
||||||
|
#define VOLATILE volatile
|
||||||
|
#endif
|
||||||
|
#if (defined __ARM7M__) // Needed for old versions that do not know the define yet
|
||||||
|
#if (__CORE__ == __ARM7M__) // Cortex-M3
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if (defined __ARM7EM__)
|
||||||
|
#if (__CORE__ == __ARM7EM__) // Cortex-M4/M7
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() asm VOLATILE ("DMB");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if (defined __ARM8M_BASELINE__)
|
||||||
|
#if (__CORE__ == __ARM8M_BASELINE__) // Cortex-M23
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 0
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() asm VOLATILE ("DMB");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if (defined __ARM8M_MAINLINE__)
|
||||||
|
#if (__CORE__ == __ARM8M_MAINLINE__) // Cortex-M33
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() asm VOLATILE ("DMB");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if (defined __ARM8EM_MAINLINE__)
|
||||||
|
#if (__CORE__ == __ARM8EM_MAINLINE__) // Cortex-???
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 1
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() asm VOLATILE ("DMB");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if\
|
||||||
|
((defined __ARM7A__) && (__CORE__ == __ARM7A__)) || \
|
||||||
|
((defined __ARM7R__) && (__CORE__ == __ARM7R__)) || \
|
||||||
|
((defined __ARM8A__) && (__CORE__ == __ARM8A__)) || \
|
||||||
|
((defined __ARM8R__) && (__CORE__ == __ARM8R__))
|
||||||
|
//
|
||||||
|
// Cortex-A/R ARMv7-A/R & ARMv8-A/R
|
||||||
|
//
|
||||||
|
#define _CORE_NEEDS_DMB 1
|
||||||
|
#define RTT__DMB() asm VOLATILE ("DMB");
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
//
|
||||||
|
// Other compilers
|
||||||
|
//
|
||||||
|
#define _CC_HAS_RTT_ASM_SUPPORT 0
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 0
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// If IDE and core support the ASM version, enable ASM version by default
|
||||||
|
//
|
||||||
|
#ifndef _CORE_HAS_RTT_ASM_SUPPORT
|
||||||
|
#define _CORE_HAS_RTT_ASM_SUPPORT 0 // Default for unknown cores
|
||||||
|
#endif
|
||||||
|
#if (_CC_HAS_RTT_ASM_SUPPORT && _CORE_HAS_RTT_ASM_SUPPORT)
|
||||||
|
#define RTT_USE_ASM (1)
|
||||||
|
#else
|
||||||
|
#define RTT_USE_ASM (0)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _CORE_NEEDS_DMB
|
||||||
|
#define _CORE_NEEDS_DMB 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RTT__DMB
|
||||||
|
#if _CORE_NEEDS_DMB
|
||||||
|
#error "Don't know how to place inline assembly for DMB"
|
||||||
|
#else
|
||||||
|
#define RTT__DMB()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_CPU_CACHE_LINE_SIZE
|
||||||
|
#define SEGGER_RTT_CPU_CACHE_LINE_SIZE (0) // On most target systems where RTT is used, we do not have a CPU cache, therefore 0 is a good default here
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_UNCACHED_OFF
|
||||||
|
#if SEGGER_RTT_CPU_CACHE_LINE_SIZE
|
||||||
|
#error "SEGGER_RTT_UNCACHED_OFF must be defined when setting SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
|
||||||
|
#else
|
||||||
|
#define SEGGER_RTT_UNCACHED_OFF (0)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if RTT_USE_ASM
|
||||||
|
#if SEGGER_RTT_CPU_CACHE_LINE_SIZE
|
||||||
|
#error "RTT_USE_ASM is not available if SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_ASM // defined when SEGGER_RTT.h is included from assembly file
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Defines, fixed
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine how much we must pad the control block to make it a multiple of a cache line in size
|
||||||
|
// Assuming: U8 = 1B
|
||||||
|
// U16 = 2B
|
||||||
|
// U32 = 4B
|
||||||
|
// U8/U16/U32* = 4B
|
||||||
|
//
|
||||||
|
#if SEGGER_RTT_CPU_CACHE_LINE_SIZE // Avoid division by zero in case we do not have any cache
|
||||||
|
#define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (((NumBytes + SEGGER_RTT_CPU_CACHE_LINE_SIZE - 1) / SEGGER_RTT_CPU_CACHE_LINE_SIZE) * SEGGER_RTT_CPU_CACHE_LINE_SIZE)
|
||||||
|
#else
|
||||||
|
#define SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(NumBytes) (NumBytes)
|
||||||
|
#endif
|
||||||
|
#define SEGGER_RTT__CB_SIZE (16 + 4 + 4 + (SEGGER_RTT_MAX_NUM_UP_BUFFERS * 24) + (SEGGER_RTT_MAX_NUM_DOWN_BUFFERS * 24))
|
||||||
|
#define SEGGER_RTT__CB_PADDING (SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(SEGGER_RTT__CB_SIZE) - SEGGER_RTT__CB_SIZE)
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Types
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Description for a circular buffer (also called "ring buffer")
|
||||||
|
// which is used as up-buffer (T->H)
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
|
||||||
|
char* pBuffer; // Pointer to start of buffer
|
||||||
|
unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
|
||||||
|
unsigned WrOff; // Position of next item to be written by either target.
|
||||||
|
volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host.
|
||||||
|
unsigned Flags; // Contains configuration flags. Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
|
||||||
|
} SEGGER_RTT_BUFFER_UP;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Description for a circular buffer (also called "ring buffer")
|
||||||
|
// which is used as down-buffer (H->T)
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4"
|
||||||
|
char* pBuffer; // Pointer to start of buffer
|
||||||
|
unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty.
|
||||||
|
volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host.
|
||||||
|
unsigned RdOff; // Position of next item to be read by target (down-buffer).
|
||||||
|
unsigned Flags; // Contains configuration flags. Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
|
||||||
|
} SEGGER_RTT_BUFFER_DOWN;
|
||||||
|
|
||||||
|
//
|
||||||
|
// RTT control block which describes the number of buffers available
|
||||||
|
// as well as the configuration for each buffer
|
||||||
|
//
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
char acID[16]; // Initialized to "SEGGER RTT"
|
||||||
|
int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2)
|
||||||
|
int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2)
|
||||||
|
SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host
|
||||||
|
SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target
|
||||||
|
#if SEGGER_RTT__CB_PADDING
|
||||||
|
unsigned char aDummy[SEGGER_RTT__CB_PADDING];
|
||||||
|
#endif
|
||||||
|
} SEGGER_RTT_CB;
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Global data
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
extern SEGGER_RTT_CB _SEGGER_RTT;
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT API functions
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
|
||||||
|
int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
|
||||||
|
int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
|
||||||
|
int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags);
|
||||||
|
int SEGGER_RTT_GetKey (void);
|
||||||
|
unsigned SEGGER_RTT_HasData (unsigned BufferIndex);
|
||||||
|
int SEGGER_RTT_HasKey (void);
|
||||||
|
unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex);
|
||||||
|
void SEGGER_RTT_Init (void);
|
||||||
|
unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
|
||||||
|
unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
|
||||||
|
int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName);
|
||||||
|
int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName);
|
||||||
|
int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags);
|
||||||
|
int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags);
|
||||||
|
int SEGGER_RTT_WaitKey (void);
|
||||||
|
unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||||
|
unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||||
|
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||||
|
unsigned SEGGER_RTT_ASM_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||||
|
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
|
||||||
|
void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||||
|
unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c);
|
||||||
|
unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c);
|
||||||
|
unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c);
|
||||||
|
unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex);
|
||||||
|
unsigned SEGGER_RTT_GetBytesInBuffer (unsigned BufferIndex);
|
||||||
|
//
|
||||||
|
// Function macro for performance optimization
|
||||||
|
//
|
||||||
|
#define SEGGER_RTT_HASDATA(n) (((SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_DOWN*)((uintptr_t)&_SEGGER_RTT.aDown[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff)
|
||||||
|
|
||||||
|
#if RTT_USE_ASM
|
||||||
|
#define SEGGER_RTT_WriteSkipNoLock SEGGER_RTT_ASM_WriteSkipNoLock
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT transfer functions to send RTT data via other channels.
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
unsigned SEGGER_RTT_ReadUpBuffer (unsigned BufferIndex, void* pBuffer, unsigned BufferSize);
|
||||||
|
unsigned SEGGER_RTT_ReadUpBufferNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize);
|
||||||
|
unsigned SEGGER_RTT_WriteDownBuffer (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||||
|
unsigned SEGGER_RTT_WriteDownBufferNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_HASDATA_UP(n) (((SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->WrOff - ((SEGGER_RTT_BUFFER_UP*)((uintptr_t)&_SEGGER_RTT.aUp[n] + SEGGER_RTT_UNCACHED_OFF))->RdOff) // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT "Terminal" API functions
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
int SEGGER_RTT_SetTerminal (unsigned char TerminalId);
|
||||||
|
int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s);
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT printf functions (require SEGGER_RTT_printf.c)
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
|
||||||
|
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // ifndef(SEGGER_RTT_ASM)
|
||||||
|
|
||||||
|
//
|
||||||
|
// For some environments, NULL may not be defined until certain headers are included
|
||||||
|
//
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void*)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Defines
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Operating modes. Define behavior if buffer is full (not enough space for entire message)
|
||||||
|
//
|
||||||
|
#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0) // Skip. Do not block, output nothing. (Default)
|
||||||
|
#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1) // Trim: Do not block, output as much as fits.
|
||||||
|
#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2) // Block: Wait until there is space in the buffer.
|
||||||
|
#define SEGGER_RTT_MODE_MASK (3)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Control sequences, based on ANSI.
|
||||||
|
// Can be used to control color, and clear the screen
|
||||||
|
//
|
||||||
|
#define RTT_CTRL_RESET "\x1B[0m" // Reset to default colors
|
||||||
|
#define RTT_CTRL_CLEAR "\x1B[2J" // Clear screen, reposition cursor to top left
|
||||||
|
|
||||||
|
#define RTT_CTRL_TEXT_BLACK "\x1B[2;30m"
|
||||||
|
#define RTT_CTRL_TEXT_RED "\x1B[2;31m"
|
||||||
|
#define RTT_CTRL_TEXT_GREEN "\x1B[2;32m"
|
||||||
|
#define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m"
|
||||||
|
#define RTT_CTRL_TEXT_BLUE "\x1B[2;34m"
|
||||||
|
#define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m"
|
||||||
|
#define RTT_CTRL_TEXT_CYAN "\x1B[2;36m"
|
||||||
|
#define RTT_CTRL_TEXT_WHITE "\x1B[2;37m"
|
||||||
|
|
||||||
|
#define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m"
|
||||||
|
#define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m"
|
||||||
|
#define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m"
|
||||||
|
#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m"
|
||||||
|
#define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m"
|
||||||
|
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m"
|
||||||
|
#define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m"
|
||||||
|
#define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m"
|
||||||
|
|
||||||
|
#define RTT_CTRL_BG_BLACK "\x1B[24;40m"
|
||||||
|
#define RTT_CTRL_BG_RED "\x1B[24;41m"
|
||||||
|
#define RTT_CTRL_BG_GREEN "\x1B[24;42m"
|
||||||
|
#define RTT_CTRL_BG_YELLOW "\x1B[24;43m"
|
||||||
|
#define RTT_CTRL_BG_BLUE "\x1B[24;44m"
|
||||||
|
#define RTT_CTRL_BG_MAGENTA "\x1B[24;45m"
|
||||||
|
#define RTT_CTRL_BG_CYAN "\x1B[24;46m"
|
||||||
|
#define RTT_CTRL_BG_WHITE "\x1B[24;47m"
|
||||||
|
|
||||||
|
#define RTT_CTRL_BG_BRIGHT_BLACK "\x1B[4;40m"
|
||||||
|
#define RTT_CTRL_BG_BRIGHT_RED "\x1B[4;41m"
|
||||||
|
#define RTT_CTRL_BG_BRIGHT_GREEN "\x1B[4;42m"
|
||||||
|
#define RTT_CTRL_BG_BRIGHT_YELLOW "\x1B[4;43m"
|
||||||
|
#define RTT_CTRL_BG_BRIGHT_BLUE "\x1B[4;44m"
|
||||||
|
#define RTT_CTRL_BG_BRIGHT_MAGENTA "\x1B[4;45m"
|
||||||
|
#define RTT_CTRL_BG_BRIGHT_CYAN "\x1B[4;46m"
|
||||||
|
#define RTT_CTRL_BG_BRIGHT_WHITE "\x1B[4;47m"
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************************** End of file ****************************/
|
242
libs/SEGGER_RTT/RTT/SEGGER_RTT_ASM_ARMv7M.S
Normal file
242
libs/SEGGER_RTT/RTT/SEGGER_RTT_ASM_ARMv7M.S
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* (c) SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
* www.segger.com *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
-------------------------- END-OF-HEADER -----------------------------
|
||||||
|
|
||||||
|
File : SEGGER_RTT_ASM_ARMv7M.S
|
||||||
|
Purpose : Assembler implementation of RTT functions for ARMv7M
|
||||||
|
|
||||||
|
Additional information:
|
||||||
|
This module is written to be assembler-independent and works with
|
||||||
|
GCC and clang (Embedded Studio) and IAR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SEGGER_RTT_ASM // Used to control processed input from header file
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Defines, fixed
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _CCIAR 0
|
||||||
|
#define _CCCLANG 1
|
||||||
|
|
||||||
|
#if (defined __SES_ARM) || (defined __GNUC__) || (defined __clang__)
|
||||||
|
#define _CC_TYPE _CCCLANG
|
||||||
|
#define _PUB_SYM .global
|
||||||
|
#define _EXT_SYM .extern
|
||||||
|
#define _END .end
|
||||||
|
#define _WEAK .weak
|
||||||
|
#define _THUMB_FUNC .thumb_func
|
||||||
|
#define _THUMB_CODE .code 16
|
||||||
|
#define _WORD .word
|
||||||
|
#define _SECTION(Sect, Type, AlignExp) .section Sect ##, "ax"
|
||||||
|
#define _ALIGN(Exp) .align Exp
|
||||||
|
#define _PLACE_LITS .ltorg
|
||||||
|
#define _DATA_SECT_START
|
||||||
|
#define _C_STARTUP _start
|
||||||
|
#define _STACK_END __stack_end__
|
||||||
|
#define _RAMFUNC
|
||||||
|
//
|
||||||
|
// .text => Link to flash
|
||||||
|
// .fast => Link to RAM
|
||||||
|
// OtherSect => Usually link to RAM
|
||||||
|
// Alignment is 2^x
|
||||||
|
//
|
||||||
|
#elif defined (__IASMARM__)
|
||||||
|
#define _CC_TYPE _CCIAR
|
||||||
|
#define _PUB_SYM PUBLIC
|
||||||
|
#define _EXT_SYM EXTERN
|
||||||
|
#define _END END
|
||||||
|
#define _WEAK _WEAK
|
||||||
|
#define _THUMB_FUNC
|
||||||
|
#define _THUMB_CODE THUMB
|
||||||
|
#define _WORD DCD
|
||||||
|
#define _SECTION(Sect, Type, AlignExp) SECTION Sect ## : ## Type ## :REORDER:NOROOT ## (AlignExp)
|
||||||
|
#define _ALIGN(Exp) alignrom Exp
|
||||||
|
#define _PLACE_LITS
|
||||||
|
#define _DATA_SECT_START DATA
|
||||||
|
#define _C_STARTUP __iar_program_start
|
||||||
|
#define _STACK_END sfe(CSTACK)
|
||||||
|
#define _RAMFUNC SECTION_TYPE SHT_PROGBITS, SHF_WRITE | SHF_EXECINSTR
|
||||||
|
//
|
||||||
|
// .text => Link to flash
|
||||||
|
// .textrw => Link to RAM
|
||||||
|
// OtherSect => Usually link to RAM
|
||||||
|
// NOROOT => Allows linker to throw away the function, if not referenced
|
||||||
|
// Alignment is 2^x
|
||||||
|
//
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (_CC_TYPE == _CCIAR)
|
||||||
|
NAME SEGGER_RTT_ASM_ARMv7M
|
||||||
|
#else
|
||||||
|
.syntax unified
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (RTT_USE_ASM) && (RTT_USE_ASM == 1)
|
||||||
|
#define SHT_PROGBITS 0x1
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Public / external symbols
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
_EXT_SYM __aeabi_memcpy
|
||||||
|
_EXT_SYM __aeabi_memcpy4
|
||||||
|
_EXT_SYM _SEGGER_RTT
|
||||||
|
|
||||||
|
_PUB_SYM SEGGER_RTT_ASM_WriteSkipNoLock
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* SEGGER_RTT_WriteSkipNoLock
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* Stores a specified number of characters in SEGGER RTT
|
||||||
|
* control block which is then read by the host.
|
||||||
|
* SEGGER_RTT_WriteSkipNoLock does not lock the application and
|
||||||
|
* skips all data, if the data does not fit into the buffer.
|
||||||
|
*
|
||||||
|
* Parameters
|
||||||
|
* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
|
||||||
|
* pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
|
||||||
|
* NumBytes Number of bytes to be stored in the SEGGER RTT control block.
|
||||||
|
* MUST be > 0!!!
|
||||||
|
* This is done for performance reasons, so no initial check has do be done.
|
||||||
|
*
|
||||||
|
* Return value
|
||||||
|
* 1: Data has been copied
|
||||||
|
* 0: No space, data has not been copied
|
||||||
|
*
|
||||||
|
* Notes
|
||||||
|
* (1) If there is not enough space in the "Up"-buffer, all data is dropped.
|
||||||
|
* (2) For performance reasons this function does not call Init()
|
||||||
|
* and may only be called after RTT has been initialized.
|
||||||
|
* Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
|
||||||
|
*/
|
||||||
|
_SECTION(.text, CODE, 2)
|
||||||
|
_ALIGN(2)
|
||||||
|
_THUMB_FUNC
|
||||||
|
SEGGER_RTT_ASM_WriteSkipNoLock: // unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pData, unsigned NumBytes) {
|
||||||
|
//
|
||||||
|
// Cases:
|
||||||
|
// 1) RdOff <= WrOff => Space until wrap-around is sufficient
|
||||||
|
// 2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks)
|
||||||
|
// 3) RdOff < WrOff => No space in buf
|
||||||
|
// 4) RdOff > WrOff => Space is sufficient
|
||||||
|
// 5) RdOff > WrOff => No space in buf
|
||||||
|
//
|
||||||
|
// 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough
|
||||||
|
//
|
||||||
|
// Register usage:
|
||||||
|
// R0 Temporary needed as RdOff, <Tmp> register later on
|
||||||
|
// R1 pData
|
||||||
|
// R2 <NumBytes>
|
||||||
|
// R3 <Tmp> register. Hold free for subroutine calls
|
||||||
|
// R4 <Rem>
|
||||||
|
// R5 pRing->pBuffer
|
||||||
|
// R6 pRing (Points to active struct SEGGER_RTT_BUFFER_DOWN)
|
||||||
|
// R7 WrOff
|
||||||
|
//
|
||||||
|
PUSH {R4-R7}
|
||||||
|
ADD R3,R0,R0, LSL #+1
|
||||||
|
LDR.W R0,=_SEGGER_RTT // pRing = &_SEGGER_RTT.aUp[BufferIndex];
|
||||||
|
ADD R0,R0,R3, LSL #+3
|
||||||
|
ADD R6,R0,#+24
|
||||||
|
LDR R0,[R6, #+16] // RdOff = pRing->RdOff;
|
||||||
|
LDR R7,[R6, #+12] // WrOff = pRing->WrOff;
|
||||||
|
LDR R5,[R6, #+4] // pRing->pBuffer
|
||||||
|
CMP R7,R0
|
||||||
|
BCC.N _CheckCase4 // if (RdOff <= WrOff) { => Case 1), 2) or 3)
|
||||||
|
//
|
||||||
|
// Handling for case 1, later on identical to case 4
|
||||||
|
//
|
||||||
|
LDR R3,[R6, #+8] // Avail = pRing->SizeOfBuffer - WrOff - 1u; => Space until wrap-around (assume 1 byte not usable for case that RdOff == 0)
|
||||||
|
SUBS R4,R3,R7 // <Rem> (Used in case we jump into case 2 afterwards)
|
||||||
|
SUBS R3,R4,#+1 // <Avail>
|
||||||
|
CMP R3,R2
|
||||||
|
BCC.N _CheckCase2 // if (Avail >= NumBytes) { => Case 1)?
|
||||||
|
_Case4:
|
||||||
|
ADDS R5,R7,R5 // pBuffer += WrOff
|
||||||
|
ADDS R0,R2,R7 // v = WrOff + NumBytes
|
||||||
|
//
|
||||||
|
// 2x unrolling for the copy loop that is used most of the time
|
||||||
|
// This is a special optimization for small SystemView packets and makes them even faster
|
||||||
|
//
|
||||||
|
_ALIGN(2)
|
||||||
|
_LoopCopyStraight: // memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
|
||||||
|
LDRB R3,[R1], #+1
|
||||||
|
STRB R3,[R5], #+1 // *pDest++ = *pSrc++
|
||||||
|
SUBS R2,R2,#+1
|
||||||
|
BEQ _CSDone
|
||||||
|
LDRB R3,[R1], #+1
|
||||||
|
STRB R3,[R5], #+1 // *pDest++ = *pSrc++
|
||||||
|
SUBS R2,R2,#+1
|
||||||
|
BNE _LoopCopyStraight
|
||||||
|
_CSDone:
|
||||||
|
#if _CORE_NEEDS_DMB // Do not slow down cores that do not need a DMB instruction here
|
||||||
|
DMB // Cortex-M7 may delay memory writes and also change the order in which the writes happen. Therefore, make sure that all buffer writes are finished, before updating the <WrOff> in the struct
|
||||||
|
#endif
|
||||||
|
STR R0,[R6, #+12] // pRing->WrOff = WrOff + NumBytes;
|
||||||
|
MOVS R0,#+1
|
||||||
|
POP {R4-R7}
|
||||||
|
BX LR // Return 1
|
||||||
|
_CheckCase2:
|
||||||
|
ADDS R0,R0,R3 // Avail += RdOff; => Space incl. wrap-around
|
||||||
|
CMP R0,R2
|
||||||
|
BCC.N _Case3 // if (Avail >= NumBytes) { => Case 2? => If not, we have case 3) (does not fit)
|
||||||
|
//
|
||||||
|
// Handling for case 2
|
||||||
|
//
|
||||||
|
ADDS R0,R7,R5 // v = pRing->pBuffer + WrOff => Do not change pRing->pBuffer here because 2nd chunk needs org. value
|
||||||
|
SUBS R2,R2,R4 // NumBytes -= Rem; (Rem = pRing->SizeOfBuffer - WrOff; => Space until end of buffer)
|
||||||
|
_LoopCopyBeforeWrapAround: // memcpy(pRing->pBuffer + WrOff, pData, Rem); => Copy 1st chunk
|
||||||
|
LDRB R3,[R1], #+1
|
||||||
|
STRB R3,[R0], #+1 // *pDest++ = *pSrc++
|
||||||
|
SUBS R4,R4,#+1
|
||||||
|
BNE _LoopCopyBeforeWrapAround
|
||||||
|
//
|
||||||
|
// Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used
|
||||||
|
// But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element
|
||||||
|
// In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks
|
||||||
|
// Therefore, check if 2nd memcpy is necessary at all
|
||||||
|
//
|
||||||
|
ADDS R4,R2,#+0 // Save <NumBytes> (needed as counter in loop but must be written to <WrOff> after the loop). Also use this inst to update the flags to skip 2nd loop if possible
|
||||||
|
BEQ.N _No2ChunkNeeded // if (NumBytes) {
|
||||||
|
_LoopCopyAfterWrapAround: // memcpy(pRing->pBuffer, pData + Rem, NumBytes);
|
||||||
|
LDRB R3,[R1], #+1 // pData already points to the next src byte due to copy loop increment before this loop
|
||||||
|
STRB R3,[R5], #+1 // *pDest++ = *pSrc++
|
||||||
|
SUBS R2,R2,#+1
|
||||||
|
BNE _LoopCopyAfterWrapAround
|
||||||
|
_No2ChunkNeeded:
|
||||||
|
#if _CORE_NEEDS_DMB // Do not slow down cores that do not need a DMB instruction here
|
||||||
|
DMB // Cortex-M7 may delay memory writes and also change the order in which the writes happen. Therefore, make sure that all buffer writes are finished, before updating the <WrOff> in the struct
|
||||||
|
#endif
|
||||||
|
STR R4,[R6, #+12] // pRing->WrOff = NumBytes; => Must be written after copying data because J-Link may read control block asynchronously while writing into buffer
|
||||||
|
MOVS R0,#+1
|
||||||
|
POP {R4-R7}
|
||||||
|
BX LR // Return 1
|
||||||
|
_CheckCase4:
|
||||||
|
SUBS R0,R0,R7
|
||||||
|
SUBS R0,R0,#+1 // Avail = RdOff - WrOff - 1u;
|
||||||
|
CMP R0,R2
|
||||||
|
BCS.N _Case4 // if (Avail >= NumBytes) { => Case 4) == 1) ? => If not, we have case 5) == 3) (does not fit)
|
||||||
|
_Case3:
|
||||||
|
MOVS R0,#+0
|
||||||
|
POP {R4-R7}
|
||||||
|
BX LR // Return 0
|
||||||
|
_PLACE_LITS
|
||||||
|
|
||||||
|
#endif // defined (RTT_USE_ASM) && (RTT_USE_ASM == 1)
|
||||||
|
_END
|
||||||
|
|
||||||
|
/*************************** End of file ****************************/
|
440
libs/SEGGER_RTT/RTT/SEGGER_RTT_Conf.h
Normal file
440
libs/SEGGER_RTT/RTT/SEGGER_RTT_Conf.h
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
---------------------------END-OF-HEADER------------------------------
|
||||||
|
File : SEGGER_RTT_Conf.h
|
||||||
|
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||||
|
allows real-time communication on targets which support
|
||||||
|
debugger memory accesses while the CPU is running.
|
||||||
|
Revision: $Rev: 24316 $
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_CONF_H
|
||||||
|
#define SEGGER_RTT_CONF_H
|
||||||
|
|
||||||
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
|
#include <intrinsics.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Defines, configurable
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Take in and set to correct values for Cortex-A systems with CPU cache
|
||||||
|
//
|
||||||
|
//#define SEGGER_RTT_CPU_CACHE_LINE_SIZE (32) // Largest cache line size (in bytes) in the current system
|
||||||
|
//#define SEGGER_RTT_UNCACHED_OFF (0xFB000000) // Address alias where RTT CB and buffers can be accessed uncached
|
||||||
|
//
|
||||||
|
// Most common case:
|
||||||
|
// Up-channel 0: RTT
|
||||||
|
// Up-channel 1: SystemView
|
||||||
|
//
|
||||||
|
#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS
|
||||||
|
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// Most common case:
|
||||||
|
// Down-channel 0: RTT
|
||||||
|
// Down-channel 1: SystemView
|
||||||
|
//
|
||||||
|
#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
|
||||||
|
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUFFER_SIZE_UP
|
||||||
|
#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUFFER_SIZE_DOWN
|
||||||
|
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
|
||||||
|
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_MODE_DEFAULT
|
||||||
|
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT memcpy configuration
|
||||||
|
*
|
||||||
|
* memcpy() is good for large amounts of data,
|
||||||
|
* but the overhead is big for small amounts, which are usually stored via RTT.
|
||||||
|
* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead.
|
||||||
|
*
|
||||||
|
* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions.
|
||||||
|
* This is may be required with memory access restrictions,
|
||||||
|
* such as on Cortex-A devices with MMU.
|
||||||
|
*/
|
||||||
|
#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP
|
||||||
|
#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets
|
||||||
|
//
|
||||||
|
//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__))
|
||||||
|
// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes))
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
|
||||||
|
// Otherwise we would probably end up with a mixed string in the buffer.
|
||||||
|
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
|
||||||
|
//
|
||||||
|
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
|
||||||
|
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
|
||||||
|
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
|
||||||
|
// (Higher priority = lower priority number)
|
||||||
|
// Default value for embOS: 128u
|
||||||
|
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||||
|
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
|
||||||
|
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
|
||||||
|
//
|
||||||
|
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||||
|
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for SEGGER Embedded Studio,
|
||||||
|
* Rowley CrossStudio and GCC
|
||||||
|
*/
|
||||||
|
#if ((defined(__SES_ARM) || defined(__SES_RISCV) || defined(__CROSSWORKS_ARM) || defined(__GNUC__) || defined(__clang__)) && !defined (__CC_ARM) && !defined(WIN32))
|
||||||
|
#if (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
__asm volatile ("mrs %0, primask \n\t" \
|
||||||
|
"movs r1, #1 \n\t" \
|
||||||
|
"msr primask, r1 \n\t" \
|
||||||
|
: "=r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
: "r1", "cc" \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
|
||||||
|
: \
|
||||||
|
: "r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__))
|
||||||
|
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||||
|
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||||
|
#endif
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
__asm volatile ("mrs %0, basepri \n\t" \
|
||||||
|
"mov r1, %1 \n\t" \
|
||||||
|
"msr basepri, r1 \n\t" \
|
||||||
|
: "=r" (_SEGGER_RTT__LockState) \
|
||||||
|
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
|
||||||
|
: "r1", "cc" \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
|
||||||
|
: \
|
||||||
|
: "r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif (defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__))
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
__asm volatile ("mrs r1, CPSR \n\t" \
|
||||||
|
"mov %0, r1 \n\t" \
|
||||||
|
"orr r1, r1, #0xC0 \n\t" \
|
||||||
|
"msr CPSR_c, r1 \n\t" \
|
||||||
|
: "=r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
: "r1", "cc" \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
|
||||||
|
"mrs r1, CPSR \n\t" \
|
||||||
|
"bic r1, r1, #0xC0 \n\t" \
|
||||||
|
"and r0, r0, #0xC0 \n\t" \
|
||||||
|
"orr r1, r1, r0 \n\t" \
|
||||||
|
"msr CPSR_c, r1 \n\t" \
|
||||||
|
: \
|
||||||
|
: "r" (_SEGGER_RTT__LockState) \
|
||||||
|
: "r0", "r1", "cc" \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
#elif defined(__riscv) || defined(__riscv_xlen)
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
__asm volatile ("csrr %0, mstatus \n\t" \
|
||||||
|
"csrci mstatus, 8 \n\t" \
|
||||||
|
"andi %0, %0, 8 \n\t" \
|
||||||
|
: "=r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
: \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __asm volatile ("csrr a1, mstatus \n\t" \
|
||||||
|
"or %0, %0, a1 \n\t" \
|
||||||
|
"csrs mstatus, %0 \n\t" \
|
||||||
|
: \
|
||||||
|
: "r" (_SEGGER_RTT__LockState) \
|
||||||
|
: "a1" \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define SEGGER_RTT_LOCK()
|
||||||
|
#define SEGGER_RTT_UNLOCK()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for IAR EWARM
|
||||||
|
*/
|
||||||
|
#ifdef __ICCARM__
|
||||||
|
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) || \
|
||||||
|
(defined (__ARM8M_BASELINE__) && (__CORE__ == __ARM8M_BASELINE__))
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = __get_PRIMASK(); \
|
||||||
|
__set_PRIMASK(1);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || \
|
||||||
|
(defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || \
|
||||||
|
(defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__)) || \
|
||||||
|
(defined (__ARM8M_MAINLINE__) && (__CORE__ == __ARM8M_MAINLINE__))
|
||||||
|
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||||
|
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||||
|
#endif
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = __get_BASEPRI(); \
|
||||||
|
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#elif (defined (__ARM7A__) && (__CORE__ == __ARM7A__)) || \
|
||||||
|
(defined (__ARM7R__) && (__CORE__ == __ARM7R__))
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
__asm volatile ("mrs r1, CPSR \n\t" \
|
||||||
|
"mov %0, r1 \n\t" \
|
||||||
|
"orr r1, r1, #0xC0 \n\t" \
|
||||||
|
"msr CPSR_c, r1 \n\t" \
|
||||||
|
: "=r" (_SEGGER_RTT__LockState) \
|
||||||
|
: \
|
||||||
|
: "r1", "cc" \
|
||||||
|
);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
|
||||||
|
"mrs r1, CPSR \n\t" \
|
||||||
|
"bic r1, r1, #0xC0 \n\t" \
|
||||||
|
"and r0, r0, #0xC0 \n\t" \
|
||||||
|
"orr r1, r1, r0 \n\t" \
|
||||||
|
"msr CPSR_c, r1 \n\t" \
|
||||||
|
: \
|
||||||
|
: "r" (_SEGGER_RTT__LockState) \
|
||||||
|
: "r0", "r1", "cc" \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for IAR RX
|
||||||
|
*/
|
||||||
|
#ifdef __ICCRX__
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned long _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = __get_interrupt_state(); \
|
||||||
|
__disable_interrupt();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for IAR RL78
|
||||||
|
*/
|
||||||
|
#ifdef __ICCRL78__
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
__istate_t _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = __get_interrupt_state(); \
|
||||||
|
__disable_interrupt();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for KEIL ARM
|
||||||
|
*/
|
||||||
|
#ifdef __CC_ARM
|
||||||
|
#if (defined __TARGET_ARCH_6S_M)
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
register unsigned char _SEGGER_RTT__PRIMASK __asm( "primask"); \
|
||||||
|
_SEGGER_RTT__LockState = _SEGGER_RTT__PRIMASK; \
|
||||||
|
_SEGGER_RTT__PRIMASK = 1u; \
|
||||||
|
__schedule_barrier();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() _SEGGER_RTT__PRIMASK = _SEGGER_RTT__LockState; \
|
||||||
|
__schedule_barrier(); \
|
||||||
|
}
|
||||||
|
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||||
|
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||||
|
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||||
|
#endif
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
register unsigned char BASEPRI __asm( "basepri"); \
|
||||||
|
_SEGGER_RTT__LockState = BASEPRI; \
|
||||||
|
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
|
||||||
|
__schedule_barrier();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() BASEPRI = _SEGGER_RTT__LockState; \
|
||||||
|
__schedule_barrier(); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for TI ARM
|
||||||
|
*/
|
||||||
|
#ifdef __TI_ARM__
|
||||||
|
#if defined (__TI_ARM_V6M0__)
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = __get_PRIMASK(); \
|
||||||
|
__set_PRIMASK(1);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
|
||||||
|
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||||
|
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||||
|
#endif
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned int _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = _set_interrupt_priority(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() _set_interrupt_priority(_SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for CCRX
|
||||||
|
*/
|
||||||
|
#ifdef __RX
|
||||||
|
#include <machine.h>
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
unsigned long _SEGGER_RTT__LockState; \
|
||||||
|
_SEGGER_RTT__LockState = get_psw() & 0x010000; \
|
||||||
|
clrpsw_i();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() set_psw(get_psw() | _SEGGER_RTT__LockState); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration for embOS Simulation on Windows
|
||||||
|
* (Can also be used for generic RTT locking with embOS)
|
||||||
|
*/
|
||||||
|
#if defined(WIN32) || defined(SEGGER_RTT_LOCK_EMBOS)
|
||||||
|
|
||||||
|
void OS_SIM_EnterCriticalSection(void);
|
||||||
|
void OS_SIM_LeaveCriticalSection(void);
|
||||||
|
|
||||||
|
#define SEGGER_RTT_LOCK() { \
|
||||||
|
OS_SIM_EnterCriticalSection();
|
||||||
|
|
||||||
|
#define SEGGER_RTT_UNLOCK() OS_SIM_LeaveCriticalSection(); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* RTT lock configuration fallback
|
||||||
|
*/
|
||||||
|
#ifndef SEGGER_RTT_LOCK
|
||||||
|
#define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_UNLOCK
|
||||||
|
#define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* If SEGGER_RTT_SECTION is defined but SEGGER_RTT_BUFFER_SECTION
|
||||||
|
* is not, use the same section for SEGGER_RTT_BUFFER_SECTION.
|
||||||
|
*/
|
||||||
|
#ifndef SEGGER_RTT_BUFFER_SECTION
|
||||||
|
#if defined(SEGGER_RTT_SECTION)
|
||||||
|
#define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*************************** End of file ****************************/
|
522
libs/SEGGER_RTT/RTT/SEGGER_RTT_printf.c
Normal file
522
libs/SEGGER_RTT/RTT/SEGGER_RTT_printf.c
Normal file
@ -0,0 +1,522 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
---------------------------END-OF-HEADER------------------------------
|
||||||
|
File : SEGGER_RTT_printf.c
|
||||||
|
Purpose : Replacement for printf to write formatted data via RTT
|
||||||
|
Revision: $Rev: 17697 $
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
|
#include "SEGGER_RTT_Conf.h"
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Defines, configurable
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
|
||||||
|
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0)
|
||||||
|
#define FORMAT_FLAG_PAD_ZERO (1u << 1)
|
||||||
|
#define FORMAT_FLAG_PRINT_SIGN (1u << 2)
|
||||||
|
#define FORMAT_FLAG_ALTERNATE (1u << 3)
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Types
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* pBuffer;
|
||||||
|
unsigned BufferSize;
|
||||||
|
unsigned Cnt;
|
||||||
|
|
||||||
|
int ReturnValue;
|
||||||
|
|
||||||
|
unsigned RTTBufferIndex;
|
||||||
|
} SEGGER_RTT_PRINTF_DESC;
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Function prototypes
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Static code
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _StoreChar
|
||||||
|
*/
|
||||||
|
static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) {
|
||||||
|
unsigned Cnt;
|
||||||
|
|
||||||
|
Cnt = p->Cnt;
|
||||||
|
if ((Cnt + 1u) <= p->BufferSize) {
|
||||||
|
*(p->pBuffer + Cnt) = c;
|
||||||
|
p->Cnt = Cnt + 1u;
|
||||||
|
p->ReturnValue++;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Write part of string, when the buffer is full
|
||||||
|
//
|
||||||
|
if (p->Cnt == p->BufferSize) {
|
||||||
|
if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {
|
||||||
|
p->ReturnValue = -1;
|
||||||
|
} else {
|
||||||
|
p->Cnt = 0u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _PrintUnsigned
|
||||||
|
*/
|
||||||
|
static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
|
||||||
|
static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||||
|
unsigned Div;
|
||||||
|
unsigned Digit;
|
||||||
|
unsigned Number;
|
||||||
|
unsigned Width;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
Number = v;
|
||||||
|
Digit = 1u;
|
||||||
|
//
|
||||||
|
// Get actual field width
|
||||||
|
//
|
||||||
|
Width = 1u;
|
||||||
|
while (Number >= Base) {
|
||||||
|
Number = (Number / Base);
|
||||||
|
Width++;
|
||||||
|
}
|
||||||
|
if (NumDigits > Width) {
|
||||||
|
Width = NumDigits;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Print leading chars if necessary
|
||||||
|
//
|
||||||
|
if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
|
||||||
|
if (FieldWidth != 0u) {
|
||||||
|
if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
|
||||||
|
c = '0';
|
||||||
|
} else {
|
||||||
|
c = ' ';
|
||||||
|
}
|
||||||
|
while ((FieldWidth != 0u) && (Width < FieldWidth)) {
|
||||||
|
FieldWidth--;
|
||||||
|
_StoreChar(pBufferDesc, c);
|
||||||
|
if (pBufferDesc->ReturnValue < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pBufferDesc->ReturnValue >= 0) {
|
||||||
|
//
|
||||||
|
// Compute Digit.
|
||||||
|
// Loop until Digit has the value of the highest digit required.
|
||||||
|
// Example: If the output is 345 (Base 10), loop 2 times until Digit is 100.
|
||||||
|
//
|
||||||
|
while (1) {
|
||||||
|
if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned)
|
||||||
|
NumDigits--;
|
||||||
|
} else {
|
||||||
|
Div = v / Digit;
|
||||||
|
if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Digit *= Base;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Output digits
|
||||||
|
//
|
||||||
|
do {
|
||||||
|
Div = v / Digit;
|
||||||
|
v -= Div * Digit;
|
||||||
|
_StoreChar(pBufferDesc, _aV2C[Div]);
|
||||||
|
if (pBufferDesc->ReturnValue < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Digit /= Base;
|
||||||
|
} while (Digit);
|
||||||
|
//
|
||||||
|
// Print trailing spaces if necessary
|
||||||
|
//
|
||||||
|
if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
|
||||||
|
if (FieldWidth != 0u) {
|
||||||
|
while ((FieldWidth != 0u) && (Width < FieldWidth)) {
|
||||||
|
FieldWidth--;
|
||||||
|
_StoreChar(pBufferDesc, ' ');
|
||||||
|
if (pBufferDesc->ReturnValue < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _PrintInt
|
||||||
|
*/
|
||||||
|
static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
|
||||||
|
unsigned Width;
|
||||||
|
int Number;
|
||||||
|
|
||||||
|
Number = (v < 0) ? -v : v;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get actual field width
|
||||||
|
//
|
||||||
|
Width = 1u;
|
||||||
|
while (Number >= (int)Base) {
|
||||||
|
Number = (Number / (int)Base);
|
||||||
|
Width++;
|
||||||
|
}
|
||||||
|
if (NumDigits > Width) {
|
||||||
|
Width = NumDigits;
|
||||||
|
}
|
||||||
|
if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
|
||||||
|
FieldWidth--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Print leading spaces if necessary
|
||||||
|
//
|
||||||
|
if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
|
||||||
|
if (FieldWidth != 0u) {
|
||||||
|
while ((FieldWidth != 0u) && (Width < FieldWidth)) {
|
||||||
|
FieldWidth--;
|
||||||
|
_StoreChar(pBufferDesc, ' ');
|
||||||
|
if (pBufferDesc->ReturnValue < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Print sign if necessary
|
||||||
|
//
|
||||||
|
if (pBufferDesc->ReturnValue >= 0) {
|
||||||
|
if (v < 0) {
|
||||||
|
v = -v;
|
||||||
|
_StoreChar(pBufferDesc, '-');
|
||||||
|
} else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
|
||||||
|
_StoreChar(pBufferDesc, '+');
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (pBufferDesc->ReturnValue >= 0) {
|
||||||
|
//
|
||||||
|
// Print leading zeros if necessary
|
||||||
|
//
|
||||||
|
if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
|
||||||
|
if (FieldWidth != 0u) {
|
||||||
|
while ((FieldWidth != 0u) && (Width < FieldWidth)) {
|
||||||
|
FieldWidth--;
|
||||||
|
_StoreChar(pBufferDesc, '0');
|
||||||
|
if (pBufferDesc->ReturnValue < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pBufferDesc->ReturnValue >= 0) {
|
||||||
|
//
|
||||||
|
// Print number without sign
|
||||||
|
//
|
||||||
|
_PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Public code
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* SEGGER_RTT_vprintf
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* Stores a formatted string in SEGGER RTT control block.
|
||||||
|
* This data is read by the host.
|
||||||
|
*
|
||||||
|
* Parameters
|
||||||
|
* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
|
||||||
|
* sFormat Pointer to format string
|
||||||
|
* pParamList Pointer to the list of arguments for the format string
|
||||||
|
*
|
||||||
|
* Return values
|
||||||
|
* >= 0: Number of bytes which have been stored in the "Up"-buffer.
|
||||||
|
* < 0: Error
|
||||||
|
*/
|
||||||
|
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) {
|
||||||
|
char c;
|
||||||
|
SEGGER_RTT_PRINTF_DESC BufferDesc;
|
||||||
|
int v;
|
||||||
|
unsigned char PrecisionSet;
|
||||||
|
unsigned Precision;
|
||||||
|
unsigned FormatFlags;
|
||||||
|
unsigned FieldWidth;
|
||||||
|
char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
|
||||||
|
|
||||||
|
BufferDesc.pBuffer = acBuffer;
|
||||||
|
BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE;
|
||||||
|
BufferDesc.Cnt = 0u;
|
||||||
|
BufferDesc.RTTBufferIndex = BufferIndex;
|
||||||
|
BufferDesc.ReturnValue = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
c = *sFormat;
|
||||||
|
sFormat++;
|
||||||
|
if (c == 0u) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c == '%') {
|
||||||
|
//
|
||||||
|
// Filter out flags
|
||||||
|
//
|
||||||
|
FormatFlags = 0u;
|
||||||
|
v = 1;
|
||||||
|
do {
|
||||||
|
c = *sFormat;
|
||||||
|
switch (c) {
|
||||||
|
case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
|
||||||
|
case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break;
|
||||||
|
case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break;
|
||||||
|
case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break;
|
||||||
|
default: v = 0; break;
|
||||||
|
}
|
||||||
|
} while (v);
|
||||||
|
//
|
||||||
|
// filter out field with
|
||||||
|
//
|
||||||
|
FieldWidth = 0u;
|
||||||
|
do {
|
||||||
|
c = *sFormat;
|
||||||
|
if ((c < '0') || (c > '9')) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sFormat++;
|
||||||
|
FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0');
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Filter out precision (number of digits to display)
|
||||||
|
//
|
||||||
|
PrecisionSet = 0;
|
||||||
|
Precision = 0u;
|
||||||
|
c = *sFormat;
|
||||||
|
if (c == '.') {
|
||||||
|
sFormat++;
|
||||||
|
if (*sFormat == '*') {
|
||||||
|
sFormat++;
|
||||||
|
PrecisionSet = 1;
|
||||||
|
Precision = va_arg(*pParamList, int);
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
c = *sFormat;
|
||||||
|
if ((c < '0') || (c > '9')) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PrecisionSet = 1;
|
||||||
|
sFormat++;
|
||||||
|
Precision = Precision * 10u + ((unsigned)c - '0');
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Filter out length modifier
|
||||||
|
//
|
||||||
|
c = *sFormat;
|
||||||
|
do {
|
||||||
|
if ((c == 'l') || (c == 'h')) {
|
||||||
|
sFormat++;
|
||||||
|
c = *sFormat;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
//
|
||||||
|
// Handle specifiers
|
||||||
|
//
|
||||||
|
switch (c) {
|
||||||
|
case 'c': {
|
||||||
|
char c0;
|
||||||
|
v = va_arg(*pParamList, int);
|
||||||
|
c0 = (char)v;
|
||||||
|
_StoreChar(&BufferDesc, c0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'd':
|
||||||
|
v = va_arg(*pParamList, int);
|
||||||
|
_PrintInt(&BufferDesc, v, 10u, Precision, FieldWidth, FormatFlags);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
v = va_arg(*pParamList, int);
|
||||||
|
_PrintUnsigned(&BufferDesc, (unsigned)v, 10u, Precision, FieldWidth, FormatFlags);
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
v = va_arg(*pParamList, int);
|
||||||
|
_PrintUnsigned(&BufferDesc, (unsigned)v, 16u, Precision, FieldWidth, FormatFlags);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
{
|
||||||
|
const char * s = va_arg(*pParamList, const char *);
|
||||||
|
if (s == NULL) {
|
||||||
|
s = "(NULL)"; // Print (NULL) instead of crashing or breaking, as it is more informative to the user.
|
||||||
|
PrecisionSet = 0; // Make sure (NULL) is printed, even when precision was set.
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
c = *s;
|
||||||
|
s++;
|
||||||
|
if (c == '\0') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((PrecisionSet != 0) && (Precision == 0)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_StoreChar(&BufferDesc, c);
|
||||||
|
Precision--;
|
||||||
|
} while (BufferDesc.ReturnValue >= 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
v = va_arg(*pParamList, int);
|
||||||
|
_PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u);
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
_StoreChar(&BufferDesc, '%');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sFormat++;
|
||||||
|
} else {
|
||||||
|
_StoreChar(&BufferDesc, c);
|
||||||
|
}
|
||||||
|
} while (BufferDesc.ReturnValue >= 0);
|
||||||
|
|
||||||
|
if (BufferDesc.ReturnValue > 0) {
|
||||||
|
//
|
||||||
|
// Write remaining data, if any
|
||||||
|
//
|
||||||
|
if (BufferDesc.Cnt != 0u) {
|
||||||
|
SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
|
||||||
|
}
|
||||||
|
BufferDesc.ReturnValue += (int)BufferDesc.Cnt;
|
||||||
|
}
|
||||||
|
return BufferDesc.ReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* SEGGER_RTT_printf
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* Stores a formatted string in SEGGER RTT control block.
|
||||||
|
* This data is read by the host.
|
||||||
|
*
|
||||||
|
* Parameters
|
||||||
|
* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
|
||||||
|
* sFormat Pointer to format string, followed by the arguments for conversion
|
||||||
|
*
|
||||||
|
* Return values
|
||||||
|
* >= 0: Number of bytes which have been stored in the "Up"-buffer.
|
||||||
|
* < 0: Error
|
||||||
|
*
|
||||||
|
* Notes
|
||||||
|
* (1) Conversion specifications have following syntax:
|
||||||
|
* %[flags][FieldWidth][.Precision]ConversionSpecifier
|
||||||
|
* (2) Supported flags:
|
||||||
|
* -: Left justify within the field width
|
||||||
|
* +: Always print sign extension for signed conversions
|
||||||
|
* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision
|
||||||
|
* Supported conversion specifiers:
|
||||||
|
* c: Print the argument as one char
|
||||||
|
* d: Print the argument as a signed integer
|
||||||
|
* u: Print the argument as an unsigned integer
|
||||||
|
* x: Print the argument as an hexadecimal integer
|
||||||
|
* s: Print the string pointed to by the argument
|
||||||
|
* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.)
|
||||||
|
*/
|
||||||
|
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) {
|
||||||
|
int r;
|
||||||
|
va_list ParamList;
|
||||||
|
|
||||||
|
va_start(ParamList, sFormat);
|
||||||
|
r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);
|
||||||
|
va_end(ParamList);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
/*************************** End of file ****************************/
|
125
libs/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_GCC.c
Normal file
125
libs/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_GCC.c
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
---------------------------END-OF-HEADER------------------------------
|
||||||
|
File : SEGGER_RTT_Syscalls_GCC.c
|
||||||
|
Purpose : Low-level functions for using printf() via RTT in GCC.
|
||||||
|
To use RTT for printf output, include this file in your
|
||||||
|
application.
|
||||||
|
Revision: $Rev: 24316 $
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if (defined __GNUC__) && !(defined __SES_ARM) && !(defined __CROSSWORKS_ARM) && !(defined __ARMCC_VERSION) && !(defined __CC_ARM)
|
||||||
|
|
||||||
|
#include <reent.h> // required for _write_r
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Types
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
// If necessary define the _reent struct
|
||||||
|
// to match the one passed by the used standard library.
|
||||||
|
//
|
||||||
|
struct _reent;
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Function prototypes
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
_ssize_t _write (int file, const void *ptr, size_t len);
|
||||||
|
_ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len);
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Global functions
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _write()
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* Low-level write function.
|
||||||
|
* libc subroutines will use this system routine for output to all files,
|
||||||
|
* including stdout.
|
||||||
|
* Write data via RTT.
|
||||||
|
*/
|
||||||
|
_ssize_t _write(int file, const void *ptr, size_t len) {
|
||||||
|
(void) file; /* Not used, avoid warning */
|
||||||
|
SEGGER_RTT_Write(0, ptr, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _write_r()
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* Low-level reentrant write function.
|
||||||
|
* libc subroutines will use this system routine for output to all files,
|
||||||
|
* including stdout.
|
||||||
|
* Write data via RTT.
|
||||||
|
*/
|
||||||
|
_ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len) {
|
||||||
|
(void) file; /* Not used, avoid warning */
|
||||||
|
(void) r; /* Not used, avoid warning */
|
||||||
|
SEGGER_RTT_Write(0, ptr, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/****** End Of File *************************************************/
|
120
libs/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_IAR.c
Normal file
120
libs/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_IAR.c
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
---------------------------END-OF-HEADER------------------------------
|
||||||
|
File : SEGGER_RTT_Syscalls_IAR.c
|
||||||
|
Purpose : Low-level functions for using printf() via RTT in IAR.
|
||||||
|
To use RTT for printf output, include this file in your
|
||||||
|
application and set the Library Configuration to Normal.
|
||||||
|
Revision: $Rev: 24316 $
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
|
|
||||||
|
//
|
||||||
|
// Since IAR EWARM V8 and EWRX V4, yfuns.h is considered as deprecated and LowLevelIOInterface.h
|
||||||
|
// shall be used instead. To not break any compatibility with older compiler versions, we have a
|
||||||
|
// version check in here.
|
||||||
|
//
|
||||||
|
#if ((defined __ICCARM__) && (__VER__ >= 8000000)) || ((defined __ICCRX__) && (__VER__ >= 400))
|
||||||
|
#include <LowLevelIOInterface.h>
|
||||||
|
#else
|
||||||
|
#include <yfuns.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
|
#pragma module_name = "?__write"
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Function prototypes
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
size_t __write(int handle, const unsigned char * buffer, size_t size);
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Global functions
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* __write()
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* Low-level write function.
|
||||||
|
* Standard library subroutines will use this system routine
|
||||||
|
* for output to all files, including stdout.
|
||||||
|
* Write data via RTT.
|
||||||
|
*/
|
||||||
|
size_t __write(int handle, const unsigned char * buffer, size_t size) {
|
||||||
|
(void) handle; /* Not used, avoid warning */
|
||||||
|
SEGGER_RTT_Write(0, (const char*)buffer, size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* __write_buffered()
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* Low-level write function.
|
||||||
|
* Standard library subroutines will use this system routine
|
||||||
|
* for output to all files, including stdout.
|
||||||
|
* Write data via RTT.
|
||||||
|
*/
|
||||||
|
size_t __write_buffered(int handle, const unsigned char * buffer, size_t size) {
|
||||||
|
(void) handle; /* Not used, avoid warning */
|
||||||
|
SEGGER_RTT_Write(0, (const char*)buffer, size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/****** End Of File *************************************************/
|
405
libs/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_KEIL.c
Normal file
405
libs/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_KEIL.c
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
---------------------------END-OF-HEADER------------------------------
|
||||||
|
File : RTT_Syscalls_KEIL.c
|
||||||
|
Purpose : Retargeting module for KEIL MDK-CM3.
|
||||||
|
Low-level functions for using printf() via RTT
|
||||||
|
Revision: $Rev: 29653 $
|
||||||
|
Notes : (1) https://wiki.segger.com/Keil_MDK-ARM#RTT_in_uVision
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if (defined __CC_ARM) || (defined __ARMCC_VERSION)
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <rt_sys.h>
|
||||||
|
#include <rt_misc.h>
|
||||||
|
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* #pragmas
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
#if __ARMCC_VERSION < 6000000
|
||||||
|
#pragma import(__use_no_semihosting)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MICROLIB
|
||||||
|
#pragma import(__use_full_stdio)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Defines non-configurable
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard IO device handles - arbitrary, but any real file system handles must be
|
||||||
|
less than 0x8000. */
|
||||||
|
#define STDIN 0x8001 // Standard Input Stream
|
||||||
|
#define STDOUT 0x8002 // Standard Output Stream
|
||||||
|
#define STDERR 0x8003 // Standard Error Stream
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Public const
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
#if __ARMCC_VERSION < 5000000
|
||||||
|
//const char __stdin_name[] = "STDIN";
|
||||||
|
const char __stdout_name[] = "STDOUT";
|
||||||
|
const char __stderr_name[] = "STDERR";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Public code
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _ttywrch
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* Outputs a character to the console
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* c - character to output
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void _ttywrch(int c) {
|
||||||
|
fputc(c, stdout); // stdout
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_open
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* Opens the device/file in order to do read/write operations
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* sName - sName of the device/file to open
|
||||||
|
* OpenMode - This parameter is currently ignored
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* != 0 - Handle to the object to open, otherwise
|
||||||
|
* == 0 -"device" is not handled by this module
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
FILEHANDLE _sys_open(const char * sName, int OpenMode) {
|
||||||
|
(void)OpenMode;
|
||||||
|
// Register standard Input Output devices.
|
||||||
|
if (strcmp(sName, __stdout_name) == 0) {
|
||||||
|
return (STDOUT);
|
||||||
|
} else if (strcmp(sName, __stderr_name) == 0) {
|
||||||
|
return (STDERR);
|
||||||
|
} else
|
||||||
|
return (0); // Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_close
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* Closes the handle to the open device/file
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* hFile - Handle to a file opened via _sys_open
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* 0 - device/file closed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int _sys_close(FILEHANDLE hFile) {
|
||||||
|
(void)hFile;
|
||||||
|
return 0; // Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_write
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* Writes the data to an open handle.
|
||||||
|
* Currently this function only outputs data to the console
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* hFile - Handle to a file opened via _sys_open
|
||||||
|
* pBuffer - Pointer to the data that shall be written
|
||||||
|
* NumBytes - Number of bytes to write
|
||||||
|
* Mode - The Mode that shall be used
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* Number of bytes *not* written to the file/device
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int _sys_write(FILEHANDLE hFile, const unsigned char * pBuffer, unsigned NumBytes, int Mode) {
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
(void)Mode;
|
||||||
|
if (hFile == STDOUT) {
|
||||||
|
SEGGER_RTT_Write(0, (const char*)pBuffer, NumBytes);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_istty
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* This function shall return whether the opened file
|
||||||
|
* is a console device or not.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* hFile - Handle to a file opened via _sys_open
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* 1 - Device is a console
|
||||||
|
* 0 - Device is not a console
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int _sys_istty(FILEHANDLE hFile) {
|
||||||
|
if (hFile > 0x8000) {
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0); // Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_seek
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* Seeks via the file to a specific position
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* hFile - Handle to a file opened via _sys_open
|
||||||
|
* Pos -
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* int -
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int _sys_seek(FILEHANDLE hFile, long Pos) {
|
||||||
|
(void)hFile;
|
||||||
|
(void)Pos;
|
||||||
|
return (0); // Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_flen
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* Returns the length of the opened file handle
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* hFile - Handle to a file opened via _sys_open
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* Length of the file
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
long _sys_flen(FILEHANDLE hFile) {
|
||||||
|
(void)hFile;
|
||||||
|
return (0); // Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (__ARMCC_VERSION <= 6000000) // The following functions are not required to be implemented for CC version > 6.
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_read
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* Reads data from an open handle.
|
||||||
|
* Currently this modules does nothing.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* hFile - Handle to a file opened via _sys_open
|
||||||
|
* pBuffer - Pointer to buffer to store the read data
|
||||||
|
* NumBytes - Number of bytes to read
|
||||||
|
* Mode - The Mode that shall be used
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* Number of bytes read from the file/device
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int _sys_read(FILEHANDLE hFile, unsigned char * pBuffer, unsigned NumBytes, int Mode) {
|
||||||
|
(void)hFile;
|
||||||
|
(void)pBuffer;
|
||||||
|
(void)NumBytes;
|
||||||
|
(void)Mode;
|
||||||
|
return (0); // Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_ensure
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* hFile - Handle to a file opened via _sys_open
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* int -
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int _sys_ensure(FILEHANDLE hFile) {
|
||||||
|
(void)hFile;
|
||||||
|
return (-1); // Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_tmpnam
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* This function converts the file number fileno for a temporary
|
||||||
|
* file to a unique filename, for example, tmp0001.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* pBuffer - Pointer to a buffer to store the name
|
||||||
|
* FileNum - file number to convert
|
||||||
|
* MaxLen - Size of the buffer
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* 1 - Error
|
||||||
|
* 0 - Success
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#if __ARMCC_VERSION >= 6190000
|
||||||
|
void _sys_tmpnam(char * pBuffer, int FileNum, unsigned MaxLen) {
|
||||||
|
(void)pBuffer;
|
||||||
|
(void)FileNum;
|
||||||
|
(void)MaxLen;
|
||||||
|
return; // Not implemented
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int _sys_tmpnam(char * pBuffer, int FileNum, unsigned MaxLen) {
|
||||||
|
(void)pBuffer;
|
||||||
|
(void)FileNum;
|
||||||
|
(void)MaxLen;
|
||||||
|
return (1); // Not implemented
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_command_string
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* This function shall execute a system command.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* cmd - Pointer to the command string
|
||||||
|
* len - Length of the string
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* == NULL - Command was not successfully executed
|
||||||
|
* == sCmd - Command was passed successfully
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
char * _sys_command_string(char * cmd, int len) {
|
||||||
|
(void)len;
|
||||||
|
return cmd; // Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* _sys_exit
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* This function is called when the application returns from main
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* ReturnCode - Return code from the main function
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void _sys_exit(int ReturnCode) {
|
||||||
|
(void)ReturnCode;
|
||||||
|
while (1); // Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __ARMCC_VERSION >= 5000000
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* stdout_putchar
|
||||||
|
*
|
||||||
|
* Function description:
|
||||||
|
* Put a character to the stdout
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* ch - Character to output
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int stdout_putchar(int ch) {
|
||||||
|
(void)ch;
|
||||||
|
return ch; // Not implemented
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #if __ARMCC_VERSION <= 6000000
|
||||||
|
#endif // #if (defined __CC_ARM) || (defined __ARMCC_VERSION)
|
||||||
|
/*************************** End of file ****************************/
|
252
libs/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_SES.c
Normal file
252
libs/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_SES.c
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* SEGGER Microcontroller GmbH *
|
||||||
|
* The Embedded Experts *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* (c) 1995 - 2021 SEGGER Microcontroller GmbH *
|
||||||
|
* *
|
||||||
|
* www.segger.com Support: support@segger.com *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* SEGGER RTT * Real Time Transfer for embedded targets *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* All rights reserved. *
|
||||||
|
* *
|
||||||
|
* SEGGER strongly recommends to not make any changes *
|
||||||
|
* to or modify the source code of this software in order to stay *
|
||||||
|
* compatible with the RTT protocol and J-Link. *
|
||||||
|
* *
|
||||||
|
* Redistribution and use in source and binary forms, with or *
|
||||||
|
* without modification, are permitted provided that the following *
|
||||||
|
* condition is met: *
|
||||||
|
* *
|
||||||
|
* o Redistributions of source code must retain the above copyright *
|
||||||
|
* notice, this condition and the following disclaimer. *
|
||||||
|
* *
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||||
|
* CONTRIBUTORS "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 SEGGER Microcontroller 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. *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
* *
|
||||||
|
* RTT version: 8.44a *
|
||||||
|
* *
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
---------------------------END-OF-HEADER------------------------------
|
||||||
|
File : SEGGER_RTT_Syscalls_SES.c
|
||||||
|
Purpose : Reimplementation of printf, puts and __getchar using RTT
|
||||||
|
in SEGGER Embedded Studio.
|
||||||
|
To use RTT for printf output, include this file in your
|
||||||
|
application.
|
||||||
|
Revision: $Rev: 24316 $
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if (defined __SES_ARM) || (defined __SES_RISCV) || (defined __CROSSWORKS_ARM)
|
||||||
|
|
||||||
|
#include "SEGGER_RTT.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "limits.h"
|
||||||
|
#include "__libc.h"
|
||||||
|
#include "__vfprintf.h"
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Defines, configurable
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
// Select string formatting implementation.
|
||||||
|
//
|
||||||
|
// RTT printf formatting
|
||||||
|
// - Configurable stack usage. (SEGGER_RTT_PRINTF_BUFFER_SIZE in SEGGER_RTT_Conf.h)
|
||||||
|
// - No maximum string length.
|
||||||
|
// - Limited conversion specifiers and flags. (See SEGGER_RTT_printf.c)
|
||||||
|
// Standard library printf formatting
|
||||||
|
// - Configurable formatting capabilities.
|
||||||
|
// - Full conversion specifier and flag support.
|
||||||
|
// - Maximum string length has to be known or (slightly) slower character-wise output.
|
||||||
|
//
|
||||||
|
// #define PRINTF_USE_SEGGER_RTT_FORMATTING 0 // Use standard library formatting
|
||||||
|
// #define PRINTF_USE_SEGGER_RTT_FORMATTING 1 // Use RTT formatting
|
||||||
|
//
|
||||||
|
#ifndef PRINTF_USE_SEGGER_RTT_FORMATTING
|
||||||
|
#define PRINTF_USE_SEGGER_RTT_FORMATTING 0
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// If using standard library formatting,
|
||||||
|
// select maximum output string buffer size or character-wise output.
|
||||||
|
//
|
||||||
|
// #define PRINTF_BUFFER_SIZE 0 // Use character-wise output
|
||||||
|
// #define PRINTF_BUFFER_SIZE 128 // Default maximum string length
|
||||||
|
//
|
||||||
|
#ifndef PRINTF_BUFFER_SIZE
|
||||||
|
#define PRINTF_BUFFER_SIZE 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PRINTF_USE_SEGGER_RTT_FORMATTING // Use SEGGER RTT formatting implementation
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Function prototypes
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Global functions, printf
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* printf()
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* print a formatted string using RTT and SEGGER RTT formatting.
|
||||||
|
*/
|
||||||
|
int printf(const char *fmt,...) {
|
||||||
|
int n;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start (args, fmt);
|
||||||
|
n = SEGGER_RTT_vprintf(0, fmt, &args);
|
||||||
|
va_end(args);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif PRINTF_BUFFER_SIZE == 0 // Use standard library formatting with character-wise output
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Static functions
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
static int _putchar(int x, __printf_tag_ptr ctx) {
|
||||||
|
(void)ctx;
|
||||||
|
SEGGER_RTT_Write(0, (char *)&x, 1);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Global functions, printf
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* printf()
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* print a formatted string character-wise, using RTT and standard
|
||||||
|
* library formatting.
|
||||||
|
*/
|
||||||
|
int printf(const char *fmt, ...) {
|
||||||
|
int n;
|
||||||
|
va_list args;
|
||||||
|
__printf_t iod;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
iod.string = 0;
|
||||||
|
iod.maxchars = INT_MAX;
|
||||||
|
iod.output_fn = _putchar;
|
||||||
|
SEGGER_RTT_LOCK();
|
||||||
|
n = __vfprintf(&iod, fmt, args);
|
||||||
|
SEGGER_RTT_UNLOCK();
|
||||||
|
va_end(args);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // Use standard library formatting with static buffer
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Global functions, printf
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* printf()
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* print a formatted string using RTT and standard library formatting.
|
||||||
|
*/
|
||||||
|
int printf(const char *fmt,...) {
|
||||||
|
int n;
|
||||||
|
char aBuffer[PRINTF_BUFFER_SIZE];
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start (args, fmt);
|
||||||
|
n = vsnprintf(aBuffer, sizeof(aBuffer), fmt, args);
|
||||||
|
if (n > (int)sizeof(aBuffer)) {
|
||||||
|
SEGGER_RTT_Write(0, aBuffer, sizeof(aBuffer));
|
||||||
|
} else if (n > 0) {
|
||||||
|
SEGGER_RTT_Write(0, aBuffer, n);
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Global functions
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
*/
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* puts()
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* print a string using RTT.
|
||||||
|
*/
|
||||||
|
int puts(const char *s) {
|
||||||
|
return SEGGER_RTT_WriteString(0, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* __putchar()
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* Write one character via RTT.
|
||||||
|
*/
|
||||||
|
int __putchar(int x, __printf_tag_ptr ctx) {
|
||||||
|
(void)ctx;
|
||||||
|
SEGGER_RTT_Write(0, (char *)&x, 1);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* __getchar()
|
||||||
|
*
|
||||||
|
* Function description
|
||||||
|
* Wait for and get a character via RTT.
|
||||||
|
*/
|
||||||
|
int __getchar() {
|
||||||
|
return SEGGER_RTT_WaitKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/****** End Of File *************************************************/
|
39
libs/SEGGER_RTT/cmake_install.cmake
Normal file
39
libs/SEGGER_RTT/cmake_install.cmake
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Install script for directory: D:/Git_Code/school_stm32/embedding/SEGGER_RTT
|
||||||
|
|
||||||
|
# Set the install prefix
|
||||||
|
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||||
|
set(CMAKE_INSTALL_PREFIX "C:/Program Files/embedding")
|
||||||
|
endif()
|
||||||
|
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||||
|
|
||||||
|
# Set the install configuration name.
|
||||||
|
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||||
|
if(BUILD_TYPE)
|
||||||
|
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||||
|
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||||
|
else()
|
||||||
|
set(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set the component getting installed.
|
||||||
|
if(NOT CMAKE_INSTALL_COMPONENT)
|
||||||
|
if(COMPONENT)
|
||||||
|
message(STATUS "Install component: \"${COMPONENT}\"")
|
||||||
|
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||||
|
else()
|
||||||
|
set(CMAKE_INSTALL_COMPONENT)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Is this installation the result of a crosscompile?
|
||||||
|
if(NOT DEFINED CMAKE_CROSSCOMPILING)
|
||||||
|
set(CMAKE_CROSSCOMPILING "TRUE")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set default install directory permissions.
|
||||||
|
if(NOT DEFINED CMAKE_OBJDUMP)
|
||||||
|
set(CMAKE_OBJDUMP "D:/Programs/_compiler/ST/STM32CubeCLT_1.18.0/GNU-tools-for-STM32/bin/arm-none-eabi-objdump.exe")
|
||||||
|
endif()
|
||||||
|
|
88
libs/ge_interface/ge_input.c
Normal file
88
libs/ge_interface/ge_input.c
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#include <main.h>
|
||||||
|
#include "ge_interface.h"
|
||||||
|
#include "include/ge_kfifo.h"
|
||||||
|
|
||||||
|
#define SCAN_BTN(lnum, hnum) do { \
|
||||||
|
/*GE_SET_OFF(KEY_L ## hnum);*/ \
|
||||||
|
if (GE_IS_BIN_PRESSD(H ## hnum)) \
|
||||||
|
event.num = GE_ITYPE_KEY_L ## lnum ## H ## hnum, \
|
||||||
|
ctx->func_send(ctx, event); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
void input_btn_func(ge_input_t* ctx) {
|
||||||
|
ge_input_event_t event;
|
||||||
|
|
||||||
|
if (GE_IS_BIN_PRESSD(1)) event.num = GE_ITYPE_KEY_1, ctx->func_send(ctx, event);
|
||||||
|
if (GE_IS_BIN_PRESSD(2)) event.num = GE_ITYPE_KEY_2, ctx->func_send(ctx, event);
|
||||||
|
if (GE_IS_BIN_PRESSD(3)) event.num = GE_ITYPE_KEY_3, ctx->func_send(ctx, event);
|
||||||
|
if (GE_IS_BIN_PRESSD(4)) event.num = GE_ITYPE_KEY_4, ctx->func_send(ctx, event);
|
||||||
|
|
||||||
|
GE_SET_OFF(KEY_L1);
|
||||||
|
SCAN_BTN(1, 1);
|
||||||
|
SCAN_BTN(1, 2);
|
||||||
|
SCAN_BTN(1, 3);
|
||||||
|
SCAN_BTN(1, 4);
|
||||||
|
HAL_Delay(10);
|
||||||
|
GE_SET_ON(KEY_L1);
|
||||||
|
|
||||||
|
GE_SET_OFF(KEY_L2);
|
||||||
|
SCAN_BTN(2, 1);
|
||||||
|
SCAN_BTN(2, 2);
|
||||||
|
SCAN_BTN(2, 3);
|
||||||
|
SCAN_BTN(2, 4);
|
||||||
|
HAL_Delay(10);
|
||||||
|
GE_SET_ON(KEY_L2);
|
||||||
|
|
||||||
|
GE_SET_OFF(KEY_L3);
|
||||||
|
SCAN_BTN(3, 1);
|
||||||
|
SCAN_BTN(3, 2);
|
||||||
|
SCAN_BTN(3, 3);
|
||||||
|
SCAN_BTN(3, 4);
|
||||||
|
HAL_Delay(10);
|
||||||
|
GE_SET_ON(KEY_L3);
|
||||||
|
|
||||||
|
GE_SET_OFF(KEY_L4);
|
||||||
|
SCAN_BTN(4, 1);
|
||||||
|
SCAN_BTN(4, 2);
|
||||||
|
SCAN_BTN(4, 3);
|
||||||
|
SCAN_BTN(4, 4);
|
||||||
|
HAL_Delay(10);
|
||||||
|
GE_SET_ON(KEY_L4);
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_GE_KFIFO(ge_input_fifo, ge_input_event_t, 16, ge_input_fifo_t);
|
||||||
|
|
||||||
|
int ge_input_send (ge_input_t* ctx, ge_input_event_t event) {
|
||||||
|
struct ge_input_fifo_t* fifo = (struct ge_input_fifo_t*)ctx->context;
|
||||||
|
if (ge_kfifo_is_full(fifo)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ge_kfifo_put(fifo, event);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ge_input_peek (ge_input_t* ctx, ge_input_event_t* event) {
|
||||||
|
struct ge_input_fifo_t* fifo = (struct ge_input_fifo_t*)ctx->context;
|
||||||
|
if (ge_kfifo_is_empty(fifo)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ge_kfifo_peek(fifo, event);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ge_input_recv (ge_input_t* ctx, ge_input_event_t* event) {
|
||||||
|
struct ge_input_fifo_t* fifo = (struct ge_input_fifo_t*)ctx->context;
|
||||||
|
if (ge_kfifo_is_empty(fifo)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ge_kfifo_get(fifo, event);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ge_input_t ge_input = {
|
||||||
|
.context = &ge_input_fifo,
|
||||||
|
|
||||||
|
.func_send = ge_input_send,
|
||||||
|
.func_peek = ge_input_peek,
|
||||||
|
.func_recv = ge_input_recv,
|
||||||
|
};
|
55
libs/ge_interface/ge_interface.h
Normal file
55
libs/ge_interface/ge_interface.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef __GE_INTERFACE_H__
|
||||||
|
#define __GE_INTERFACE_H__
|
||||||
|
|
||||||
|
#include "include/ge_input.h"
|
||||||
|
#include "include/ge_render.h"
|
||||||
|
#include "include/ge_resource.h"
|
||||||
|
#include "include/ge_timer.h"
|
||||||
|
#include <pynic_log/pynic_log.h>
|
||||||
|
|
||||||
|
extern ge_input_t ge_input;
|
||||||
|
extern ge_render_t ge_render;
|
||||||
|
extern ge_resource_t ge_resource;
|
||||||
|
extern ge_timer_t ge_timer;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
GE_ITYPE_NONE,
|
||||||
|
GE_ITYPE_KEY_1,
|
||||||
|
GE_ITYPE_KEY_2,
|
||||||
|
GE_ITYPE_KEY_3,
|
||||||
|
GE_ITYPE_KEY_4,
|
||||||
|
GE_ITYPE_KEY_L1H1,
|
||||||
|
GE_ITYPE_KEY_L1H2,
|
||||||
|
GE_ITYPE_KEY_L1H3,
|
||||||
|
GE_ITYPE_KEY_L1H4,
|
||||||
|
GE_ITYPE_KEY_L2H1,
|
||||||
|
GE_ITYPE_KEY_L2H2,
|
||||||
|
GE_ITYPE_KEY_L2H3,
|
||||||
|
GE_ITYPE_KEY_L2H4,
|
||||||
|
GE_ITYPE_KEY_L3H1,
|
||||||
|
GE_ITYPE_KEY_L3H2,
|
||||||
|
GE_ITYPE_KEY_L3H3,
|
||||||
|
GE_ITYPE_KEY_L3H4,
|
||||||
|
GE_ITYPE_KEY_L4H1,
|
||||||
|
GE_ITYPE_KEY_L4H2,
|
||||||
|
GE_ITYPE_KEY_L4H3,
|
||||||
|
GE_ITYPE_KEY_L4H4,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GE_FAST_SET_ON(name) (name##_GPIO_Port->BSRR = name##_Pin)
|
||||||
|
#define GE_FAST_SET_OFF(name) (name##_GPIO_Port->BRR = name##_Pin)
|
||||||
|
// #define GE_FAST_SET_OFF(name) (name##_GPIO_Port->BSRR = (uint32_t)name##_Pin << 16u;)
|
||||||
|
|
||||||
|
#define GE_SET_STATE(name, state) HAL_GPIO_WritePin(name##_GPIO_Port, name##_Pin, state)
|
||||||
|
#define GE_SET_ON(name) GE_SET_STATE(name, GPIO_PIN_SET)
|
||||||
|
#define GE_SET_OFF(name) GE_SET_STATE(name, GPIO_PIN_RESET)
|
||||||
|
|
||||||
|
#define GE_LED_SET(num, state) HAL_GPIO_WritePin(LED_##num##_GPIO_Port, LED_##num##_Pin, state);
|
||||||
|
#define GE_LED_TOGGLE(num) HAL_GPIO_TogglePin(LED_##num##_GPIO_Port, LED_##num##_Pin);
|
||||||
|
#define GE_LED_ON(num) GE_LED_SET(num, GPIO_PIN_SET)
|
||||||
|
#define GE_LED_OFF(num) GE_LED_SET(num, GPIO_PIN_RESET)
|
||||||
|
#define GE_IS_BIN_PRESSD(num) (HAL_GPIO_ReadPin(KEY_##num##_GPIO_Port, KEY_##num##_Pin) == GPIO_PIN_RESET)
|
||||||
|
|
||||||
|
void input_btn_func(ge_input_t* ctx);
|
||||||
|
|
||||||
|
#endif // __GE_INTERFACE_H__
|
333
libs/ge_interface/ge_render.c
Normal file
333
libs/ge_interface/ge_render.c
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
#include <main.h>
|
||||||
|
#include "ge_interface.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lcd_driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define lcd_write_bit_reg(bit) \
|
||||||
|
do { \
|
||||||
|
(bit) ? GE_FAST_SET_ON(LCD_SDA) : GE_FAST_SET_OFF(LCD_SDA); \
|
||||||
|
GE_FAST_SET_OFF(LCD_SCL); GE_FAST_SET_ON(LCD_SCL); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define lcd_write_byte(data) \
|
||||||
|
do { \
|
||||||
|
uint8_t __d = (data); \
|
||||||
|
lcd_write_bit_reg(__d & 0x80); \
|
||||||
|
lcd_write_bit_reg(__d & 0x40); \
|
||||||
|
lcd_write_bit_reg(__d & 0x20); \
|
||||||
|
lcd_write_bit_reg(__d & 0x10); \
|
||||||
|
lcd_write_bit_reg(__d & 0x08); \
|
||||||
|
lcd_write_bit_reg(__d & 0x04); \
|
||||||
|
lcd_write_bit_reg(__d & 0x02); \
|
||||||
|
lcd_write_bit_reg(__d & 0x01); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define lcd_write_32bit(data) \
|
||||||
|
do { \
|
||||||
|
uint32_t __d32 = (data); \
|
||||||
|
lcd_write_byte(__d32 >> 24); \
|
||||||
|
lcd_write_byte(__d32 >> 16); \
|
||||||
|
lcd_write_byte(__d32 >> 8); \
|
||||||
|
lcd_write_byte(__d32); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static inline void lcd_write_raw_data(const uint8_t* data, uint32_t len) {
|
||||||
|
if (!data || len == 0) return;
|
||||||
|
|
||||||
|
// 32位对齐部分(高效处理)
|
||||||
|
uint32_t word_count = len >> 2; // len / 4
|
||||||
|
uint32_t* word_ptr = (uint32_t*)data;
|
||||||
|
|
||||||
|
while (word_count--) {
|
||||||
|
lcd_write_32bit(*word_ptr++); // 使用32位写入宏
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理剩余字节(非4字节对齐部分)
|
||||||
|
uint8_t remain = len % 4;
|
||||||
|
if (remain) {
|
||||||
|
uint8_t* byte_ptr = (uint8_t*)word_ptr;
|
||||||
|
for (uint8_t i = 0; i < remain; i++) {
|
||||||
|
lcd_write_byte(*byte_ptr++); // 使用8位写入宏
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lcd_write_cmd(uint8_t cmd, const uint8_t* data, uint32_t len) {
|
||||||
|
// write index
|
||||||
|
GE_FAST_SET_OFF(LCD_CS);
|
||||||
|
GE_FAST_SET_OFF(LCD_DC);
|
||||||
|
lcd_write_byte(cmd);
|
||||||
|
GE_FAST_SET_ON(LCD_CS);
|
||||||
|
|
||||||
|
if (len == 0 || data == NULL) return;
|
||||||
|
// write data
|
||||||
|
GE_FAST_SET_OFF(LCD_CS);
|
||||||
|
GE_FAST_SET_ON(LCD_DC);
|
||||||
|
lcd_write_raw_data(data, len);
|
||||||
|
GE_FAST_SET_ON(LCD_CS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lcd_reset(void) {
|
||||||
|
// LCD_RES_Pin
|
||||||
|
// 重启屏幕 RES(RE Set)
|
||||||
|
GE_SET_OFF(LCD_RES);
|
||||||
|
HAL_Delay(100);
|
||||||
|
GE_SET_ON(LCD_RES);
|
||||||
|
HAL_Delay(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const uint8_t cmd;
|
||||||
|
const uint32_t len;
|
||||||
|
const uint8_t* data;
|
||||||
|
} lcd_init_cmds[] = {
|
||||||
|
{0x11, 0, NULL},
|
||||||
|
|
||||||
|
//ST7735R Frame Rate
|
||||||
|
{0xB1, 3, (uint8_t[]){0x01, 0x2C, 0x2D}},
|
||||||
|
{0xB2, 3, (uint8_t[]){0x01, 0x2C, 0x2D}},
|
||||||
|
{0xB3, 6, (uint8_t[]){0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D}},
|
||||||
|
|
||||||
|
// Column inversion
|
||||||
|
{0xB4, 1, (uint8_t[]){0x07}},
|
||||||
|
|
||||||
|
// ST7735R Power Sequence
|
||||||
|
{0xC0, 3, (uint8_t[]){0xA2, 0x02, 0x84}},
|
||||||
|
{0xC1, 1, (uint8_t[]){0xC5}},
|
||||||
|
{0xC2, 2, (uint8_t[]){0x0A, 0x00}},
|
||||||
|
{0xC3, 2, (uint8_t[]){0x8A, 0x2A}},
|
||||||
|
{0xC4, 2, (uint8_t[]){0x8A, 0xEE}},
|
||||||
|
|
||||||
|
// VCOM
|
||||||
|
{0xC5, 1, (uint8_t[]){0x0E}},
|
||||||
|
|
||||||
|
//MX, MY, RGB mode
|
||||||
|
{0x36, 1, (uint8_t[]){0xC8}},
|
||||||
|
|
||||||
|
// Gamma Sequence (正极性)
|
||||||
|
{0xE0, 16, (uint8_t[]){
|
||||||
|
0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22,
|
||||||
|
0x1f, 0x1b, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10
|
||||||
|
}},
|
||||||
|
|
||||||
|
// Gamma Sequence (负极性)
|
||||||
|
{0xE1, 16, (uint8_t[]){
|
||||||
|
0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e,
|
||||||
|
0x30, 0x30, 0x39, 0x3f, 0x00, 0x07, 0x03, 0x10
|
||||||
|
}},
|
||||||
|
|
||||||
|
// 设置X方向地址范围
|
||||||
|
{0x2A, 4, (uint8_t[]){0x00, 0x00, 0x00, 0x7f}},
|
||||||
|
|
||||||
|
// 设置Y方向地址范围
|
||||||
|
{0x2B, 4, (uint8_t[]){0x00, 0x00, 0x00, 0x9f}},
|
||||||
|
|
||||||
|
// 测试命令
|
||||||
|
{0xF0, 1, (uint8_t[]){0x01}}, // Enable test command
|
||||||
|
{0xF6, 1, (uint8_t[]){0x00}}, // Disable ram power save mode
|
||||||
|
|
||||||
|
// 颜色模式
|
||||||
|
{0x3A, 1, (uint8_t[]){0x05}}, // 65k mode (16-bit RGB565)
|
||||||
|
|
||||||
|
// 显示开启
|
||||||
|
{0x29, 0, NULL} // Display on
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline init_lcd() {
|
||||||
|
lcd_reset(); //Reset before LCD Init.
|
||||||
|
|
||||||
|
//LCD Init For 1.44Inch LCD Panel with ST7735R.
|
||||||
|
lcd_write_cmd(0x11, NULL, 0); //Sleep exit
|
||||||
|
HAL_Delay(120);
|
||||||
|
|
||||||
|
// 批量处理初始化序列
|
||||||
|
for (size_t i = 0; i < sizeof(lcd_init_cmds)/sizeof(lcd_init_cmds[0]); i++) {
|
||||||
|
lcd_write_cmd(lcd_init_cmds[i].cmd, lcd_init_cmds[i].data, lcd_init_cmds[i].len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开启背光 (Back Light)
|
||||||
|
GE_SET_ON(LCD_BL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lcd_set_region(int pos_x, int pos_y, int size_x, int size_y) {
|
||||||
|
#define LCD_WRITE_INDEX(data) do { \
|
||||||
|
GE_FAST_SET_OFF(LCD_CS); \
|
||||||
|
GE_FAST_SET_OFF(LCD_DC); \
|
||||||
|
lcd_write_byte(data); \
|
||||||
|
GE_FAST_SET_ON(LCD_CS); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define LCD_WRITE_DATA(data) do { \
|
||||||
|
GE_FAST_SET_OFF(LCD_CS); \
|
||||||
|
GE_FAST_SET_ON(LCD_DC); \
|
||||||
|
lcd_write_byte(data); \
|
||||||
|
GE_FAST_SET_ON(LCD_CS); \
|
||||||
|
} while(0)
|
||||||
|
const uint8_t x_start = pos_x;
|
||||||
|
const uint8_t x_end = pos_x + size_x - 1;
|
||||||
|
const uint8_t y_start = pos_y;
|
||||||
|
const uint8_t y_end = pos_y + size_y - 1;
|
||||||
|
|
||||||
|
LCD_WRITE_INDEX(0x2a);
|
||||||
|
LCD_WRITE_DATA(0x00);
|
||||||
|
LCD_WRITE_DATA(x_start+2);
|
||||||
|
LCD_WRITE_DATA(0x00);
|
||||||
|
LCD_WRITE_DATA(x_end+2);
|
||||||
|
|
||||||
|
LCD_WRITE_INDEX(0x2b);
|
||||||
|
LCD_WRITE_DATA(0x00);
|
||||||
|
LCD_WRITE_DATA(y_start+3);
|
||||||
|
LCD_WRITE_DATA(0x00);
|
||||||
|
LCD_WRITE_DATA(y_end+3);
|
||||||
|
|
||||||
|
LCD_WRITE_INDEX(0x2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcd_draw_point(ge_render_t* ctx, const ge_render_pos2_t* pos, uint16_t color) {
|
||||||
|
(void)ctx;
|
||||||
|
Assert(pos != NULL);
|
||||||
|
lcd_set_region(pos->x, pos->y, 1, 1);
|
||||||
|
|
||||||
|
GE_FAST_SET_OFF(LCD_CS);
|
||||||
|
GE_FAST_SET_ON(LCD_DC);
|
||||||
|
|
||||||
|
lcd_write_byte(color);
|
||||||
|
lcd_write_byte(color >> 8);
|
||||||
|
|
||||||
|
GE_FAST_SET_OFF(LCD_DC);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcd_draw_rect(ge_render_t* ctx, const ge_render_rect_t* rect, uint16_t color) {
|
||||||
|
(void)ctx;
|
||||||
|
const int pos_x = rect ? rect->pos.x : 0;
|
||||||
|
const int pos_y = rect ? rect->pos.y : 0;
|
||||||
|
const int size_x = rect ? rect->size.x : ctx->screen_size.x;
|
||||||
|
const int size_y = rect ? rect->size.y : ctx->screen_size.y;
|
||||||
|
const int len = size_x * size_y;
|
||||||
|
|
||||||
|
lcd_set_region(pos_x, pos_y, size_x, size_y);
|
||||||
|
|
||||||
|
// MUST SET
|
||||||
|
GE_FAST_SET_OFF(LCD_CS);
|
||||||
|
// MUST SET
|
||||||
|
GE_FAST_SET_ON(LCD_DC);
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
lcd_write_byte(color >> 8);
|
||||||
|
lcd_write_byte(color);
|
||||||
|
}
|
||||||
|
GE_FAST_SET_ON(LCD_CS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 隔行扫描(Interlaced Rendering) 或半帧缓冲(Half-Frame Buffer)
|
||||||
|
* 借鉴NES古早游戏的绘制优化策略减少闪屏和闪烁
|
||||||
|
* 重新设计绘制接口
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SCREEN_HEIGHT 128
|
||||||
|
#define SCREEN_WIDTH 128
|
||||||
|
typedef enum {
|
||||||
|
GE_RENDER_EVEN_LINES, // 渲染偶数数行
|
||||||
|
GE_RENDER_ODD_LINES, // 渲染奇数数行
|
||||||
|
} ge_render_field_t;
|
||||||
|
static struct ge_content {
|
||||||
|
uint16_t head_canary;
|
||||||
|
uint16_t screen_buffer[SCREEN_HEIGHT / 2][SCREEN_WIDTH];
|
||||||
|
uint16_t tail_canary;
|
||||||
|
} ge_content;
|
||||||
|
static ge_render_field_t current_field = GE_RENDER_EVEN_LINES;
|
||||||
|
|
||||||
|
#define CTX_BUF(ctx) (((struct ge_content*)ctx->context)->screen_buffer)
|
||||||
|
#define CTX_BUF_PTR(ctx, x, y) ((uint16_t*)CTX_BUF(ctx) + SCREEN_WIDTH * (y) + (x))
|
||||||
|
|
||||||
|
#define HEAD_CANARY 0xDEAD
|
||||||
|
#define TAIL_CANARY 0xBEEF
|
||||||
|
|
||||||
|
static int init(ge_render_t* ctx, const ge_render_pos2_t* init_screen_size) {
|
||||||
|
(void)init_screen_size;
|
||||||
|
init_lcd();
|
||||||
|
/**
|
||||||
|
* set canary
|
||||||
|
*/
|
||||||
|
((struct ge_content*)ctx->context)->head_canary = HEAD_CANARY;
|
||||||
|
((struct ge_content*)ctx->context)->tail_canary = TAIL_CANARY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flush(ge_render_t* ctx) {
|
||||||
|
AssertFmt(((struct ge_content*)ctx->context)->head_canary == HEAD_CANARY, "Invalid head canary");
|
||||||
|
AssertFmt(((struct ge_content*)ctx->context)->tail_canary == TAIL_CANARY, "Invalid tail canary");
|
||||||
|
uint16_t* buffer = ((struct ge_content*)ctx->context)->screen_buffer;
|
||||||
|
|
||||||
|
const int start_y = (current_field == GE_RENDER_EVEN_LINES) ? 0 : 1;
|
||||||
|
for (int buffer_y = 0; buffer_y < ctx->screen_size.y / 2; buffer_y++) {
|
||||||
|
const int screen_y = start_y + buffer_y * 2;
|
||||||
|
|
||||||
|
// 设置当前行区域 (1行高)
|
||||||
|
lcd_set_region(0, screen_y, ctx->screen_size.y, 1);
|
||||||
|
|
||||||
|
GE_FAST_SET_OFF(LCD_CS);
|
||||||
|
GE_FAST_SET_ON(LCD_DC);
|
||||||
|
|
||||||
|
// 传输整行数据
|
||||||
|
uint16_t* line_ptr = buffer + buffer_y * ctx->screen_size.x;
|
||||||
|
for (int x = 0; x < ctx->screen_size.x; x++) {
|
||||||
|
lcd_write_byte(*line_ptr >> 8); // 高字节
|
||||||
|
lcd_write_byte(*line_ptr & 0xFF); // 低字节
|
||||||
|
line_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
GE_FAST_SET_ON(LCD_CS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换模式
|
||||||
|
current_field = (current_field == GE_RENDER_EVEN_LINES) ?
|
||||||
|
GE_RENDER_ODD_LINES : GE_RENDER_EVEN_LINES;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int check_need_flush(ge_render_t* ctx, const ge_render_pos2_t* pos) {
|
||||||
|
const int isOdd = pos->y % 2;
|
||||||
|
const int isNeedOdd = (current_field == GE_RENDER_ODD_LINES) ? 1 : 0;
|
||||||
|
return isOdd == isNeedOdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int should_render_line(int y) {
|
||||||
|
return (y % 2) == (current_field == GE_RENDER_ODD_LINES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int buf_draw_rect(ge_render_t* ctx, const ge_render_rect_t* rect, uint16_t color) {
|
||||||
|
Assert(ctx != NULL && rect != NULL);
|
||||||
|
|
||||||
|
// 只更新属于当前场的行
|
||||||
|
for (int y = rect->pos.y; y < rect->pos.y + rect->size.y; y++) {
|
||||||
|
if (!should_render_line(y)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int x = rect->pos.x; x < rect->pos.x + rect->size.x; x++) {
|
||||||
|
*CTX_BUF_PTR(ctx, x, y / 2) = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ge_render_t ge_render = {
|
||||||
|
.context = &ge_content,
|
||||||
|
.screen_size = {
|
||||||
|
.x = 128,
|
||||||
|
.y = 128,
|
||||||
|
},
|
||||||
|
|
||||||
|
.init_func = init,
|
||||||
|
.func_flush = flush,
|
||||||
|
|
||||||
|
.func_draw_point = (ge_render_draw_point_func_t)lcd_draw_point,
|
||||||
|
.func_draw_rect = (ge_render_draw_rect_func_t)buf_draw_rect,
|
||||||
|
.func_draw_text = 0,
|
||||||
|
.func_draw_res = 0,
|
||||||
|
};
|
0
libs/ge_interface/ge_resource.c
Normal file
0
libs/ge_interface/ge_resource.c
Normal file
0
libs/ge_interface/ge_timer.c
Normal file
0
libs/ge_interface/ge_timer.c
Normal file
24
libs/ge_interface/include/ge_input.h
Normal file
24
libs/ge_interface/include/ge_input.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef __GE_INPUT_H__
|
||||||
|
#define __GE_INPUT_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct ge_input;
|
||||||
|
typedef struct ge_input ge_input_t;
|
||||||
|
typedef union ge_input_event {
|
||||||
|
void* ctx;
|
||||||
|
uintptr_t num;
|
||||||
|
} ge_input_event_t;
|
||||||
|
|
||||||
|
typedef int(*ge_input_send_func_t)(ge_input_t* ctx, ge_input_event_t event);
|
||||||
|
typedef int(*ge_input_peek_func_t)(ge_input_t* ctx, ge_input_event_t* event);
|
||||||
|
typedef int(*ge_input_recv_func_t)(ge_input_t* ctx, ge_input_event_t* event);
|
||||||
|
|
||||||
|
struct ge_input {
|
||||||
|
void* context;
|
||||||
|
ge_input_send_func_t func_send;
|
||||||
|
ge_input_peek_func_t func_peek;
|
||||||
|
ge_input_recv_func_t func_recv;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __GE_INPUT_H__
|
236
libs/ge_interface/include/ge_kfifo.h
Normal file
236
libs/ge_interface/include/ge_kfifo.h
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
/*
|
||||||
|
* A generic kernel FIFO implementation
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __GE_KFIFO_H__
|
||||||
|
#define __GE_KFIFO_H__
|
||||||
|
/**
|
||||||
|
* 仿照linux内核中的kfifo实现
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GE_MEMORY_BARRIR
|
||||||
|
#define GE_MEMORY_BARRIR() __sync_synchronize()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GE_ARRAY_SIZE
|
||||||
|
#define GE_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct __ge_kfifo {
|
||||||
|
unsigned int in;
|
||||||
|
unsigned int out;
|
||||||
|
unsigned int mask;
|
||||||
|
unsigned int esize;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define __STRUCT_GE_KFIFO(type, size) \
|
||||||
|
{ \
|
||||||
|
struct __ge_kfifo kfifo; \
|
||||||
|
type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DECLARE_KFIFO - macro to declare a fifo object
|
||||||
|
* @fifo: name of the declared fifo
|
||||||
|
* @type: type of the fifo elements
|
||||||
|
* @size: the number of elements in the fifo, this must be a power of 2
|
||||||
|
*/
|
||||||
|
#define DECLARE_GE_KFIFO(fifo, type, size, tname) struct tname __STRUCT_GE_KFIFO(type, size) fifo
|
||||||
|
|
||||||
|
#define INIT_GE_KFIFO(fifo) do { \
|
||||||
|
struct __ge_kfifo *__kfifo = &((fifo)->kfifo); \
|
||||||
|
__kfifo->in = 0; \
|
||||||
|
__kfifo->out = 0; \
|
||||||
|
__kfifo->mask = GE_ARRAY_SIZE((fifo)->buf) - 1; \
|
||||||
|
__kfifo->esize = sizeof(*((fifo)->buf)); \
|
||||||
|
__kfifo->data = (fifo)->buf; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEFINE_KFIFO - macro to define and initialize a fifo
|
||||||
|
* @fifo: name of the declared fifo datatype
|
||||||
|
* @type: type of the fifo elements
|
||||||
|
* @size: the number of elements in the fifo, this must be a power of 2
|
||||||
|
*
|
||||||
|
* Note: the macro can be used for global and local fifo data type variables.
|
||||||
|
*/
|
||||||
|
#define DEFINE_GE_KFIFO(fifo, type, size, tname) \
|
||||||
|
DECLARE_GE_KFIFO(fifo, type, size, tname) = \
|
||||||
|
(struct tname) { { \
|
||||||
|
.in = 0, \
|
||||||
|
.out = 0, \
|
||||||
|
.mask = GE_ARRAY_SIZE((fifo).buf) - 1, \
|
||||||
|
.esize = sizeof(*(fifo).buf), \
|
||||||
|
.data = (fifo).buf, \
|
||||||
|
}, { 0 } }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kfifo_size - returns the size of the fifo in elements
|
||||||
|
* @fifo: address of the fifo to be used
|
||||||
|
*/
|
||||||
|
#define ge_kfifo_size(fifo) \
|
||||||
|
((fifo)->kfifo.mask + 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kfifo_len - returns the number of used elements in the fifo
|
||||||
|
* @fifo: address of the fifo to be used
|
||||||
|
*/
|
||||||
|
#define ge_kfifo_len(fifo) \
|
||||||
|
((fifo)->kfifo.in - (fifo)->kfifo.out)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kfifo_is_empty - returns true if the fifo is empty
|
||||||
|
* @fifo: address of the fifo to be used
|
||||||
|
*/
|
||||||
|
#define ge_kfifo_is_empty(fifo) \
|
||||||
|
((fifo)->kfifo.in == (fifo)->kfifo.out)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kfifo_is_full - returns true if the fifo is full
|
||||||
|
* @fifo: address of the fifo to be used
|
||||||
|
*/
|
||||||
|
#define ge_kfifo_is_full(fifo) (ge_kfifo_len(fifo) > (fifo)->kfifo.mask)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kfifo_put - put data into the fifo
|
||||||
|
* @fifo: address of the fifo to be used
|
||||||
|
* @val: the data to be added
|
||||||
|
*
|
||||||
|
* This macro copies the given value into the fifo.
|
||||||
|
* It returns 0 if the fifo was full. Otherwise it returns the number
|
||||||
|
* processed elements.
|
||||||
|
*
|
||||||
|
* Note that with only one concurrent reader and one concurrent
|
||||||
|
* writer, you don't need extra locking to use these macro.
|
||||||
|
*/
|
||||||
|
#define ge_kfifo_put(fifo, val) do { \
|
||||||
|
unsigned int __ret; \
|
||||||
|
struct __ge_kfifo *__kfifo = &((fifo)->kfifo); \
|
||||||
|
__ret = !ge_kfifo_is_full(fifo); \
|
||||||
|
if (__ret) { \
|
||||||
|
((fifo)->buf)[__kfifo->in & __kfifo->mask] = val; \
|
||||||
|
/*smp_wmb();*/ \
|
||||||
|
GE_MEMORY_BARRIR(); \
|
||||||
|
__kfifo->in++; \
|
||||||
|
} \
|
||||||
|
/*__ret;*/ \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kfifo_get - get data from the fifo
|
||||||
|
* @fifo: address of the fifo to be used
|
||||||
|
* @val: address where to store the data
|
||||||
|
*
|
||||||
|
* This macro reads the data from the fifo.
|
||||||
|
* It returns 0 if the fifo was empty. Otherwise it returns the number
|
||||||
|
* processed elements.
|
||||||
|
*
|
||||||
|
* Note that with only one concurrent reader and one concurrent
|
||||||
|
* writer, you don't need extra locking to use these macro.
|
||||||
|
*/
|
||||||
|
#define ge_kfifo_get(fifo, val) do { \
|
||||||
|
unsigned int __ret; \
|
||||||
|
struct __ge_kfifo *__kfifo = &((fifo)->kfifo); \
|
||||||
|
__ret = !ge_kfifo_is_empty(fifo); \
|
||||||
|
if (__ret) { \
|
||||||
|
*val = ((fifo)->buf)[__kfifo->out & __kfifo->mask]; \
|
||||||
|
/*smp_wmb();*/ \
|
||||||
|
GE_MEMORY_BARRIR(); \
|
||||||
|
__kfifo->out++; \
|
||||||
|
} \
|
||||||
|
/*__ret;*/ \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kfifo_peek - get data from the fifo without removing
|
||||||
|
* @fifo: address of the fifo to be used
|
||||||
|
* @val: address where to store the data
|
||||||
|
*
|
||||||
|
* This reads the data from the fifo without removing it from the fifo.
|
||||||
|
* It returns 0 if the fifo was empty. Otherwise it returns the number
|
||||||
|
* processed elements.
|
||||||
|
*
|
||||||
|
* Note that with only one concurrent reader and one concurrent
|
||||||
|
* writer, you don't need extra locking to use these macro.
|
||||||
|
*/
|
||||||
|
#define ge_kfifo_peek(fifo, val) do { \
|
||||||
|
unsigned int __ret; \
|
||||||
|
struct __ge_kfifo *__kfifo = &((fifo)->kfifo); \
|
||||||
|
__ret = !ge_kfifo_is_empty(fifo); \
|
||||||
|
if (__ret) { \
|
||||||
|
*val = ((fifo)->buf)[__kfifo->out & __kfifo->mask]; \
|
||||||
|
/*smp_wmb();*/ \
|
||||||
|
GE_MEMORY_BARRIR(); \
|
||||||
|
} \
|
||||||
|
/*__ret;*/ \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kfifo_in - put data into the fifo
|
||||||
|
* @fifo: address of the fifo to be used
|
||||||
|
* @buf: the data to be added
|
||||||
|
* @n: number of elements to be added
|
||||||
|
*
|
||||||
|
* This macro copies the given buffer into the fifo and returns the
|
||||||
|
* number of copied elements.
|
||||||
|
*
|
||||||
|
* Note that with only one concurrent reader and one concurrent
|
||||||
|
* writer, you don't need extra locking to use these macro.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
#define kfifo_in(fifo, buf, n) \
|
||||||
|
({ \
|
||||||
|
typeof((fifo) + 1) __tmp = (fifo); \
|
||||||
|
typeof(__tmp->ptr_const) __buf = (buf); \
|
||||||
|
unsigned long __n = (n); \
|
||||||
|
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||||
|
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||||
|
(__recsize) ?\
|
||||||
|
__kfifo_in_r(__kfifo, __buf, __n, __recsize) : \
|
||||||
|
__kfifo_in(__kfifo, __buf, __n); \
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* kfifo_out - get data from the fifo
|
||||||
|
* @fifo: address of the fifo to be used
|
||||||
|
* @buf: pointer to the storage buffer
|
||||||
|
* @n: max. number of elements to get
|
||||||
|
*
|
||||||
|
* This macro gets some data from the fifo and returns the numbers of elements
|
||||||
|
* copied.
|
||||||
|
*
|
||||||
|
* Note that with only one concurrent reader and one concurrent
|
||||||
|
* writer, you don't need extra locking to use these macro.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
#define kfifo_out(fifo, buf, n) \
|
||||||
|
({ \
|
||||||
|
typeof((fifo) + 1) __tmp = (fifo); \
|
||||||
|
typeof(__tmp->ptr) __buf = (buf); \
|
||||||
|
unsigned long __n = (n); \
|
||||||
|
const size_t __recsize = sizeof(*__tmp->rectype); \
|
||||||
|
struct __kfifo *__kfifo = &__tmp->kfifo; \
|
||||||
|
(__recsize) ?\
|
||||||
|
__kfifo_out_r(__kfifo, __buf, __n, __recsize) : \
|
||||||
|
__kfifo_out(__kfifo, __buf, __n); \
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif // __GE_KFIFO_H__
|
42
libs/ge_interface/include/ge_render.h
Normal file
42
libs/ge_interface/include/ge_render.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef __GE_RENDER_H__
|
||||||
|
#define __GE_RENDER_H__
|
||||||
|
|
||||||
|
#include "ge_resource.h"
|
||||||
|
|
||||||
|
typedef int ge_render_unit_t;
|
||||||
|
typedef int ge_render_color_t;
|
||||||
|
|
||||||
|
typedef struct ge_render_pos2 {
|
||||||
|
ge_render_unit_t x;
|
||||||
|
ge_render_unit_t y;
|
||||||
|
} ge_render_pos2_t;
|
||||||
|
|
||||||
|
typedef struct ge_render_rect {
|
||||||
|
ge_render_pos2_t pos;
|
||||||
|
ge_render_pos2_t size;
|
||||||
|
} ge_render_rect_t;
|
||||||
|
|
||||||
|
struct ge_render;
|
||||||
|
typedef struct ge_render ge_render_t;
|
||||||
|
|
||||||
|
typedef int(*ge_render_init_func_t) (ge_render_t* ctx, const ge_render_pos2_t* init_screen_size);
|
||||||
|
typedef int(*ge_render_flush_func_t) (ge_render_t* ctx);
|
||||||
|
|
||||||
|
typedef int(*ge_render_draw_point_func_t) (ge_render_t* ctx, const ge_render_pos2_t* pos, ge_render_color_t color);
|
||||||
|
typedef int(*ge_render_draw_rect_func_t) (ge_render_t* ctx, const ge_render_rect_t* rect, ge_render_color_t color);
|
||||||
|
typedef int(*ge_render_draw_text_func_t) (ge_render_t* ctx, const ge_render_pos2_t* pos, const char* text);
|
||||||
|
typedef int(*ge_render_draw_resource_func_t)(ge_render_t* ctx, const ge_render_pos2_t* pos, const ge_resource_t* res);
|
||||||
|
|
||||||
|
struct ge_render {
|
||||||
|
void* context;
|
||||||
|
const ge_render_pos2_t screen_size;
|
||||||
|
ge_render_init_func_t init_func;
|
||||||
|
ge_render_flush_func_t func_flush;
|
||||||
|
|
||||||
|
ge_render_draw_point_func_t func_draw_point;
|
||||||
|
ge_render_draw_rect_func_t func_draw_rect;
|
||||||
|
ge_render_draw_text_func_t func_draw_text;
|
||||||
|
ge_render_draw_resource_func_t func_draw_res;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __GE_RENDER_H__
|
12
libs/ge_interface/include/ge_resource.h
Normal file
12
libs/ge_interface/include/ge_resource.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef __GE_RESOURCE_H__
|
||||||
|
#define __GE_RESOURCE_H__
|
||||||
|
|
||||||
|
struct ge_resource;
|
||||||
|
typedef struct ge_resource ge_resource_t;
|
||||||
|
|
||||||
|
struct ge_resource {
|
||||||
|
int type;
|
||||||
|
void* context;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __GE_RESOURCE_H__
|
23
libs/ge_interface/include/ge_timer.h
Normal file
23
libs/ge_interface/include/ge_timer.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef __GE_TIMER_H__
|
||||||
|
#define __GE_TIMER_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef uint64_t ge_time_t;
|
||||||
|
|
||||||
|
struct ge_timer;
|
||||||
|
typedef struct ge_timer ge_timer_t;
|
||||||
|
|
||||||
|
typedef void(*ge_timer_getus_func_t)(ge_timer_t* timer);
|
||||||
|
typedef void(*ge_timer_sleepus_func_t)(const ge_timer_t* timer);
|
||||||
|
typedef void(*ge_timer_getms_func_t)(ge_timer_t* timer);
|
||||||
|
typedef void(*ge_timer_sleepms_func_t)(const ge_timer_t* timer);
|
||||||
|
|
||||||
|
struct ge_timer {
|
||||||
|
ge_time_t time;
|
||||||
|
ge_timer_getms_func_t func_getms;
|
||||||
|
ge_timer_sleepms_func_t func_sleepms;
|
||||||
|
ge_timer_getus_func_t func_getus;
|
||||||
|
ge_timer_sleepus_func_t func_sleepus;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __GE_TIMER_H__
|
24
libs/logger.h
Normal file
24
libs/logger.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef __LOGGER_H__
|
||||||
|
#define __LOGGER_H__
|
||||||
|
|
||||||
|
#include "SEGGER_RTT/RTT/SEGGER_RTT.h"
|
||||||
|
#define __PYNIC_NO_STDIO__
|
||||||
|
#define _pynic_logout_printf(fmt, ...) SEGGER_RTT_printf(0, fmt, ##__VA_ARGS__)
|
||||||
|
#define _pynic_snprintf snprintf
|
||||||
|
#define _pynic_exit goto_error_handler
|
||||||
|
|
||||||
|
void Error_Handler(void);
|
||||||
|
static void goto_error_handler(int errno) {
|
||||||
|
(void)errno;
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __PYNIC_LOG_IMPLIMENT__
|
||||||
|
#include <stdio.h>
|
||||||
|
#define INIT_LOGGER() do { \
|
||||||
|
SEGGER_RTT_Init(); \
|
||||||
|
} while(0)
|
||||||
|
#endif
|
||||||
|
#include "pynic_log/pynic_log.h"
|
||||||
|
|
||||||
|
#endif // __LOGGER_H__
|
212
libs/pynic_log/README.md
Normal file
212
libs/pynic_log/README.md
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
# Pythonic_log
|
||||||
|
|
||||||
|
纯头文件的轻量化日志库,模仿 Python `logging` 标准库的设计,支持终端彩色输出,不依赖任何标准库。
|
||||||
|
|
||||||
|
## 特性亮点
|
||||||
|
|
||||||
|
- 🚀 **纯头文件实现** - 单文件集成,无需编译
|
||||||
|
- 🧩 **零依赖** - 不依赖标准库(可通过宏配置)
|
||||||
|
- 🌈 **终端彩色输出** - 内置 ANSI 颜色支持
|
||||||
|
- ⚙️ **多级日志系统** - 支持 DEBUG/INFO/WARN/ERROR/FATAL/TRACE
|
||||||
|
- 🧪 **高级断言工具** - 包含 Assert, Panie, TODO 等实用宏
|
||||||
|
- 📦 **模块化设计** - 支持多模块独立日志配置
|
||||||
|
- 🔧 **高度可配置** - 自定义输出、格式化和退出行为
|
||||||
|
|
||||||
|
## 快速入门
|
||||||
|
|
||||||
|
### 基础使用
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "pylike_log.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// 基础日志输出
|
||||||
|
LOG_INFO("Application started");
|
||||||
|
LOG_DEBUG("Debug value: %d", 42);
|
||||||
|
LOG_WARN("This is a warning");
|
||||||
|
LOG_ERROR("Something went wrong!");
|
||||||
|
|
||||||
|
// 断言工具
|
||||||
|
int value = 10;
|
||||||
|
Assert(value > 5); // 条件断言
|
||||||
|
AssertFmt(value != 0, "Value cannot be zero");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 输出示例
|
||||||
|
|
||||||
|
```shell
|
||||||
|
[INFO ] - root - main.c:8 | Application started
|
||||||
|
[DEBUG] - root - main.c:9 | Debug value: 42
|
||||||
|
[WARN ] - root - main.c:10 | This is a warning
|
||||||
|
[ERROR] - root - main.c:11 | Something went wrong!
|
||||||
|
```
|
||||||
|
|
||||||
|
## 核心功能
|
||||||
|
|
||||||
|
### 日志级别控制
|
||||||
|
|
||||||
|
```c
|
||||||
|
// 获取日志器实例
|
||||||
|
logger_t* logger = log_get("my_module");
|
||||||
|
|
||||||
|
// 设置日志级别(只显示 WARN 及以上)
|
||||||
|
log_set_level(logger, LOG_LEVEL_WARN | LOG_LEVEL_ERROR | LOG_LEVEL_FATAL);
|
||||||
|
|
||||||
|
// 模块化日志
|
||||||
|
MLOG_WARN(logger, "Module-specific warning: %s", "Low memory");
|
||||||
|
```
|
||||||
|
|
||||||
|
### 自定义日志处理器
|
||||||
|
|
||||||
|
```c
|
||||||
|
void custom_handler(
|
||||||
|
log_level_t level,
|
||||||
|
const char* module,
|
||||||
|
const char* file,
|
||||||
|
int line,
|
||||||
|
const char* message
|
||||||
|
) {
|
||||||
|
// 自定义处理逻辑(如写入文件/网络)
|
||||||
|
printf("[CUSTOM] %s:%d - %s\n", file, line, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
logger_t* logger = log_get(NULL);
|
||||||
|
log_set_handler(logger, custom_handler);
|
||||||
|
|
||||||
|
LOG_INFO("This will use custom handler");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 断言系统
|
||||||
|
|
||||||
|
```c
|
||||||
|
void critical_function(int* ptr) {
|
||||||
|
// 空指针检查
|
||||||
|
AssertFmt(ptr != NULL, "Received NULL pointer");
|
||||||
|
|
||||||
|
// 范围检查
|
||||||
|
AssertFmt(*ptr >= 0 && *ptr <= 100, "Value %d out of range", *ptr);
|
||||||
|
|
||||||
|
// 标记未实现功能
|
||||||
|
TODO(); // 触发致命错误
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置选项
|
||||||
|
|
||||||
|
### 基本配置宏
|
||||||
|
|
||||||
|
| 宏名称 | 默认值 | 描述 |
|
||||||
|
| :-------------------- | :----- | :--------------- |
|
||||||
|
| `LOGGER_MAX_BUF_SIZE` | 512 | 单条日志最大长度 |
|
||||||
|
| `__LOG_NO_COLOR__` | - | 禁用彩色输出 |
|
||||||
|
| `__NO_STDIO__` | - | 禁用标准库依赖 |
|
||||||
|
|
||||||
|
|
||||||
|
### 标准库替代(嵌入式环境)
|
||||||
|
```c
|
||||||
|
// 在包含头文件前定义这些宏
|
||||||
|
#define _pylike_logout_printf(fmt, ...) my_printf(fmt, ##__VA_ARGS__)
|
||||||
|
#define _pylike_snprintf my_snprintf
|
||||||
|
#define _pylike_exit my_exit
|
||||||
|
|
||||||
|
#include "pylike_log.h"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 颜色自定义
|
||||||
|
编辑 `pylike_color.h` 修改 ANSI 颜色代码,或定义 `__NO_PYLIKE_COLOR__` 完全禁用颜色。
|
||||||
|
|
||||||
|
## 高级用法
|
||||||
|
|
||||||
|
### 性能追踪
|
||||||
|
|
||||||
|
```c
|
||||||
|
void complex_operation() {
|
||||||
|
LOG_TRACE("Entering complex_operation");
|
||||||
|
|
||||||
|
// ... 复杂计算 ...
|
||||||
|
|
||||||
|
LOG_TRACE("Exiting complex_operation");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 致命错误处理
|
||||||
|
|
||||||
|
```c
|
||||||
|
void load_config() {
|
||||||
|
if (!config_valid) {
|
||||||
|
LOG_FATAL("Invalid configuration - aborting");
|
||||||
|
// 此处会自动调用 exit(-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 模块化日志系统
|
||||||
|
|
||||||
|
```c
|
||||||
|
// 创建模块专用日志器
|
||||||
|
logger_t network_logger;
|
||||||
|
init_logger(&network_logger, "NETWORK");
|
||||||
|
|
||||||
|
// 设置模块日志级别
|
||||||
|
log_set_level(&network_logger, LOG_LEVEL_DEBUG | LOG_LEVEL_ERROR);
|
||||||
|
|
||||||
|
// 使用模块日志
|
||||||
|
MLOG_DEBUG(&network_logger, "Connecting to %s", "192.168.1.1");
|
||||||
|
```
|
||||||
|
|
||||||
|
## API 参考
|
||||||
|
|
||||||
|
### 日志级别
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef enum log_level {
|
||||||
|
LOG_LEVEL_NOTSET = 0, // 未设置级别(继承默认配置)
|
||||||
|
LOG_LEVEL_DEBUG = 1 << 0, // 调试信息(开发阶段详细信息)
|
||||||
|
LOG_LEVEL_INFO = 1 << 1, // 常规信息(系统运行状态)
|
||||||
|
LOG_LEVEL_WARN = 1 << 2, // 警告信息(潜在问题提示)
|
||||||
|
LOG_LEVEL_ERROR = 1 << 3, // 错误信息(可恢复的错误)
|
||||||
|
LOG_LEVEL_FATAL = 1 << 4, // 致命错误(导致程序终止的严重错误)
|
||||||
|
LOG_LEVEL_TRACE = 1 << 5, // 追踪(性能追踪或者栈帧追踪)
|
||||||
|
LOG_LEVEL_ALL = 0xFF, // 全级别标志(组合所有日志级别)
|
||||||
|
} log_level_t;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 日志器结构
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef struct logger {
|
||||||
|
const char* name; // 日志器名称(用于模块区分)
|
||||||
|
log_level_t level; // 当前设置的日志级别
|
||||||
|
log_handler handler; // 日志处理回调函数
|
||||||
|
char buf[LOGGER_MAX_BUF_SIZE]; // 格式化缓冲区
|
||||||
|
} logger_t;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 核心函数
|
||||||
|
|
||||||
|
| 函数 | 描述 |
|
||||||
|
| :---------------------------------------- | :------------------- |
|
||||||
|
| `init_logger(logger_t*, const char*)` | 初始化日志器实例 |
|
||||||
|
| `log_get(const char*)` | 获取或创建日志器实例 |
|
||||||
|
| `log_set_level(logger_t*, log_level_t)` | 设置日志级别 |
|
||||||
|
| `log_set_handler(logger_t*, log_handler)` | 设置自定义日志处理器 |
|
||||||
|
|
||||||
|
## 集成指南
|
||||||
|
|
||||||
|
1. 将 `pylike_log.h` 和 `pylike_color.h` 添加到项目
|
||||||
|
2. 在需要日志的源文件中包含头文件
|
||||||
|
3. (可选)配置自定义输出函数(嵌入式系统)
|
||||||
|
4. 使用提供的日志宏记录信息
|
||||||
|
|
||||||
|
## 设计理念
|
||||||
|
|
||||||
|
- **极简主义**:单头文件实现核心功能
|
||||||
|
- **灵活性**:通过宏配置适应各种环境
|
||||||
|
- **Pythonic API**:借鉴 Python logging 的优秀设计
|
||||||
|
- **安全第一**:所有宏都使用 `do {...} while(0)` 包装
|
59
libs/pynic_log/pynic_color.h
Normal file
59
libs/pynic_log/pynic_color.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* @file color.h
|
||||||
|
* @brief ANSI终端颜色控制码定义
|
||||||
|
*
|
||||||
|
* 提供跨平台的终端文本颜色和样式控制支持
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PYNIC_TERMINAL_COLOR_H__
|
||||||
|
#define __PYNIC_TERMINAL_COLOR_H__
|
||||||
|
|
||||||
|
/// @name 前景色控制码
|
||||||
|
/// @{
|
||||||
|
#define ANSI_FG_BLACK "\33[30m" ///< 黑色前景
|
||||||
|
#define ANSI_FG_RED "\33[31m" ///< 红色前景
|
||||||
|
#define ANSI_FG_GREEN "\33[32m" ///< 绿色前景
|
||||||
|
#define ANSI_FG_YELLOW "\33[33m" ///< 黄色前景
|
||||||
|
#define ANSI_FG_BLUE "\33[34m" ///< 蓝色前景
|
||||||
|
#define ANSI_FG_MAGENTA "\33[35m" ///< 品红色前景
|
||||||
|
#define ANSI_FG_CYAN "\33[36m" ///< 青色前景
|
||||||
|
#define ANSI_FG_WHITE "\33[37m" ///< 白色前景
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @name 背景色控制码
|
||||||
|
/// @{
|
||||||
|
#define ANSI_BG_BLACK "\33[40m" ///< 黑色背景
|
||||||
|
#define ANSI_BG_RED "\33[41m" ///< 红色背景
|
||||||
|
#define ANSI_BG_GREEN "\33[42m" ///< 绿色背景
|
||||||
|
#define ANSI_BG_YELLOW "\33[43m" ///< 黄色背景
|
||||||
|
#define ANSI_BG_BLUE "\33[44m" ///< 蓝色背景
|
||||||
|
#define ANSI_BG_MAGENTA "\33[45m" ///< 品红色背景(注:原始代码此处应为45m)
|
||||||
|
#define ANSI_BG_CYAN "\33[46m" ///< 青色背景
|
||||||
|
#define ANSI_BG_WHITE "\33[47m" ///< 白色背景
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @name 文字样式控制码
|
||||||
|
/// @{
|
||||||
|
#define ANSI_UNDERLINED "\33[4m" ///< 下划线样式
|
||||||
|
#define ANSI_BOLD "\33[1m" ///< 粗体样式
|
||||||
|
#define ANSI_NONE "\33[0m" ///< 重置所有样式
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def ANSI_FMT
|
||||||
|
* @brief 安全文本格式化宏
|
||||||
|
* @param str 目标字符串
|
||||||
|
* @param fmt ANSI格式序列(可组合多个样式)
|
||||||
|
*
|
||||||
|
* @note 当定义ANSI_FMT_DISABLE时自动禁用颜色输出
|
||||||
|
* @code
|
||||||
|
* printf(ANSI_FMT("Warning!", ANSI_FG_YELLOW ANSI_BOLD));
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#ifndef ANSI_FMT_DISABLE
|
||||||
|
#define ANSI_FMT(str, fmt) fmt str ANSI_NONE ///< 启用样式包裹
|
||||||
|
#else
|
||||||
|
#define ANSI_FMT(str, fmt) str ///< 禁用样式输出
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __PYNIC_TERMINAL_COLOR_H__
|
288
libs/pynic_log/pynic_log.h
Normal file
288
libs/pynic_log/pynic_log.h
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
/**
|
||||||
|
* @file pythonic_log.h
|
||||||
|
* @brief 模仿python标准库logger的日志系统核心模块(支持多级日志、断言和异常处理)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PYNIC_LOG_H__
|
||||||
|
#define __PYNIC_LOG_H__
|
||||||
|
|
||||||
|
#ifndef __PYNIC_NO_STDIO__
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef _pynic_logout_printf
|
||||||
|
#define _pynic_logout_printf(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
#ifndef _pynic_snprintf
|
||||||
|
#define _pynic_snprintf snprintf
|
||||||
|
#endif
|
||||||
|
#ifndef _pynic_exit
|
||||||
|
#define _pynic_exit exit
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __PYNIC_NO_COLOR__
|
||||||
|
#include "pynic_color.h"
|
||||||
|
#else
|
||||||
|
#ifndef __PYNIC_LOG_NO_COLOR__
|
||||||
|
#define __PYNIC_LOG_NO_COLOR__
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PYNIC_LOGGER_MAX_BUF_SIZE
|
||||||
|
#define PYNIC_LOGGER_MAX_BUF_SIZE 512 ///< 单条日志最大缓冲区尺寸
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// #define __PYNIC_LOG_IMPLIMENT__
|
||||||
|
|
||||||
|
#ifndef _pynic_exit
|
||||||
|
#warning _pynic_exit not defined, it will make some exit not triggered
|
||||||
|
#endif
|
||||||
|
#ifndef _pynic_logout_printf
|
||||||
|
#error _pynic_logout_printf not defined so log will not work
|
||||||
|
#endif
|
||||||
|
#ifndef _pynic_snprintf
|
||||||
|
#error _pynic_logout_printf not defined so log will not work
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _PYNIC_STR(str) #str
|
||||||
|
#define PYNIC_STR(str) _PYNIC_STR(str)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 日志级别枚举
|
||||||
|
*
|
||||||
|
* 定义日志系统的输出级别和组合标志位
|
||||||
|
*/
|
||||||
|
typedef enum log_level {
|
||||||
|
LOG_LEVEL_NOTSET = 0, ///< 未设置级别(继承默认配置)
|
||||||
|
LOG_LEVEL_DEBUG = 1 << 0, ///< 调试信息(开发阶段详细信息)
|
||||||
|
LOG_LEVEL_INFO = 1 << 1, ///< 常规信息(系统运行状态)
|
||||||
|
LOG_LEVEL_WARN = 1 << 2, ///< 警告信息(潜在问题提示)
|
||||||
|
LOG_LEVEL_ERROR = 1 << 3, ///< 错误信息(可恢复的错误)
|
||||||
|
LOG_LEVEL_FATAL = 1 << 4, ///< 致命错误(导致程序终止的严重错误)
|
||||||
|
LOG_LEVEL_TRACE = 1 << 5, ///< 追踪(性能追踪或者栈帧追踪)
|
||||||
|
LOG_LEVEL_ALL = 0xFF, ///< 全级别标志(组合所有日志级别)
|
||||||
|
} log_level_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 日志处理回调函数类型
|
||||||
|
* @param level 日志级别
|
||||||
|
* @param module 模块名称(可为NULL)
|
||||||
|
* @param file 源文件名
|
||||||
|
* @param line 代码行号
|
||||||
|
* @param message 格式化后的日志消息
|
||||||
|
* @todo 待实现模块名称,输入的模块名称,都将被忽略
|
||||||
|
*/
|
||||||
|
typedef void (*pynic_log_handler)(
|
||||||
|
log_level_t level,
|
||||||
|
const char* module,
|
||||||
|
const char* file,
|
||||||
|
int line,
|
||||||
|
const char* message
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 日志器实例结构体
|
||||||
|
*
|
||||||
|
* 每个日志器实例维护独立的配置和缓冲区
|
||||||
|
*/
|
||||||
|
typedef struct logger {
|
||||||
|
const char* name; ///< 日志器名称(用于模块区分)
|
||||||
|
log_level_t level; ///< 当前设置的日志级别
|
||||||
|
pynic_log_handler handler; ///< 日志处理回调函数
|
||||||
|
char buf[PYNIC_LOGGER_MAX_BUF_SIZE]; ///< 格式化缓冲区
|
||||||
|
} logger_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化日志实例 其余参数设置为默认值
|
||||||
|
* @param[in] logger 日志器实例指针
|
||||||
|
* @param[in] name 日志器名称(NULL表示获取默认日志器名称)
|
||||||
|
*/
|
||||||
|
void init_logger(logger_t* logger, const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化日志实例
|
||||||
|
* @param[in] logger 日志器实例指针
|
||||||
|
* @param[in] name 日志器名称(NULL表示获取默认日志器名称)
|
||||||
|
* @param[in] handler 日志处理回调函数
|
||||||
|
*/
|
||||||
|
void init_logger_ex(logger_t* logger, const char* name, pynic_log_handler hander);
|
||||||
|
|
||||||
|
// TODO log_set(); 暂未实现 日志注册
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取或创建日志器实例
|
||||||
|
* @param[in] name 日志器名称(NULL表示获取默认日志器)
|
||||||
|
* @return 日志器实例指针
|
||||||
|
* @warning 若没有找到相应日志器则会返回根日志器
|
||||||
|
*/
|
||||||
|
logger_t* log_get(const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置日志级别
|
||||||
|
* @param[in] logger 目标日志器实例
|
||||||
|
* @param[in] level 要设置的日志级别(可组合多个级别)
|
||||||
|
*/
|
||||||
|
void log_set_level(logger_t* logger, log_level_t level);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置自定义日志处理器
|
||||||
|
* @param[in] logger 目标日志器实例
|
||||||
|
* @param[in] handler 自定义处理函数(NULL恢复默认处理)
|
||||||
|
*/
|
||||||
|
void log_set_handler(logger_t* logger, pynic_log_handler handler);
|
||||||
|
|
||||||
|
#ifndef LOG_MAX_MAROC_BUF_SIZE
|
||||||
|
#define LOG_MAX_MAROC_BUF_SIZE LOGGER_MAX_BUF_SIZE ///< 宏展开缓冲区尺寸
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def _LOG
|
||||||
|
* @brief 内部日志宏(供其他日志宏调用)
|
||||||
|
* @param _module_ 模块实例(NULL表示使用默认日志器)
|
||||||
|
* @param _level_ 日志级别
|
||||||
|
* @param _msg_ 格式字符串
|
||||||
|
* @param ... 可变参数列表
|
||||||
|
*/
|
||||||
|
#define _LOG(_module_, _level_, _msg_, ...) \
|
||||||
|
do { \
|
||||||
|
logger_t* _logger; \
|
||||||
|
if (_module_ == NULL) _logger = log_get(NULL); \
|
||||||
|
else _logger = _module_; \
|
||||||
|
if (_logger && _logger->handler && (_logger->level & (_level_))) { \
|
||||||
|
_pynic_snprintf(_logger->buf, sizeof(_logger->buf), (_msg_), ##__VA_ARGS__); \
|
||||||
|
_logger->handler((_level_), _logger->name, __FILE__, __LINE__, _logger->buf); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/// @name 模块日志宏
|
||||||
|
/// @{
|
||||||
|
#define MLOG_NOTSET(module, ...) _LOG(module, LOG_LEVEL_NOTSET, __VA_ARGS__) ///< 未分类日志
|
||||||
|
#define MLOG_DEBUG( module, ...) _LOG(module, LOG_LEVEL_DEBUG, __VA_ARGS__) ///< 调试日志(需启用DEBUG级别)
|
||||||
|
#define MLOG_INFO( module, ...) _LOG(module, LOG_LEVEL_INFO, __VA_ARGS__) ///< 信息日志(常规运行日志)
|
||||||
|
#define MLOG_WARN( module, ...) _LOG(module, LOG_LEVEL_WARN, __VA_ARGS__) ///< 警告日志(潜在问题)
|
||||||
|
#define MLOG_ERROR( module, ...) _LOG(module, LOG_LEVEL_ERROR, __VA_ARGS__) ///< 错误日志(可恢复错误)
|
||||||
|
#define MLOG_FATAL( module, ...) _LOG(module, LOG_LEVEL_FATAL, __VA_ARGS__) ///< 致命错误日志(程序终止前)
|
||||||
|
#define MLOG_TRACE( module, ...) _LOG(module, LOG_LEVEL_TRACE, __VA_ARGS__) ///< 追踪日志(调用栈跟踪)
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @name 快捷日志宏
|
||||||
|
/// @{
|
||||||
|
#define LOG_NOTSET(...) _LOG(NULL, LOG_LEVEL_NOTSET, __VA_ARGS__) ///< 未分类日志
|
||||||
|
#define LOG_DEBUG(...) _LOG(NULL, LOG_LEVEL_DEBUG, __VA_ARGS__) ///< 调试日志(需启用DEBUG级别)
|
||||||
|
#define LOG_INFO(...) _LOG(NULL, LOG_LEVEL_INFO, __VA_ARGS__) ///< 信息日志(常规运行日志)
|
||||||
|
#define LOG_WARN(...) _LOG(NULL, LOG_LEVEL_WARN, __VA_ARGS__) ///< 警告日志(潜在问题)
|
||||||
|
#define LOG_ERROR(...) _LOG(NULL, LOG_LEVEL_ERROR, __VA_ARGS__) ///< 错误日志(可恢复错误)
|
||||||
|
#define LOG_FATAL(...) _LOG(NULL, LOG_LEVEL_FATAL, __VA_ARGS__) ///< 致命错误日志(程序终止前)
|
||||||
|
#define LOG_TRACE(...) _LOG(NULL, LOG_LEVEL_TRACE, __VA_ARGS__) ///< 追踪日志(调用栈跟踪)
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def _Assert
|
||||||
|
* @brief 断言检查内部宏
|
||||||
|
* @param cond 检查条件表达式
|
||||||
|
* @param ... 错误信息参数(格式字符串+参数)
|
||||||
|
*/
|
||||||
|
#define _Assert(cond, ...) \
|
||||||
|
do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
LOG_FATAL(__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/// @name 断言工具宏
|
||||||
|
/// @{
|
||||||
|
#define AssertFmt(cond, format, ...) _Assert(cond, "Assertion Failure: " format, ## __VA_ARGS__) ///< 带格式的断言检查
|
||||||
|
#define PanicFmt(format, ...) _Assert(0, "Panic: " format, ## __VA_ARGS__) ///< 立即触发致命错误
|
||||||
|
#ifndef Assert
|
||||||
|
#define Assert(cond) AssertFmt(cond, "cond is `" PYNIC_STR(cond) "`") ///< 基础断言检查
|
||||||
|
#endif
|
||||||
|
#define Panic(...) PanicFmt(__VA_ARGS__) ///< 触发致命错误(带自定义消息)
|
||||||
|
#define TODO() PanicFmt("TODO please implement me") ///< 标记未实现代码(触发致命错误)
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
static inline const char* pynic_level_str(log_level_t level) {
|
||||||
|
const char* level_str;
|
||||||
|
switch (level) {
|
||||||
|
case LOG_LEVEL_DEBUG: level_str = "DEBUG"; break;
|
||||||
|
case LOG_LEVEL_INFO: level_str = "INFO "; break;
|
||||||
|
case LOG_LEVEL_WARN: level_str = "WARN "; break;
|
||||||
|
case LOG_LEVEL_ERROR: level_str = "ERROR"; break;
|
||||||
|
case LOG_LEVEL_FATAL: level_str = "FATAL"; break;
|
||||||
|
case LOG_LEVEL_TRACE: level_str = "TRACE"; break;
|
||||||
|
default: level_str = "NOTSET"; break;
|
||||||
|
}
|
||||||
|
return level_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __PYNIC_TERMINAL_COLOR_H__
|
||||||
|
static inline const char* pynic_level_color(log_level_t level) {
|
||||||
|
const char* color_code = ANSI_NONE;
|
||||||
|
switch (level) {
|
||||||
|
case LOG_LEVEL_DEBUG: color_code = ANSI_FG_CYAN; break;
|
||||||
|
case LOG_LEVEL_INFO: color_code = ANSI_FG_GREEN; break;
|
||||||
|
case LOG_LEVEL_TRACE: color_code = ANSI_FG_BLUE; break;
|
||||||
|
case LOG_LEVEL_WARN: color_code = ANSI_FG_YELLOW; break;
|
||||||
|
case LOG_LEVEL_ERROR: color_code = ANSI_FG_RED; break;
|
||||||
|
case LOG_LEVEL_FATAL: color_code = ANSI_FG_RED ANSI_UNDERLINED; break; // 增强对比度
|
||||||
|
default: color_code = ANSI_NONE;
|
||||||
|
}
|
||||||
|
return color_code;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PYNIC_LOG_IMPLIMENT__
|
||||||
|
|
||||||
|
static void __pynic_log_default_handler(log_level_t level, const char* module, const char* file, int line, const char* message) {
|
||||||
|
const char* level_str = pynic_level_str(level);
|
||||||
|
|
||||||
|
/// @note: 定义 __PYNIC_LOG_NO_COLOR__ 会取消颜色输出
|
||||||
|
#ifndef __PYNIC_LOG_NO_COLOR__
|
||||||
|
_pynic_logout_printf(ANSI_BOLD "%s[%s] - %s - %s:%d | %s" ANSI_NONE "\n",
|
||||||
|
pynic_level_color(level), level_str, module, file, line, message);
|
||||||
|
#else
|
||||||
|
_pynic_logout_printf("[%s] %s:%d | %s: %s\n",
|
||||||
|
level_str, file, line, module, message);
|
||||||
|
#endif
|
||||||
|
if (level & LOG_LEVEL_FATAL) {
|
||||||
|
_pynic_exit(-LOG_LEVEL_FATAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static logger_t __pynic_root_logger = {
|
||||||
|
.name = "root",
|
||||||
|
.level = LOG_LEVEL_ALL,
|
||||||
|
.handler = __pynic_log_default_handler,
|
||||||
|
};
|
||||||
|
|
||||||
|
void init_logger(logger_t* logger, const char* name) {
|
||||||
|
init_logger_ex(logger, name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_logger_ex(logger_t* logger, const char* name, pynic_log_handler hander) {
|
||||||
|
logger->name = name;
|
||||||
|
logger->handler = hander ? hander : __pynic_log_default_handler;
|
||||||
|
log_set_level(logger, LOG_LEVEL_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger_t* log_get(const char* name) {
|
||||||
|
if (name == NULL) return &__pynic_root_logger;
|
||||||
|
return &__pynic_root_logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_set_level(logger_t* logger, log_level_t level) {
|
||||||
|
if (logger) logger->level = level;
|
||||||
|
else __pynic_root_logger.level = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_set_handler(logger_t* logger, pynic_log_handler handler) {
|
||||||
|
if (logger) logger->handler = handler;
|
||||||
|
else __pynic_root_logger.handler = handler;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __PYNIC_LOG_H__
|
Reference in New Issue
Block a user