From 59c11f3f937408ec7ff3972a84335a5dbf11fd69 Mon Sep 17 00:00:00 2001 From: yuquanjun Date: Thu, 10 Sep 2026 06:51:32 +0800 Subject: [PATCH] Fix BT recv stack smash and harden pitch/chord SysEx paths. Enlarge BT recv stack, move large handlers/log buffers off the stack, clamp key indexes, and yield in W25Q busy-wait so BLE protocol tests stay stable. Co-authored-by: Cursor --- APP/app_log.c | 20 ++++++++++++++++++- Global/Global.c | 17 +++++++++------- device/W25Q64/W25Q128.c | 7 +++++++ protocol/bl_uart_parse.c | 40 ++++++++++++++++++++++++++++---------- protocol/git_user_fw_ver.h | 10 +++++----- task/task_init.c | 2 +- 6 files changed, 72 insertions(+), 24 deletions(-) diff --git a/APP/app_log.c b/APP/app_log.c index 860322a..62384ee 100644 --- a/APP/app_log.c +++ b/APP/app_log.c @@ -136,7 +136,9 @@ void app_log_set_ui_page(const char *name) void app_log_write(char level, const char *cat, const char *fmt, ...) { - char line[APP_LOG_SLOT_SIZE]; + /* 静态行缓冲:TaskBTRecv 等小栈线程禁止再开 128B 局部数组 */ + static char line[APP_LOG_SLOT_SIZE]; + static rt_mutex_t s_log_mtx = RT_NULL; va_list ap; int n; @@ -144,9 +146,21 @@ void app_log_write(char level, const char *cat, const char *fmt, ...) return; } + if (s_log_mtx == RT_NULL) { + s_log_mtx = rt_mutex_create("applog", RT_IPC_FLAG_PRIO); + } + if (s_log_mtx != RT_NULL) { + if (rt_mutex_take(s_log_mtx, rt_tick_from_millisecond(20)) != RT_EOK) { + return; + } + } + n = snprintf(line, sizeof(line), "[%05u][%c][%-4s] ", (unsigned)app_log_ms(), level, cat); if (n < 0) { + if (s_log_mtx != RT_NULL) { + rt_mutex_release(s_log_mtx); + } return; } if ((size_t)n >= sizeof(line)) { @@ -160,6 +174,10 @@ void app_log_write(char level, const char *cat, const char *fmt, ...) app_log_slot_store(line); SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, line); SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, "\n"); + + if (s_log_mtx != RT_NULL) { + rt_mutex_release(s_log_mtx); + } } static void app_log_dump_ram(void) diff --git a/Global/Global.c b/Global/Global.c index 3e0254f..5ede886 100644 --- a/Global/Global.c +++ b/Global/Global.c @@ -956,9 +956,8 @@ void BL_Set_led(uint8_t led, uint8_t chord_type) void BT_Pitch_offset_map(uint8_t pos_offset,uint8_t pitch_offset) { -//char Info[10]; -//sprintf (Info, "%d %d", pos_offset,pitch_offset); -//LCD_ShowString(2, 156+16, (const uint8_t*)Info, RED, WHITE, 16, 0); + if (pos_offset < 1u || pos_offset > 21u) + return; chord_type_index_map[pos_offset].PitchOffset = pitch_offset; } @@ -967,9 +966,12 @@ void BT_Chord_offset_map(uint8_t pos_offset,uint8_t chord_offset) //char Info[20]; STRING_MIDI *MIDI; const STRING_MIDI *ORGAN_MIDI; - - uint8_t group = (pos_offset - 1) / 3; /* 1~3→0, 4~6→1, ..., 19~21→6 */ + uint8_t group; uint8_t chord_APP_Local_offset = 0; + + if (pos_offset < 1u || pos_offset > 21u) + return; + group = (pos_offset - 1) / 3; /* 1~3→0, 4~6→1, ..., 19~21→6 */ switch(chord_offset){ case 0x00: @@ -1295,9 +1297,10 @@ uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff) root = buff[0]; for (i = 1; i < n; i++) { - while (buff[i] >= (uint8_t)(root + 12)) + uint8_t guard; + for (guard = 0; guard < 2 && buff[i] >= (uint8_t)(root + 12); guard++) buff[i] -= 12; - while (buff[i] < root) + for (guard = 0; guard < 2 && buff[i] < root; guard++) buff[i] += 12; } } diff --git a/device/W25Q64/W25Q128.c b/device/W25Q64/W25Q128.c index 1d7873c..0971be3 100644 --- a/device/W25Q64/W25Q128.c +++ b/device/W25Q64/W25Q128.c @@ -1,6 +1,7 @@ // File: w25q128.c #include "w25q128.h" #include "wk_system.h" +#include "rtthread.h" /* W25Q128 挂在 SPI1 上(PA5=SCK, PA6=MISO, PA7=MOSI),CS 用 PA4 GPIO 控制 */ #define W25Q128_SPI SPI1 @@ -82,6 +83,12 @@ static void W25Q128_WaitBusy(void) W25Q128_ReadWriteByte(W25X_ReadStatusReg1); // 发送读状态寄存器命令 do { status = W25Q128_ReadWriteByte(0xFF); // 循环读取状态字 + if (status & 0x01) { + SPI_CS_HIGH(); + rt_thread_mdelay(1); + SPI_CS_LOW(); + W25Q128_ReadWriteByte(W25X_ReadStatusReg1); + } } while (status & 0x01); // 等待BUSY位清零 SPI_CS_HIGH(); } diff --git a/protocol/bl_uart_parse.c b/protocol/bl_uart_parse.c index 7a4b8d6..b218a32 100644 --- a/protocol/bl_uart_parse.c +++ b/protocol/bl_uart_parse.c @@ -480,25 +480,42 @@ static void handleLED6(uint8_t *data) static void handlePitchOffset(uint8_t *data) { - BL_Sendmsg(MSG_ID_PITCH_OFFSET, data[4]+1, data[5], 0); + uint8_t key = (uint8_t)(data[4] + 1u); + if (key < 1u || key > 21u) + return; + BL_Sendmsg(MSG_ID_PITCH_OFFSET, key, data[5], 0); } static void handleChordOffset(uint8_t *data) { - BL_Sendmsg(MSG_ID_CHORD_OFFSET, data[4]+1, data[5], 0); + uint8_t key = (uint8_t)(data[4] + 1u); + if (key < 1u || key > 21u) + return; + BL_Sendmsg(MSG_ID_CHORD_OFFSET, key, data[5], 0); } extern CHORD_TYPE_INDEX chord_type_index_map[22]; static void handleReadRhythmMap(uint8_t *data) { - uint8_t ReadChordMap[47] = {0xF0, 0x60, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7}; + /* 静态缓冲:禁止在 TaskBTRecv 小栈上再开 47B */ + static uint8_t ReadChordMap[47]; uint8_t chord_map = 0; - for(uint8_t i = 1;i < 22;i ++) + uint8_t i; + + (void)data; + memset(ReadChordMap, 0, sizeof(ReadChordMap)); + ReadChordMap[0] = 0xF0; + ReadChordMap[1] = 0x60; + ReadChordMap[2] = 0x02; + ReadChordMap[3] = 0x01; + ReadChordMap[46] = 0xF7; + + for (i = 1; i < 22; i++) { - ReadChordMap[3+i] = chord_type_index_map[i].PitchOffset; + ReadChordMap[3 + i] = chord_type_index_map[i].PitchOffset; } - for(uint8_t i = 25;i < 46;i ++) + for (i = 25; i < 46; i++) { - switch(chord_type_index_map[i-24].type) + switch (chord_type_index_map[i - 24].type) { case 0: chord_map = 0; @@ -527,10 +544,13 @@ static void handleReadRhythmMap(uint8_t *data) case 8: chord_map = 11; break; + default: + chord_map = 0; + break; } ReadChordMap[i] = chord_map; } - USART4_SendData(ReadChordMap,sizeof(ReadChordMap)); + USART4_SendData(ReadChordMap, sizeof(ReadChordMap)); } static void handleIntro(uint8_t *data) @@ -609,8 +629,8 @@ static void handleDevConnect(uint8_t *data) static void handleDevName(uint8_t *data) { - char name[BLE_DEVICE_NAME_LEN + 1]; - uint8_t resp[4 + BLE_DEVICE_NAME_LEN + 1]; /* head4 + name + F7 */ + static char name[BLE_DEVICE_NAME_LEN + 1]; + static uint8_t resp[4 + BLE_DEVICE_NAME_LEN + 1]; /* head4 + name + F7 */ (void)data; BleBuildDeviceName(name); resp[0] = 0xF0; resp[1] = 0x60; resp[2] = 0x01; resp[3] = 0x02; diff --git a/protocol/git_user_fw_ver.h b/protocol/git_user_fw_ver.h index 61b9cb8..071289b 100644 --- a/protocol/git_user_fw_ver.h +++ b/protocol/git_user_fw_ver.h @@ -1,16 +1,16 @@ /* Auto-generated by tools/gen_git_user_fw_ver.py — do not edit. - * git HEAD (dirty): bb6d9ae7f9987ec6cfb3ab50579951d2b58ed888 + * git HEAD (dirty): 24ffe87527d9c8c476af39b3030ab7fec3b71884 * branch: develop → develop - * 01 0C wire: develop_bb6d9a* + * 01 0C wire: develop_24ffe8* */ #ifndef GIT_USER_FW_VER_H #define GIT_USER_FW_VER_H -#define GIT_COMMIT_ID_FULL "bb6d9ae7f9987ec6cfb3ab50579951d2b58ed888" +#define GIT_COMMIT_ID_FULL "24ffe87527d9c8c476af39b3030ab7fec3b71884" #define GIT_BRANCH_NAME "develop" -#define GIT_COMMIT_SHORT6 "bb6d9a" +#define GIT_COMMIT_SHORT6 "24ffe8" #define GIT_DIRTY (1) -#define GIT_BUILD_ID "develop_bb6d9a*" +#define GIT_BUILD_ID "develop_24ffe8*" #define GIT_BUILD_ID_LEN 15u #endif /* GIT_USER_FW_VER_H */ diff --git a/task/task_init.c b/task/task_init.c index 5dcf1bd..896754f 100644 --- a/task/task_init.c +++ b/task/task_init.c @@ -13,7 +13,7 @@ ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskUIThread_Stack[2048]; ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskTouchThread_Stack[1536]; ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskMainThread_Stack[512]; ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskBTTHandlehread_Stack[512]; -ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskBTRecvThread_Stack[512]; +ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskBTRecvThread_Stack[768]; ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskAutobandThread_Stack[512];