378 lines
9.4 KiB
C
378 lines
9.4 KiB
C
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
#include "kmdw_console.h"
|
|
#include "project.h"
|
|
|
|
#include "cmsis_os2.h"
|
|
#include "kdrv_cmsis_core.h"
|
|
|
|
#define UART_RX_ECHO_GET_DBG 0
|
|
|
|
#define BACKSP_KEY 0x08
|
|
#define RETURN_KEY 0x0D
|
|
#define DELETE_KEY 0x7F
|
|
#define BELL 0x07
|
|
|
|
#define MAX_LOG_LENGTH (256) //14bytes are necessary amount structure information "sizeof(os_message_t)" for each msg element in rtx_msgqueue.c
|
|
#define MAX_LOG_LENGTH_MSGQ (MAX_LOG_LENGTH+14)
|
|
#define DDR_LOG_BUFFER_SIZE (1 * 1024 * 1024)
|
|
#define DDR_MAX_LOG_COUNT (DDR_LOG_BUFFER_SIZE/MAX_LOG_LENGTH_MSGQ)// if using DDR
|
|
static uint32_t scpu_debug_flags = 0;
|
|
|
|
static kdrv_uart_handle_t handle0 = MSG_PORT;
|
|
static osMessageQueueId_t log_msgq = NULL;
|
|
|
|
print_callback _print_callback = NULL;
|
|
|
|
#if (defined(UART_RX_ECHO_GET_DBG) && UART_RX_ECHO_GET_DBG == 1)
|
|
uint32_t buf_tmp[1024];
|
|
char buf_tmp_char[1024];
|
|
uint32_t uart_rx_cnt = 0;
|
|
uint32_t uart_rx_cnt_tmp = 0;
|
|
#endif
|
|
|
|
osEventFlagsId_t uart_console_evid;
|
|
osSemaphoreId_t uart_send_mutex;
|
|
|
|
__weak uint32_t osKernelIrqStatus(void)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static void _print_to_uart(const char *str)
|
|
{
|
|
osMutexAcquire(uart_send_mutex, osWaitForever);
|
|
kdrv_uart_write(handle0, (uint8_t *)str, strlen(str));
|
|
osMutexRelease(uart_send_mutex);
|
|
}
|
|
|
|
kmdw_status_t kmdw_printf(const char *fmt, ...)
|
|
{
|
|
va_list arg_ptr;
|
|
static char *buffer_s = NULL;
|
|
|
|
if (NULL == buffer_s)
|
|
buffer_s = (char *)malloc(sizeof(char) * MAX_LOG_LENGTH);
|
|
|
|
sprintf(buffer_s, "[%.03f] ", (float)osKernelGetTickCount() / osKernelGetTickFreq());
|
|
int pre_len = strlen(buffer_s);
|
|
|
|
va_start(arg_ptr, fmt);
|
|
vsnprintf(buffer_s + pre_len, MAX_LOG_LENGTH - 1, fmt, arg_ptr);
|
|
va_end(arg_ptr);
|
|
|
|
buffer_s[MAX_LOG_LENGTH - 1] = 0; // just in case
|
|
|
|
if (log_msgq == NULL || osThreadGetId() == NULL)
|
|
_print_to_uart(buffer_s);
|
|
else
|
|
{
|
|
osStatus_t oss = osMessageQueuePut(log_msgq, buffer_s, NULL, 0);
|
|
if (oss != osOK)
|
|
{
|
|
//_print_to_uart("[logger] enqueue log1 failed\n");
|
|
return KMDW_STATUS_ERROR;
|
|
}
|
|
}
|
|
|
|
return KMDW_STATUS_OK;
|
|
}
|
|
|
|
kmdw_status_t kmdw_level_printf(int level, const char *fmt, ...)
|
|
{
|
|
static char *buffer_s = NULL;
|
|
uint32_t lvl = kmdw_console_get_log_level_scpu();
|
|
lvl >>= 16;
|
|
|
|
if ((level == LOG_PROFILE && level == lvl) || (level > 0 && level <= lvl))
|
|
{
|
|
va_list arg_ptr;
|
|
|
|
if (NULL == buffer_s)
|
|
buffer_s = (char *)malloc(sizeof(char) * MAX_LOG_LENGTH);
|
|
|
|
sprintf(buffer_s, "[%.03f] ", (float)osKernelGetTickCount() / osKernelGetTickFreq());
|
|
int pre_len = strlen(buffer_s);
|
|
|
|
va_start(arg_ptr, fmt);
|
|
vsnprintf(buffer_s + pre_len, MAX_LOG_LENGTH - 1, fmt, arg_ptr);
|
|
va_end(arg_ptr);
|
|
|
|
buffer_s[MAX_LOG_LENGTH - 1] = 0; // just in case
|
|
|
|
if (log_msgq == NULL || osThreadGetId() == NULL)
|
|
_print_to_uart(buffer_s);
|
|
else
|
|
{
|
|
osStatus_t oss = osMessageQueuePut(log_msgq, buffer_s, NULL, 0);
|
|
if (oss != osOK)
|
|
{
|
|
//_print_to_uart("[logger] enqueue log failed\n");
|
|
return KMDW_STATUS_ERROR;
|
|
}
|
|
}
|
|
}
|
|
|
|
return KMDW_STATUS_OK;
|
|
}
|
|
|
|
void logger_thread(void *arg)
|
|
{
|
|
uint8_t log[MAX_LOG_LENGTH];
|
|
|
|
void *log_pool = (void *)kmdw_ddr_reserve(DDR_LOG_BUFFER_SIZE);
|
|
|
|
if (log_pool)
|
|
{
|
|
osMessageQueueAttr_t msgq_attr;
|
|
memset(&msgq_attr, 0, sizeof(msgq_attr));
|
|
msgq_attr.mq_mem = log_pool;
|
|
msgq_attr.mq_size = DDR_LOG_BUFFER_SIZE;
|
|
memset(log_pool, 0, DDR_LOG_BUFFER_SIZE);
|
|
|
|
log_msgq = osMessageQueueNew(DDR_MAX_LOG_COUNT, MAX_LOG_LENGTH, &msgq_attr);
|
|
if (log_msgq == NULL)
|
|
{
|
|
printf("[logger] osMessageQueueNew failed\n");
|
|
}
|
|
}
|
|
while (1)
|
|
{
|
|
osStatus_t oss = osMessageQueueGet(log_msgq, &log[0], NULL, osWaitForever);
|
|
if (oss != osOK)
|
|
{
|
|
_print_to_uart("[logger] dequeue log failed\n");
|
|
// if (_print_callback)
|
|
// _print_callback("[logger] dequeue log failed\n");
|
|
continue;
|
|
}
|
|
|
|
_print_to_uart((const char *)log);
|
|
|
|
if (_print_callback)
|
|
_print_callback((const char *)log);
|
|
}
|
|
}
|
|
|
|
__weak uint32_t kmdw_ddr_reserve(uint32_t numbyte)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void kmdw_console_hook_callback(print_callback print_cb)
|
|
{
|
|
_print_callback = print_cb;
|
|
}
|
|
|
|
char kmdw_console_getc(void)
|
|
{
|
|
char c;
|
|
kdrv_uart_read(handle0, (uint8_t *)&c, 1);
|
|
return c;
|
|
}
|
|
|
|
void kmdw_console_putc(char Ch)
|
|
{
|
|
char cc;
|
|
|
|
if (Ch != '\0')
|
|
{
|
|
cc = Ch;
|
|
kdrv_uart_write(handle0, (uint8_t *)&cc, 1);
|
|
}
|
|
|
|
if (Ch == '\n')
|
|
{
|
|
cc = '\r';
|
|
kdrv_uart_write(handle0, (uint8_t *)&cc, 1);
|
|
}
|
|
}
|
|
|
|
void kmdw_console_puts(char *str)
|
|
{
|
|
char *cp;
|
|
for (cp = str; *cp != 0; cp++)
|
|
kmdw_console_putc(*cp);
|
|
}
|
|
|
|
int kmdw_console_echo_gets(char *buf, int len)
|
|
{
|
|
char *cp;
|
|
char data[MAX_FIFO_RX];
|
|
uint32_t count;
|
|
uint32_t exit_while = 0;
|
|
count = 0;
|
|
cp = buf;
|
|
len = 1024;
|
|
#if (defined(UART_RX_ECHO_GET_DBG) && UART_RX_ECHO_GET_DBG == 1)
|
|
uart_rx_cnt=0;
|
|
memset(buf_tmp, 0, sizeof(buf_tmp));
|
|
memset(buf_tmp_char, 0xff, sizeof(buf_tmp_char));
|
|
#endif
|
|
do
|
|
{
|
|
memset(data, 0, MAX_FIFO_RX);
|
|
kdrv_uart_get_char(handle0, data);
|
|
//kdrv_uart_read(handle0, (uint8_t*)data, 1);
|
|
for(uint32_t i = 0; i< gDrvCtx.uart_dev[handle0]->info.xfer.rx_cnt; i++)
|
|
{
|
|
|
|
#if (defined(UART_RX_ECHO_GET_DBG) && UART_RX_ECHO_GET_DBG == 1)
|
|
buf_tmp[uart_rx_cnt] = uart_rx_cnt;
|
|
buf_tmp_char[uart_rx_cnt] = data[i];
|
|
uart_rx_cnt++;
|
|
#endif
|
|
if(data[i] == BACKSP_KEY || data[i] == DELETE_KEY)
|
|
{
|
|
if ((count > 0) && (count < len))
|
|
{
|
|
count--;
|
|
*(--cp) = '\0';
|
|
//kmdw_console_puts("\b \b");
|
|
}
|
|
break;
|
|
}
|
|
if(data[i] == RETURN_KEY)
|
|
{
|
|
if (count < len)
|
|
{
|
|
*cp = '\0';
|
|
kmdw_console_putc('\n');
|
|
}
|
|
exit_while = 1;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if(count < len)
|
|
{
|
|
*cp = (char)data[i];
|
|
cp++;
|
|
count++;
|
|
kmdw_console_putc(data[i]);
|
|
}
|
|
}
|
|
}
|
|
} while (exit_while == 0);
|
|
#if (defined(UART_RX_ECHO_GET_DBG) && UART_RX_ECHO_GET_DBG == 1)
|
|
uart_rx_cnt_tmp = uart_rx_cnt;
|
|
#endif
|
|
return (count);
|
|
}
|
|
|
|
__weak void kdrv_ncpu_set_scpu_debug_lvl(uint32_t lvl)
|
|
{
|
|
}
|
|
|
|
__weak void kdrv_ncpu_set_ncpu_debug_lvl(uint32_t lvl)
|
|
{
|
|
}
|
|
|
|
void kmdw_console_set_log_level_scpu(uint32_t level)
|
|
{
|
|
scpu_debug_flags = (scpu_debug_flags & ~0x000F0000) | (((level) << 16) & 0x000F0000);
|
|
kdrv_ncpu_set_scpu_debug_lvl(level);
|
|
}
|
|
|
|
uint32_t kmdw_console_get_log_level_scpu(void)
|
|
{
|
|
return scpu_debug_flags;
|
|
}
|
|
|
|
void kmdw_console_set_log_level_ncpu(uint32_t level)
|
|
{
|
|
kdrv_ncpu_set_ncpu_debug_lvl(level);
|
|
}
|
|
|
|
void kmdw_console_callback(uint32_t event)
|
|
{
|
|
|
|
if(osKernelGetState() == osKernelRunning && uart_console_evid != NULL)
|
|
{
|
|
if (event & UART_RX_DONE)
|
|
{
|
|
osEventFlagsSet(uart_console_evid, UART_RX_DONE);
|
|
}
|
|
if (event & UART_TX_DONE)
|
|
{
|
|
osEventFlagsSet(uart_console_evid, UART_TX_DONE);
|
|
}
|
|
if (event & UART_RX_TIMEOUT)
|
|
{
|
|
osEventFlagsSet(uart_console_evid, UART_RX_DONE);
|
|
}
|
|
}
|
|
if (event & UART_REVEIVE_COMPLETE)
|
|
{
|
|
kmdw_console_wait_rx_done(MSG_PORT);
|
|
};
|
|
if (event & UART_TRANSFER_COMPLETE)
|
|
{
|
|
kmdw_console_wait_tx_done(MSG_PORT);
|
|
};
|
|
}
|
|
|
|
void kmdw_console_wait_rx_done(kdrv_uart_handle_t handle)
|
|
{
|
|
if(osKernelGetState() == osKernelRunning && uart_console_evid != NULL)
|
|
{
|
|
int32_t evt_flg = osEventFlagsWait(uart_console_evid, UART_RX_DONE, osFlagsWaitAny , osWaitForever);
|
|
}
|
|
else
|
|
{
|
|
while((uart_get_status((DRVUART_PORT)handle) & SERIAL_LSR_DR) != SERIAL_LSR_DR)
|
|
{
|
|
if(osKernelIrqStatus() == false)
|
|
__WFI();
|
|
else
|
|
__NOP();
|
|
}
|
|
}
|
|
}
|
|
|
|
void kmdw_console_wait_tx_done(kdrv_uart_handle_t handle)
|
|
{
|
|
if(osKernelIrqStatus() == true)
|
|
{
|
|
while((uart_get_status((DRVUART_PORT)handle) & SERIAL_LSR_THRE) != SERIAL_LSR_THRE)
|
|
{
|
|
__NOP();
|
|
}
|
|
gDrvCtx.uart_dev[handle0]->info.status.tx_busy = 0;
|
|
}
|
|
else if(osKernelGetState() == osKernelRunning && uart_console_evid != NULL)
|
|
{
|
|
int32_t evt_flg = osEventFlagsWait(uart_console_evid, UART_TX_DONE, osFlagsWaitAny , osWaitForever);
|
|
}
|
|
else
|
|
{
|
|
while((uart_get_status((DRVUART_PORT)handle) & SERIAL_LSR_THRE) != SERIAL_LSR_THRE)
|
|
{
|
|
__WFI();
|
|
}
|
|
}
|
|
}
|
|
|
|
kmdw_status_t kmdw_uart_console_init(uint8_t uart_dev, uint32_t baudrate)
|
|
{
|
|
kdrv_status_t sts = kdrv_uart_console_init(uart_dev, baudrate, kmdw_console_callback);//NULL);//
|
|
|
|
if (sts != KDRV_STATUS_OK)
|
|
return KMDW_STATUS_ERROR;
|
|
|
|
uart_send_mutex = osMutexNew(NULL); // for uart send usage
|
|
uart_console_evid = osEventFlagsNew(0);
|
|
|
|
if(uart_console_evid == NULL)
|
|
return KMDW_STATUS_ERROR;
|
|
|
|
return KMDW_STATUS_OK;
|
|
}
|
|
|
|
|
|
kmdw_status_t kmdw_uart_uninitialize(void)
|
|
{
|
|
return KMDW_STATUS_OK;
|
|
}
|