导航部分效果最好的版本,主分支
This commit is contained in:
99
App/retarget.c
Normal file
99
App/retarget.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user