RTL8711AM

官方文档主要修改

为了实现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 ('\0').
#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("\r\n");			\
		}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	"\r\n\n# " //each AT command response will end with this string
#define STR_END_OF_ATDATA_RET	"\r\n\n> " //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, '\0');
                }
            }
        }
    }
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,'\0');
    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!!\n");
		}
	}
#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!!\n");
	}
#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, '\0');
}
//======================================================
// 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("\n\rprint event init fail!\n");
    }
    if(print_task == NULL){
        if(xTaskCreate(printing_task,                   /* 任务函数 */
                       (const char *)"print_task",      /* 任务名 */
                       512,                             /* 任务栈大小,单位 word,也就是 4 字节 */
                       NULL,                            /* 任务参数 */
                       tskIDLE_PRIORITY + 1,            /* 任务优先级*/
                       &print_task) != pdPASS)          /* 任务句柄 */
            printf("\n\rprint task init fail!\n");
    }
}
#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注释

posted @ 2017-10-16 18:19  O(∩_∩)O哈哈哈~呵呵  阅读(1259)  评论(0编辑  收藏  举报