This commit is contained in:
2026-03-31 23:30:33 +08:00
commit 760043c8e7
1615 changed files with 1406836 additions and 0 deletions

99
App/retarget.c Normal file
View File

@@ -0,0 +1,99 @@
#include "retarget.h"
#include <stdint.h>
#include <stdio.h>
#include "cmsis_os.h"
#include "usbd_cdc_if.h"
/*
* 说明:
* 1. 这里默认使用 FreeRTOS 的 CMSIS-RTOS2 接口
* 2. printf 最终会走到 _write()
* 3. _write() 内部调用 CDC_Transmit_FS() 发送到 USB 虚拟串口
* 4. 为避免多个任务同时 printf 打花,这里提供互斥锁
*/
static osMutexId_t s_retarget_mutex = NULL;
static uint8_t s_inited = 0U;
/* 互斥锁属性 */
static const osMutexAttr_t s_retarget_mutex_attr = {
.name = "retargetMutex"
};
void Retarget_Init(void)
{
if (s_inited != 0U)
{
return;
}
/* 只有在内核启动后创建互斥量才有意义 */
if (osKernelGetState() == osKernelRunning)
{
s_retarget_mutex = osMutexNew(&s_retarget_mutex_attr);
}
s_inited = 1U;
}
void Retarget_Lock(void)
{
if ((s_retarget_mutex != NULL) && (osKernelGetState() == osKernelRunning))
{
(void)osMutexAcquire(s_retarget_mutex, osWaitForever);
}
}
void Retarget_Unlock(void)
{
if ((s_retarget_mutex != NULL) && (osKernelGetState() == osKernelRunning))
{
(void)osMutexRelease(s_retarget_mutex);
}
}
/*
* GNU 工具链 printf 重定向
* 注意:
* - 不要在中断里调用 printf
* - USB CDC 忙时最多等待 20ms
* - 等待期间 osDelay(1) 让出 CPU
*/
int _write(int file, char *ptr, int len)
{
uint32_t start_tick;
uint8_t result;
(void)file;
if ((ptr == NULL) || (len <= 0))
{
return 0;
}
start_tick = HAL_GetTick();
while (1)
{
result = CDC_Transmit_FS((uint8_t *)ptr, (uint16_t)len);
if (result == USBD_OK)
{
return len;
}
/* USB 还没准备好或者正忙,最多等 20ms */
if ((HAL_GetTick() - start_tick) > 20U)
{
return 0;
}
/* 在 FreeRTOS 下主动让出 CPU */
if (osKernelGetState() == osKernelRunning)
{
osDelay(1);
}
}
}