Files
ASER-NAV/App/retarget.c

99 lines
1.9 KiB
C
Raw Permalink Normal View History

#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);
}
}
}