官方文档主要修改
为了实现log服务
1,在log_service.h 取消注释
#ifndef LOG_SERVICE_H #define LOG_SERVICE_H #include "dlist.h" /* * Include user defined options first. Anything not defined in these files * will be set to standard values. Override anything you dont like! */ #if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) #include "platform_opts.h" #include "platform_stdlib.h" #endif #ifdef __ICCARM__ //#define STRINGIFY(s) #s //#define SECTION(_name) _Pragma( STRINGIFY(location=_name)) #define log_module_init(fn) SECTION(".data.log_init") __root static void* log_##fn = (void*)fn #elif defined(__CC_ARM) #define log_module_init(fn) static void* log_##fn __attribute__((section(".data.log_init"))) = (void*)fn; #define DiagPrintf printf #elif defined(__GNUC__) #define log_module_init(fn) static void* log_##fn __attribute__((section(".data.log_init"))) = (void*)fn; #else #error "not implement" #endif //#define log_module_init(fn) #define ATC_INDEX_NUM 32 #ifndef SUPPORT_LOG_SERVICE #define SUPPORT_LOG_SERVICE 1 #endif //LOG_SERVICE_BUFLEN: default, only 63 bytes could be used for keeping input // cmd, the last byte is for string end (' '). #ifndef LOG_SERVICE_BUFLEN #define LOG_SERVICE_BUFLEN 64 #endif #ifndef CONFIG_LOG_HISTORY #define CONFIG_LOG_HISTORY 0 #if CONFIG_LOG_HISTORY #define LOG_HISTORY_LEN 5 #endif #endif //#ifndef CONFIG_LOG_HISTORY #ifndef MAX_ARGC #define MAX_ARGC 12 #endif #ifndef CONFIG_LOG_SERVICE_LOCK #define CONFIG_LOG_SERVICE_LOCK 0 // //to protect log_buf[], only one command processed per time #endif #define AT_BIT(n) (1<<n) #define AT_FLAG_DUMP AT_BIT(0) #define AT_FLAG_EDIT AT_BIT(1) #define AT_FLAG_ADC AT_BIT(2) #define AT_FLAG_GPIO AT_BIT(3) #define AT_FLAG_OTA AT_BIT(4) #define AT_FLAG_NFC AT_BIT(5) #define AT_FLAG_OS AT_BIT(6) #define AT_FLAG_LWIP AT_BIT(7) #define AT_FLAG_COMMON AT_BIT(8) #define AT_FLAG_WIFI AT_BIT(9) #define AT_FLAG_RDP AT_BIT(10) enum{ AT_DBG_OFF = 0, AT_DBG_ALWAYS, AT_DBG_ERROR, AT_DBG_WARNING, AT_DBG_INFO }; extern unsigned char gDbgLevel; extern unsigned int gDbgFlag; #define AT_PRINTK(...) do{ printf(__VA_ARGS__); printf(" "); }while(0) #define _AT_PRINTK(...) printf(__VA_ARGS__) #define AT_DBG_MSG(flag, level, ...) do{ if(((flag) & gDbgFlag) && (level <= gDbgLevel)){ AT_PRINTK(__VA_ARGS__); } }while(0) #define _AT_DBG_MSG(flag, level, ...) do{ if(((flag) & gDbgFlag) && (level <= gDbgLevel)){ _AT_PRINTK(__VA_ARGS__); } }while(0) #ifndef SUPPORT_INTERACTIVE_MODE #define SUPPORT_INTERACTIVE_MODE 0 #endif //#ifndef SUPPORT_INTERACTIVE_MODE typedef void (*log_init_t)(void); typedef void (*log_act_t)(void*); typedef struct _at_command_item_{ char *log_cmd; log_act_t at_act; struct list_head node; }log_item_t; void log_service_add_table(log_item_t *tbl, int len); int parse_param(char *buf, char **argv); #if CONFIG_LOG_SERVICE_LOCK void log_service_lock_init(void); void log_service_lock(void); u32 log_service_lock_timeout(u32 ms); void log_service_unlock(void); #endif #define C_NUM_AT_CMD 4 //"ATxx", 4 characters #define C_NUM_AT_CMD_DLT 1 //"=", 1 charater #define STR_END_OF_ATCMD_RET " # " //each AT command response will end with this string #define STR_END_OF_ATDATA_RET " > " //data transparent transmission indicator #endif
注销代码(这个为空函数,导致AT不识别)
#define log_module_init(fn)
在rtl_consol.c中
/* * Routines to access hardware * * Copyright (c) 2013 Realtek Semiconductor Corp. * * This module is a confidential and proprietary property of RealTek and * possession or use of this module requires written permission of RealTek. */ #include "rtl8195a.h" //#include <stdarg.h> #include "rtl_consol.h" #include "FreeRTOS.h" #include "task.h" #include <event_groups.h> #include "semphr.h" #if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) #include "freertos_pmu.h" #endif #include "tcm_heap.h" // Those symbols will be defined in linker script for gcc compiler // If not doing this would cause extra memory cost #if defined (__GNUC__) extern volatile UART_LOG_CTL UartLogCtl; extern volatile UART_LOG_CTL *pUartLogCtl; extern u8 *ArgvArray[MAX_ARGV]; extern UART_LOG_BUF UartLogBuf; #ifdef CONFIG_UART_LOG_HISTORY extern u8 UartLogHistoryBuf[UART_LOG_HISTORY_LEN][UART_LOG_CMD_BUFLEN]; #endif #else MON_RAM_BSS_SECTION volatile UART_LOG_CTL UartLogCtl; MON_RAM_BSS_SECTION volatile UART_LOG_CTL *pUartLogCtl; MON_RAM_BSS_SECTION u8 *ArgvArray[MAX_ARGV]; MON_RAM_BSS_SECTION UART_LOG_BUF UartLogBuf; #ifdef CONFIG_UART_LOG_HISTORY MON_RAM_BSS_SECTION u8 UartLogHistoryBuf[UART_LOG_HISTORY_LEN][UART_LOG_CMD_BUFLEN]; #endif #endif #ifdef CONFIG_KERNEL static void (*up_sema_from_isr)(_sema *) = NULL; #endif _LONG_CALL_ extern u8 UartLogCmdChk( IN u8 RevData, IN UART_LOG_CTL *prvUartLogCtl, IN u8 EchoFlag ); _LONG_CALL_ extern VOID ArrayInitialize( IN u8 *pArrayToInit, IN u8 ArrayLen, IN u8 InitValue ); _LONG_CALL_ extern VOID UartLogHistoryCmd( IN u8 RevData, IN UART_LOG_CTL *prvUartLogCtl, IN u8 EchoFlag ); _LONG_CALL_ extern VOID UartLogCmdExecute( IN PUART_LOG_CTL pUartLogCtlExe ); //================================================= /* Minimum and maximum values a `signed long int' can hold. (Same as `int'). */ #ifndef __LONG_MAX__ #if defined (__alpha__) || (defined (__sparc__) && defined(__arch64__)) || defined (__sparcv9) || defined (__s390x__) #define __LONG_MAX__ 9223372036854775807L #else #define __LONG_MAX__ 2147483647L #endif /* __alpha__ || sparc64 */ #endif #undef LONG_MIN #define LONG_MIN (-LONG_MAX-1) #undef LONG_MAX #define LONG_MAX __LONG_MAX__ /* Maximum value an `unsigned long int' can hold. (Minimum is 0). */ #undef ULONG_MAX #define ULONG_MAX (LONG_MAX * 2UL + 1) #ifndef __LONG_LONG_MAX__ #define __LONG_LONG_MAX__ 9223372036854775807LL #endif //====================================================== //<Function>: UartLogIrqHandleRam //<Usage >: To deal with Uart-Log RX IRQ //<Argus >: VOID //<Return >: VOID //<Notes >: NA //====================================================== //MON_RAM_TEXT_SECTION VOID UartLogIrqHandleRam //接收中断函数 ( VOID * Data ) { u8 UartReceiveData = 0; //For Test BOOL PullMode = _FALSE; u32 IrqEn = DiagGetIsrEnReg(); //获取中断 DiagSetIsrEnReg(0); UartReceiveData = DiagGetChar(PullMode); //获取数据 if (UartReceiveData == 0) { goto exit; } //KB_ESC chk is for cmd history, it's a special case here. if (UartReceiveData == KB_ASCII_ESC) { //4 Esc detection is only valid in the first stage of boot sequence (few seconds) if (pUartLogCtl->ExecuteEsc != _TRUE) { pUartLogCtl->ExecuteEsc = _TRUE; (*pUartLogCtl).EscSTS = 0; } else { //4 the input commands are valid only when the task is ready to execute commands if ((pUartLogCtl->BootRdy == 1) #ifdef CONFIG_KERNEL ||(pUartLogCtl->TaskRdy == 1) #endif ) { if ((*pUartLogCtl).EscSTS==0) { (*pUartLogCtl).EscSTS = 1; } } else { (*pUartLogCtl).EscSTS = 0; } } } else if ((*pUartLogCtl).EscSTS==1){ if (UartReceiveData != KB_ASCII_LBRKT){ (*pUartLogCtl).EscSTS = 0; } else{ (*pUartLogCtl).EscSTS = 2; } } else{ if ((*pUartLogCtl).EscSTS==2){ (*pUartLogCtl).EscSTS = 0; #ifdef CONFIG_UART_LOG_HISTORY if ((UartReceiveData=='A')|| UartReceiveData=='B'){ UartLogHistoryCmd(UartReceiveData,(UART_LOG_CTL *)pUartLogCtl,1); } #endif } else{ if (UartLogCmdChk(UartReceiveData,(UART_LOG_CTL *)pUartLogCtl,1)==2) { //4 check UartLog buffer to prevent from incorrect access if (pUartLogCtl->pTmpLogBuf != NULL) { pUartLogCtl->ExecuteCmd = _TRUE; #if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED if (pUartLogCtl->TaskRdy && up_sema_from_isr != NULL) //RtlUpSemaFromISR((_Sema *)&pUartLogCtl->Sema); up_sema_from_isr((_sema *)&pUartLogCtl->Sema); #endif } else { ArrayInitialize((u8 *)pUartLogCtl->pTmpLogBuf->UARTLogBuf, UART_LOG_CMD_BUFLEN, ' '); } } } } exit: DiagSetIsrEnReg(IrqEn); } MON_RAM_TEXT_SECTION VOID RtlConsolInitRam( //初始化 IN u32 Boot, IN u32 TBLSz, IN VOID *pTBL ) { UartLogBuf.BufCount = 0; ArrayInitialize(&UartLogBuf.UARTLogBuf[0],UART_LOG_CMD_BUFLEN,' '); pUartLogCtl = &UartLogCtl; pUartLogCtl->NewIdx = 0; pUartLogCtl->SeeIdx = 0; pUartLogCtl->RevdNo = 0; pUartLogCtl->EscSTS = 0; pUartLogCtl->BootRdy = 0; pUartLogCtl->pTmpLogBuf = &UartLogBuf; #ifdef CONFIG_UART_LOG_HISTORY pUartLogCtl->CRSTS = 0; pUartLogCtl->pHistoryBuf = &UartLogHistoryBuf[0]; #endif pUartLogCtl->pfINPUT = (VOID*)&DiagPrintf; pUartLogCtl->pCmdTbl = (PCOMMAND_TABLE) pTBL; pUartLogCtl->CmdTblSz = TBLSz; #ifdef CONFIG_KERNEL pUartLogCtl->TaskRdy = 0; #endif //executing boot sequence if (Boot == ROM_STAGE) { pUartLogCtl->ExecuteCmd = _FALSE; pUartLogCtl->ExecuteEsc = _FALSE; } else { pUartLogCtl->ExecuteCmd = _FALSE; pUartLogCtl->ExecuteEsc= _TRUE;//don't check Esc anymore #if defined(CONFIG_KERNEL) /* Create a Semaphone */ //RtlInitSema((_Sema*)&(pUartLogCtl->Sema), 0); rtw_init_sema((_sema*)&(pUartLogCtl->Sema), 0); pUartLogCtl->TaskRdy = 0; #ifdef PLATFORM_FREERTOS #define LOGUART_STACK_SIZE 128 //USE_MIN_STACK_SIZE modify from 512 to 128 #if CONFIG_USE_TCM_HEAP //TCM { int ret = 0; void *stack_addr = tcm_heap_malloc(LOGUART_STACK_SIZE*sizeof(int)); //void *stack_addr = rtw_malloc(stack_size*sizeof(int)); if(stack_addr == NULL){ DiagPrintf("Out of TCM heap in "LOGUART_TASK" "); } ret = xTaskGenericCreate( RtlConsolTaskRam, /* 任务函数 */ (const char *)"LOGUART_TASK", /* 任务名 */ LOGUART_STACK_SIZE, /* 任务栈大小,单位 word,也就是 4 字节 */ NULL, /* 任务参数 */ tskIDLE_PRIORITY + 5 + PRIORITIE_OFFSET, /* 任务优先级 */ NULL, stack_addr, NULL); if (pdTRUE != ret) { DiagPrintf("Create Log UART Task Err!! "); } } #else if (pdTRUE != xTaskCreate( RtlConsolTaskRam, /* 任务函数 */ (const signed char * const)"LOGUART_TASK", /* 任务名 */ LOGUART_STACK_SIZE, /* 任务栈大小,单位 word,也就是 4 字节 */ NULL, /* 任务参数 */ tskIDLE_PRIORITY + 5 + PRIORITIE_OFFSET, /* 任务优先级 */ NULL)) /* 任务句柄 */ { DiagPrintf("Create Log UART Task Err!! "); } #endif #endif #endif } CONSOLE_8195A(); } extern u8** GetArgv(const u8 *string); #if SUPPORT_LOG_SERVICE extern char log_buf[LOG_SERVICE_BUFLEN]; extern xSemaphoreHandle log_rx_interrupt_sema; #endif //====================================================== void console_cmd_exec(PUART_LOG_CTL pUartLogCtlExe) { u8 CmdCnt = 0; u8 argc = 0; u8 **argv; //u32 CmdNum; PUART_LOG_BUF pUartLogBuf = pUartLogCtlExe->pTmpLogBuf; #if SUPPORT_LOG_SERVICE strncpy(log_buf, (const u8*)&(*pUartLogBuf).UARTLogBuf[0], LOG_SERVICE_BUFLEN-1); #endif argc = GetArgc((const u8*)&((*pUartLogBuf).UARTLogBuf[0])); argv = GetArgv((const u8*)&((*pUartLogBuf).UARTLogBuf[0])); if(argc > 0){ #if SUPPORT_LOG_SERVICE // if(log_handler(argv[0]) == NULL) // legency_interactive_handler(argc, argv); //RtlUpSema((_Sema *)&log_rx_interrupt_sema); rtw_up_sema((_sema *)&log_rx_interrupt_sema); #endif ArrayInitialize(argv[0], sizeof(argv[0]) ,0); }else{ #if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) pmu_acquire_wakelock(BIT(PMU_LOGUART_DEVICE)); #endif CONSOLE_8195A(); // for null command } (*pUartLogBuf).BufCount = 0; ArrayInitialize(&(*pUartLogBuf).UARTLogBuf[0], UART_LOG_CMD_BUFLEN, ' '); } //====================================================== // overload original RtlConsolTaskRam MON_RAM_TEXT_SECTION VOID RtlConsolTaskRam( VOID *Data ) { #if SUPPORT_LOG_SERVICE log_service_init(); #endif //4 Set this for UartLog check cmd history #ifdef CONFIG_KERNEL pUartLogCtl->TaskRdy = 1; up_sema_from_isr = rtw_up_sema_from_isr; #endif #ifndef CONFIG_KERNEL pUartLogCtl->BootRdy = 1; #endif do{ #if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED //RtlDownSema((_Sema *)&pUartLogCtl->Sema); rtw_down_sema((_sema *)&pUartLogCtl->Sema); #endif if (pUartLogCtl->ExecuteCmd) { // Add command handler here console_cmd_exec((PUART_LOG_CTL)pUartLogCtl); //UartLogCmdExecute((PUART_LOG_CTL)pUartLogCtl); pUartLogCtl->ExecuteCmd = _FALSE; } }while(1); } //====================================================== #if BUFFERED_PRINTF xTaskHandle print_task = NULL; /* 任务函数 */ EventGroupHandle_t print_event = NULL; /* 事件标志组句柄 */ char print_buffer[MAX_PRINTF_BUF_LEN]; int flush_idx = 0; int used_length = 0; //长度 //检查可用空间 int available_space(void) { return MAX_PRINTF_BUF_LEN-used_length; } //打印函数 int buffered_printf(const char* fmt, ...) { /*合法性检查*/ if((print_task==NULL) || (print_event==NULL) ) return 0; char tmp_buffer[UART_LOG_CMD_BUFLEN+1]; static int print_idx = 0; int cnt; if(xEventGroupGetBits(print_event)!=1) xEventGroupSetBits(print_event, /* 事件标志组句柄 */ 1); /* 事件标志位设置 */ memset(tmp_buffer,0,UART_LOG_CMD_BUFLEN+1); VSprintf(tmp_buffer, fmt, ((const int *)&fmt)+1);//将param 按格式format写入字符串string中 cnt = _strlen(tmp_buffer); //检查长度 if(cnt < available_space()){ //可用长度 if(print_idx >= flush_idx){ if(MAX_PRINTF_BUF_LEN-print_idx >= cnt){ memcpy(&print_buffer[print_idx], tmp_buffer, cnt); }else{ memcpy(&print_buffer[print_idx], tmp_buffer, MAX_PRINTF_BUF_LEN-print_idx); memcpy(&print_buffer[0], &tmp_buffer[MAX_PRINTF_BUF_LEN-print_idx], cnt-(MAX_PRINTF_BUF_LEN-print_idx)); } }else{ // space is flush_idx - print_idx, and available space is enough memcpy(&print_buffer[print_idx], tmp_buffer, cnt); } // protection needed taskENTER_CRITICAL(); /*为了保证不被中断,将操作放入临界区。进入临界区 */ used_length+=cnt; taskEXIT_CRITICAL(); /* 完成操作,离开临界区*/ print_idx+=cnt; if(print_idx>=MAX_PRINTF_BUF_LEN) print_idx -= MAX_PRINTF_BUF_LEN; }else{ // skip cnt = 0; } return cnt; } /* 任务函数 */ void printing_task(void* arg) { while(1){ //wait event //等待事件标志被设置 if(xEventGroupWaitBits(print_event, /* 事件标志组句柄 */ 1, /* 等待被设置的事件标志位 */ pdFALSE, /* 选择是否清零被置位的事件标志位 */ pdFALSE, /* 选择是否等待所有标志位都被设置 */ 100) == 1){ /* 设置等待时间 */ while(used_length > 0){ putchar(print_buffer[flush_idx]); //输出 flush_idx++; if(flush_idx >= MAX_PRINTF_BUF_LEN) flush_idx-=MAX_PRINTF_BUF_LEN; taskENTER_CRITICAL(); /*为了保证不被中断,将操作放入临界区。进入临界区 */ used_length--; taskEXIT_CRITICAL(); /* 完成操作,离开临界区*/ } // clear event xEventGroupClearBits( print_event, 1); /* 事件标志位清零 */ } } } //打印日志初始化 void rtl_printf_init() { if(print_event==NULL){ print_event = xEventGroupCreate(); /* 创建事件标志组 */ if(print_event == NULL) /* 没有创建成功,用户可以在这里加入创建失败的处理机制 */ printf(" print event init fail! "); } if(print_task == NULL){ if(xTaskCreate(printing_task, /* 任务函数 */ (const char *)"print_task", /* 任务名 */ 512, /* 任务栈大小,单位 word,也就是 4 字节 */ NULL, /* 任务参数 */ tskIDLE_PRIORITY + 1, /* 任务优先级*/ &print_task) != pdPASS) /* 任务句柄 */ printf(" print task init fail! "); } } #endif //====================================================== //弱引用 __weak void console_init(void) { IRQ_HANDLE UartIrqHandle; //4 Register Log Uart Callback function UartIrqHandle.Data = NULL;//(u32)&UartAdapter; //中断 UartIrqHandle.IrqNum = UART_LOG_IRQ; //中断号 UartIrqHandle.IrqFun = (IRQ_FUN) UartLogIrqHandleRam;//中断函数 UartIrqHandle.Priority = 0; //中断优先级 //4 Register Isr handle InterruptUnRegister(&UartIrqHandle); //中断 InterruptRegister(&UartIrqHandle); //注册中断 #if !TASK_SCHEDULER_DISABLED RtlConsolInitRam((u32)RAM_STAGE,(u32)0,(VOID*)NULL); //禁止配置和制定自动任务 #else RtlConsolInitRam((u32)ROM_STAGE,(u32)0,(VOID*)NULL); #endif #if BUFFERED_PRINTF rtl_printf_init(); //无效 #endif }
主要是取消了MON_RAM_TEXT_SECTION注释