STM32的 syscalls.c 和 sysmem.c

syscalls.c 是 STM32CubeIDE 自動生成的標準系統調用適配文件,用于裸機環境下支持 newlib 標準庫(如 printf, scanf, malloc)的運行。這份文件提供了標準庫運行所需的最小系統調用實現。現在我來逐段解析其作用,并補充你可能需要修改或關注的地方。


🧩 主要用途

該文件讓 標準C庫函數 在沒有操作系統的 STM32 環境中可以正常工作。特別是:

  • printf() 調用 _write()(需要重定向到串口)
  • scanf() 調用 _read()(需要接收串口輸入)
  • malloc() 依賴 _sbrk()(位于另一個文件 sysmem.c 中)

📄 文件結構解析

🔹 引入的頭文件

#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>

用于提供標準類型定義和錯誤碼,支持不同系統調用的原型和實現。


🔹 環境變量(通常忽略)

char *__env[1] = { 0 };
char **environ = __env;

🔹 核心系統調用函數(重點)

1. _write(): 用于 printf
__attribute__((weak)) int _write(int file, char *ptr, int len)
{(void)file;for (int i = 0; i < len; i++)__io_putchar(*ptr++);return len;
}

?? __io_putchar()弱函數(weak),你需要在項目中自己實現這個函數,常用于串口重定向:

int __io_putchar(int ch)
{HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);return ch;
}
2. _read(): 用于 scanf
__attribute__((weak)) int _read(int file, char *ptr, int len)
{for (int i = 0; i < len; i++)*ptr++ = __io_getchar();return len;
}

你也需實現 __io_getchar(),如:

int __io_getchar(void)
{uint8_t ch;HAL_UART_Receive(&huart2, &ch, 1, HAL_MAX_DELAY);return ch;
}

🔹 其他系統調用(通常不使用,但需要實現以避免鏈接錯誤)

這些函數都是 dummy 實現(返回錯誤碼),用于滿足編譯要求:

函數用途/說明
_exit()程序退出,死循環防止退出
_kill()假設無信號機制,返回錯誤
_getpid()返回 PID 1,占位
_close()文件關閉,占位
_fstat()標識為字符設備
_isatty()判斷文件是否為終端,返回1
_lseek()文件定位,占位
_open()打開文件,占位
_unlink()刪除文件,占位
_fork()無進程管理,占位
_execve()不支持執行程序
_wait()無子進程支持,占位
_times()占位
_link()占位
_stat()占位

? 如何啟用 UART 輸出功能?

  1. 確保開啟 UART(比如 USART2)并啟用 HAL_UART_Transmit
  2. 添加以下函數實現(在 main.c 或獨立 retarget.c 文件)
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);return ch;
}int __io_getchar(void)
{uint8_t ch;HAL_UART_Receive(&huart2, &ch, 1, HAL_MAX_DELAY);return ch;
}

📝 如果你想改為 fputc() 重定向,也可以用以下方式:

int fputc(int ch, FILE *f)
{HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);return ch;
}

不過 __io_putchar 更適合與 CubeIDE 生成的 syscalls.c 搭配使用。


🔚 總結

方面內容
是否需要改動?如果你要使用 printf/scanf,是的!
推薦修改點實現 __io_putchar__io_getchar
使用 HAL_UART 示例?是,可用于 STM32 串口輸出

你提供的 sysmem.c 是 STM32CubeIDE 自動生成的內存分配支持文件,主要目的是實現標準 C 庫 malloc 系列函數所依賴的 _sbrk() 系統調用。

這是嵌入式裸機編程中用于支持動態內存分配的 標準方法


🔍 核心作用:實現 _sbrk()

? _sbrk(ptrdiff_t incr) 說明

該函數負責從 RAM 中劃出堆空間。

void *_sbrk(ptrdiff_t incr)
  • incr: 要增加的堆大小(單位:字節)
  • 返回值: 成功時返回舊的堆尾地址,失敗返回 (void *) -1 并設置 errno = ENOMEM

🧠 工作原理

它通過鏈接腳本中的符號 _end, _estack, _Min_Stack_Size 來判斷內存邊界:

 RAM 起始地址 → [.data][.bss][heap → → →] ... [stack] ← ← ← ← ← _estack(RAM末端)↑       ↑_end   _estack
  • __sbrk_heap_end:當前堆的“末尾指針”
  • _end:鏈接腳本中定義的 靜態數據段結束地址(堆的起始)
  • _estack:RAM 頂部(棧的起點)
  • _Min_Stack_Size:為主堆棧指針(MSP)保留的空間,避免棧和堆沖突

?? 如果你用的是默認 STM32CubeIDE 生成的 .ld 鏈接腳本,這些符號是自動生成的,你無需手動添加。


🧩 鏈接腳本中通常有以下內容(例如):

  ._user_heap_stack :{. = ALIGN(8);PROVIDE ( end = . );PROVIDE ( _end = . );. = . + _Min_Heap_Size;. = . + _Min_Stack_Size;. = ALIGN(8);} >RAM

?? 如果你使用 malloc() 報錯或崩潰…

  1. 確保鏈接器腳本中定義了 _end, _estack, _Min_Stack_Size

  2. 確保在 sysmem.c_sbrk() 沒有超出 max_heap

  3. 調整堆棧大小:STM32CubeIDE 中修改:

    Project -> Properties -> C/C++ Build -> Settings -> Tool Settings -> MCU Settings
    
    • 增大 Heap size
    • 調整 Stack size

? 示例:在 STM32 中使用 malloc()

#include <stdlib.h>char *buf = malloc(100);
if (!buf) {// 分配失敗,內存不足
}

該調用會通過 malloc()sbrk() 來從 RAM 中申請空間


📝 總結

項目內容
文件作用支持 malloc 的底層實現
關鍵函數_sbrk()
內存邊界判斷依據_end, _estack, _Min_Stack_Size
錯誤處理堆超出棧保留區時返回 ENOMEM

Makefile 中用于鏈接(linking)的部分配置,主要用來指導 GCC 如何鏈接目標文件、庫文件和鏈接腳本。

我們來逐項解釋這幾行內容。


🔍 內容逐行解析

# libraries
LIBS = -lc -lm -lnosys 
  • -lc:鏈接標準 C 庫(libc)
  • -lm:鏈接數學庫(libm),例如支持 sin, cos, sqrt
  • -lnosys:鏈接 libnosys.a,這是一個提供最小系統調用樁函數的庫(避免鏈接錯誤)
LIBDIR = 
  • 沒設置額外的庫搜索目錄
LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) \-Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref \-Wl,--gc-sections

這是構造鏈接參數的完整語句,分解如下:

參數說明
$(MCU)MCU 相關的 GCC 參數(如 -mcpu=cortex-m4 -mthumb
-specs=nano.specs使用輕量級 nano newlib(newlib-nano),適合嵌入式系統
-T$(LDSCRIPT)指定鏈接腳本路徑,例如 stm32f4xx.ld
$(LIBDIR)庫目錄參數(未定義時留空)
$(LIBS)鏈接所需的庫,如 -lc, -lm, -lnosys
-Wl,-Map=...ld 生成 .map 文件,幫助查看內存布局和符號
--cref.map 文件中啟用交叉引用
--gc-sections丟棄未使用的段,減小最終二進制體積

🔧 舉例:使用這些參數生成固件

假設你運行 arm-none-eabi-gcc 手動鏈接:

arm-none-eabi-gcc main.o startup_stm32f4xx.o \-mcpu=cortex-m4 -mthumb \-specs=nano.specs \-Tstm32f4xx.ld \-lc -lm -lnosys \-Wl,-Map=output.map,--cref \-Wl,--gc-sections \-o firmware.elf

? 關于 -lnosys 的補充

  • libnosys.anewlib 提供的最小系統調用實現庫。
  • 它中斷了 exit(), _kill(), _getpid() 等函數的調用鏈。
  • 通常你會通過 syscalls.c 或自己實現 _write(), _sbrk() 來覆蓋它。

? 關于 -specs=nano.specs

  • 它會讓 gcc 使用 libc_nano.alibg_nano.a
  • 這是為嵌入式優化的版本,更小但功能有限,適用于 STM32、ARM Cortex-M 等資源受限環境。

🧠 提示

如果你想使用 printf() 的浮點功能(在 nano.specs 下默認關閉),你需要額外加:

-Wl,-u,_printf_float

或在 LDFLAGS 中加:

LDFLAGS += -Wl,-u,_printf_float

? 總結

用途
-lnosys提供默認的空系統調用,避免鏈接錯誤(可被用戶定義的 _write 等函數替代)
-specs=nano.specs使用輕量 newlib 版本,適合嵌入式
-T$(LDSCRIPT)指定 .ld 鏈接腳本路徑
-Wl,--gc-sections去掉未用段,減小大小
-Map=...生成 map 文件,調試內存和符號使用情況

USE_NEWLIB_REENTRANT(或在 FreeRTOSConfig.h 中叫 configUSE_NEWLIB_REENTRANT)是一個和 FreeRTOS + newlib 標準 C 庫 集成相關的重要配置項,確實需要謹慎使用。


🧠 什么是 USE_NEWLIB_REENTRANT

簡單說:

它表示是否為每個 FreeRTOS 任務分配一個 獨立的 newlib 重入結構體 struct _reent,以支持 線程安全的標準 C 函數(如 printf, malloc 等)


🔧 背景:newlib 是單線程庫

標準的 newlib(ARM GCC 默認使用的 C 標準庫)不是線程安全的。比如:

  • 全局變量 errno
  • 全局堆指針
  • malloc() / free()

如果多任務同時調用這些函數,可能發生內存損壞或數據錯亂


? 設置 configUSE_NEWLIB_REENTRANT = 1 的作用

啟用后:

  • FreeRTOS 會為每個任務分配一個獨立的 struct _reent
  • 標準庫中的函數會使用當前任務的 reent 結構
  • 保證 malloc()errnoprintf() 等的線程安全性

?? 警告與注意事項

? 1. 你必須使用 newlib-nanonewlib

啟用 configUSE_NEWLIB_REENTRANT = 1 的前提是你項目確實在使用 newlib,否則會報錯:

cannot open source file "reent.h"

如果你沒有用 -specs=nano.specs-lc 之類的 newlib 庫,啟用這個配置毫無意義還會出錯。


? 2. 你必須提供必要的系統調用(_sbrk, _write, 等)

CubeMX 會生成 syscalls.c/sysmem.c,你必須保留它們。

否則 malloc()printf() 就無法工作。


? 3. 你可能還需要實現 __malloc_lock()__malloc_unlock()

如果你使用的是 full newlib(不是 nano 版),malloc 默認是非線程安全的,除非你實現:

void __malloc_lock(struct _reent *r) {taskENTER_CRITICAL(); // 或者使用 mutex
}void __malloc_unlock(struct _reent *r) {taskEXIT_CRITICAL();
}

🔍 啟用方式

FreeRTOSConfig.h 中加上:

#define configUSE_NEWLIB_REENTRANT 1

然后確保:

  • 編譯器鏈接了 newlib/newlib-nano(一般 -lc -lrdimon -lnosys
  • syscalls.csysmem.c
  • 編譯器路徑中包含了 reent.h(通常自動包含)

? 不建議隨意啟用的原因

官方警告你很清楚:

?? “FreeRTOS does not use newlib itself. If you enable reentrancy, you are responsible for making it work safely.”

啟用后:

  • 系統內存占用增加(每個任務增加 struct _reent
  • 鎖管理交給你自己實現
  • 如果你不理解 mallocerrno 的底層行為,很容易出錯

? 總結

配置項作用
configUSE_NEWLIB_REENTRANT = 1每個任務都有獨立 reent 結構,支持線程安全 newlib
啟用前需滿足說明
使用 newlib 庫鏈接 -lc(默認是)或 -specs=nano.specs
包含 reent.h 頭文件通常自動包含于 newlib
提供系統調用(如 _sbrk()用于 malloc
了解線程安全需求特別是 __malloc_lock()

當你在 STM32CubeMX 中啟用了 FreeRTOS,它可能會在“Project Report”或生成代碼時提示你:

提示:configUSE_NEWLIB_REENTRANT is enabled. You must ensure newlib is thread-safe and syscalls are implemented properly.


這是一個 重要但非致命 的提示,意思是你需要為啟用 configUSE_NEWLIB_REENTRANT = 1額外準備工作。下面是詳細解釋和應對方法:


🔍 提示含義詳解

當你在 CubeMX 中啟用

Use Newlib reentrant

它就會在生成的 FreeRTOSConfig.h 中添加:

#define configUSE_NEWLIB_REENTRANT 1

并提示你:你必須確保系統環境滿足 Newlib 多線程安全運行的條件,否則可能引發運行時錯誤。


? 要做的準備(否則會踩坑)

條件說明
? 使用 newlib 標準版 而非 nanonano 是精簡版,不完整支持線程安全結構
? 正確實現了 syscalls,如 _sbrk(), _write()否則 malloc()printf() 等會失效
? 每個任務堆棧空間足夠(通常 ≥ 256 字節)否則 newlib 的 _reent 結構體無法分配
? heap_3.c 要求線程鎖保護 malloc()推薦改用 heap_useNewlib.cheap_4.c

🛠 關鍵實現步驟

① 項目設置中使用 full newlib

在 STM32CubeIDE 中:

  • Project > Properties > C/C++ Build > Settings
  • 進入 Tool Settings > MCU GCC Linker > Libraries
  • ? 取消勾選 Use newlib-nano (--specs=nano.specs)
  • ?? 保留或添加 --specs=nosys.specs

② 實現系統調用 syscalls.c(如果還沒有)

你需要提供如下函數,至少要包括:

void *_sbrk(ptrdiff_t incr);     // 用于 malloc 內存擴展
int _write(int file, char *ptr, int len);  // 用于 printf 輸出

? 示例 _sbrk() 實現:

extern char _end; // Defined in linker script
static char *heap_end;void *_sbrk(ptrdiff_t incr) {char *prev_heap_end;if (heap_end == 0)heap_end = &_end;prev_heap_end = heap_end;heap_end += incr;return (void *) prev_heap_end;
}

③ 使用線程安全的 malloc() 方案(可選)

如果你使用 heap_3.c(基于標準 malloc),你需要啟用鎖支持,否則多個任務調用會沖突。

? 更好的方式:

  • 使用 heap_useNewlib.c(基于 Dave Nadler 的線程安全 malloc)
  • 或使用 heap_4.c + pvPortMalloc() 替代系統 malloc

? 示例配置(FreeRTOSConfig.h)

#define configUSE_NEWLIB_REENTRANT 1
#define configTOTAL_HEAP_SIZE     (10 * 1024)

? 示例任務(帶 printf)

void TaskPrint(void *pvParameters) {while (1) {printf("Hello from task %s\n", pcTaskGetName(NULL));vTaskDelay(pdMS_TO_TICKS(1000));}
}

? 如何驗證配置正確

測試正常現象
printf() 在多個任務中輸出沒有亂碼、不會崩潰
malloc() 在任務中使用分配正常、無崩潰
errno 在任務間隔離每個任務 errno 不沖突

📌 總結

這條提示的真正含義是:

啟用了線程安全支持后,你必須確保 newlib 運行環境完整、堆/棧足夠、syscalls 正確、malloc 線程安全,否則系統將不可預期。


當啟用configUSE_NEWLIB_REENTRANT后,每個任務的棧空間需求會顯著增加,因為需要為每個任務分配獨立的C庫上下文。

棧空間需求

基本推薦值

// 最小棧大小建議
#define configMINIMAL_STACK_SIZE    ((unsigned short)512)  // 2KB (512 * 4字節)// 實際任務棧大小建議
xTaskCreate(TaskFunction, "TaskName", 1024,        // 4KB棧空間NULL, Priority, &TaskHandle);

不同使用場景的棧大小

1. 簡單任務(只有基本操作)

#define SIMPLE_TASK_STACK_SIZE    512   // 2KB

2. 使用printf/sprintf的任務

#define PRINTF_TASK_STACK_SIZE    1024  // 4KB

3. 使用malloc/free的任務

#define MALLOC_TASK_STACK_SIZE    1024  // 4KB

4. 使用文件系統操作的任務

#define FILE_TASK_STACK_SIZE      2048  // 8KB

棧空間增加的原因

啟用configUSE_NEWLIB_REENTRANT后增加的開銷包括:

  1. struct _reent結構體:約400-600字節
  2. I/O緩沖區:printf等函數的緩沖區
  3. malloc堆管理:每個任務的堆狀態信息
  4. 錯誤處理:errno等錯誤狀態

實際測試建議

// 棧使用情況檢查
void vTaskStackCheck(void)
{UBaseType_t uxHighWaterMark;// 獲取任務剩余棧空間uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);printf("Stack remaining: %d words\n", uxHighWaterMark);
}

優化建議

1. 根據實際需求調整

// 不同任務使用不同棧大小
xTaskCreate(SimpleTask, "Simple", 512, NULL, 1, NULL);    // 2KB
xTaskCreate(PrintfTask, "Printf", 1024, NULL, 1, NULL);   // 4KB
xTaskCreate(FileTask, "File", 2048, NULL, 1, NULL);       // 8KB

2. 使用棧監控

// 在FreeRTOSConfig.h中啟用
#define configCHECK_FOR_STACK_OVERFLOW  2

3. 考慮關閉可重入支持

如果RAM緊張,可以考慮:

#define configUSE_NEWLIB_REENTRANT 0

然后使用互斥鎖保護共享資源。

總結

  • 最小推薦:512 words (2KB)
  • 安全推薦:1024 words (4KB)
  • 重度使用:2048 words (8KB)

建議從4KB開始,然后根據實際的棧使用情況進行調整。記住要定期檢查棧的高水位標記,確保沒有棧溢出的風險。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/87580.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/87580.shtml
英文地址,請注明出處:http://en.pswp.cn/web/87580.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java零基礎筆記01(JKD及開發工具IDEA安裝配置)

1.Java簡介 Java是一種廣泛使用的計算機編程語言&#xff0c;由美國的Sun Microsystems公司&#xff08;Stanford University Network&#xff09;在1995年推出。Java以其跨平臺、面向對象、安全性高等特點&#xff0c;廣泛應用于企業級應用開發、移動應用開發等領域。2009年&a…

Spark SQL架構及高級用法

Spark SQL 架構概述 架構核心組件 API層&#xff08;用戶接口&#xff09; 輸入方式&#xff1a;SQL查詢&#xff1b;DataFrame/Dataset API。統一性&#xff1a; 所有接口最終轉換為邏輯計劃樹&#xff08;Logical Plan&#xff09;&#xff0c;進入優化流程。 編譯器層&…

【機器學習深度學習】什么是下游任務模型?

目錄 前言 一、什么是下游任務模型&#xff1f; 二、為什么需要下游任務模型&#xff1f; 三、下游任務模型都在干嘛&#xff1f; 四、下游模型怎么訓練出來的&#xff1f; 五、圖解理解&#xff1a;上游 vs 下游 六、一個現實案例&#xff1a;BERT做情感分析 原始數據…

補充:問題:CORS ,前后端訪問跨域問題

補充&#xff1a;問題&#xff1a;CORS &#xff0c;前后端訪問跨域問題 我這邊的解決方法是&#xff1a; myAxios.defaults.withCredentials true; // 配置為true&#xff0c;表示前端向后端發送請求的時候&#xff0c;需要攜帶上憑證cookie整體的&#xff1a; import axio…

洛谷 P13014 [GESP202506 五級] 最大公因數-普及-

題目描述 對于兩個正整數 a,ba,ba,b&#xff0c;他們的最大公因數記為 gcd?(a,b)\gcd(a,b)gcd(a,b)。對于 k>3k > 3k>3 個正整數 c1,c2,…,ckc_1,c_2,\dots,c_kc1?,c2?,…,ck?&#xff0c;他們的最大公因數為&#xff1a; gcd?(c1,c2,…,ck)gcd?(gcd?(c1,c2,……

前端-CSS-day1

目錄 1、初識CSS 2、CSS引入方式 3、標簽選擇器 4、類選擇器 5、id選擇器 6、通配符選擇器 7、畫盒子 8、字體大小 9、字體粗細 10、字體傾斜 11、行高 12、行高-垂直居中 13、字體族 14、font屬性 15、文本縮進 16、文本對齊方式 17、圖片對齊方式 18、文本…

解鎖萬能文件內容提取器:Apache Tika

01 引言 在日常工作中&#xff0c;你是否曾為這些場景頭疼過&#xff1f; 堆積如山的PDF、Word、Excel文檔&#xff0c;如何快速提取關鍵信息&#xff1f;用戶上傳的文件五花八門&#xff0c;如何自動識別類型并安全處理&#xff1f;構建搜索引擎時&#xff0c;如何讓系統“讀懂…

gemini-cli初體驗

目錄 準備配置環境變量運行使用基礎使用配置MCP調用MCP 參考 準備 NodeJS 18版本 配置環境變量 設置GEMINI_API_KEY 變量&#xff0c;在https://aistudio.google.com/apikey創建key 設置代理&#xff08;可選&#xff0c;取決于您的網絡&#xff09;,不配置可能會報錯 api e…

Java --類變量和類方法--main語句

1. 類變量和類方法 介紹&#xff1a; 類變量也叫靜態變量/靜態屬性&#xff0c;是該類的所有對象共享的變量&#xff0c;任何一個該類的對象去訪問它時&#xff0c;取到的都是相同的值&#xff0c;同樣任何一個該類的對象去修改它時&#xff0c;修改的也是同一個變量。 語法…

spring boot項目配置使用minion

一. Minio概述 Minio是一款開源的高性能對象存儲服務,兼容Amazon S3 API,適用于私有云、混合云及邊緣計算場景。它采用分布式架構設計,支持水平擴展,提供數據加密、版本控制、生命周期管理等企業級功能,適用于存儲非結構化數據(如圖片、視頻、日志等)。 核心特性 S3兼…

<5>_Linux進程控制

目錄 一&#xff0c;進程創建&#xff0c;fork/vfork 1&#xff0c;fork創建子進程&#xff0c;操作系統都做了什么 2&#xff0c;寫時拷貝的做了什么 二&#xff0c;進程終止&#xff0c;echo $&#xff1f; 1&#xff0c;進程終止時&#xff0c;操作系統做了什么 2&…

阿里云服務器正確配置 Docker 國內鏡像的方法

&#x1f4e6; 原理說明&#xff1a;什么是“Docker 鏡像加速器”&#xff1f; Docker 默認會從官方倉庫 registry-1.docker.io 拉取鏡像。由于網絡原因&#xff0c;在中國大陸訪問這個地址較慢甚至失敗。 鏡像加速器的作用是&#xff1a; 在國內部署一個緩存服務器&#xf…

PH熱榜 | 2025-07-05

1. todai 標語&#xff1a;你的第一份個性化快樂生活指數 介紹&#xff1a;Todai 是你個人的人工智能助手&#xff0c;幫助你獲得心理清晰和情感平衡。你可以隨時隨地記錄自己的情緒&#xff0c;發現情緒變化的規律&#xff0c;并獲取基于科學的工具。 產品網站&#xff1a;…

c++ duiLib環境集成

duiLib的Github鏈接&#xff1a;https://github.com/duilib/duilib 使用vcpkg快速安裝duilib以及配置。步驟如下&#xff1a; 1、用git下載vcpkg&#xff0c;下載報錯&#xff0c;這個錯誤通常表明在Git克隆過程中&#xff0c;與GitHub服務器的SSL連接被意外重置。改用http下…

一項基于粒子圖像測速PIV系統的泥石流模擬沖擊實驗

1實驗背景 全國進入“七下八上”防汛關鍵期&#xff0c;泥石流作為山區常見地質災害&#xff0c;突發性強&#xff0c;破壞力大&#xff0c;對人民群眾生命財產安全造成威脅&#xff0c;傳統觀測手段難以實現對碎石運動軌跡與水流場耦合效應的精細觀測。而粒子圖像測速PIV技術…

ADAS功能介紹

ADAS功能介紹 ADAS&#xff08;Advanced Driving Assistance System&#xff09;高級駕駛輔助系統&#xff0c;可分為如下幾大類功能。 IA&#xff08;Information Assist&#xff09;信息輔助類 IA類功能&#xff0c;均不包含駕駛行為的控制。這些功能又可以進一步細分為三…

【LUT技術專題】CLUT代碼講解

本文是對CLUT技術的代碼講解&#xff0c;原文解讀請看CLUT文章講解。 1、原文概要 CLUT利用矩陣在保持3DLUT映射能力的前提下顯著降低了參數量。整體流程如下所示。 整體還是基于3D-LUT的框架&#xff0c;只不過添加了一個壓縮自適應的變換矩陣。作者使用的損失函數在3DLUT的…

在LinuxMint 22.1(Ubuntu24.04)上安裝使用同花順遠航版

剛剛在LinuxMint 22.1(Ubuntu24.04)安裝完成同花順遠航版&#xff0c;體驗特別好&#xff0c;忍不住要及時給深受Linux平臺無好用行情軟件之苦的朋友們進行分享了。在此之前我一直只能用同花順Linux原生版的行情軟件&#xff0c;但是該軟件只有很基本的行情功能&#xff0c;而且…

解決vue3路由配合Transition時跳轉導致頁面不渲染的問題

問題復現 <router-view v-slot"{ Component, route }"><transition name"fade" mode"out-in"><keep-alive><component :is"Component" :key"route.path" /></keep-alive></transition>…

java: 無法訪問org.springframework.boot.SpringApplication,類文件具有錯誤的版本 61.0, 應為 52.0

問題 java: 無法訪問org.springframework.boot.SpringApplication 錯誤的類文件: /D:/.m2/repository/org/springframework/boot/spring-boot/3.3.13/spring-boot-3.3.13.jar!/org/springframework/boot/SpringApplication.class 類文件具有錯誤的版本 61.0, 應為 52.0 請刪除…