UART的接口说明和应用
一,常用API介绍drvUART.h已有注释的略去。void MDrv_UART_Init(UART_DEVICE_TYPEuart_dev, MS_U32 baudrate);会mdrv_uart_open一个default的uart port——_hDefaultUart,并设置它的波特率。 void MDrv_UART_PutChar(MS_U8 u8Ch);会向hDefaultUart输出一个字符。 void MDrv_UART_PutString(char *u8str);会向hDefaultUart输出字符串。 MS_U8 MDrv_UART_GetChar(void);会从hDefaultUart读取一个字符。 void MDrv_UART_GetFile(MS_U8 *pu8Buf,MS_U32 u32Len);会从hDefaultUart读取u32Len长度的字符。 c**t UART_DrvInfo*MDrv_UART_GetInfo(void);获取串口的初始化状态。 UART_Result MDrv_UART_GetStatus(UART_DrvStatus*pStatus);获取串口的使用状态。 void MDrv_UART_SetDbgLevel(MS_U8 level);typedef enum _UART_DbgLv{ E_UART_DBGLV_NONE //nodebug message ,E_UART_DBGLV_ERR_ONLY //showerror only ,E_UART_DBGLV_INFO //showerror & informaiton ,E_UART_DBGLV_ALL //show error, information &funciton name}UART_DbgLv;输出相应等级的打印信息。 以下函数如果编辑器sync不到这个函数,请自行在drvUART.h中补上,底层已有实现。 UART_Result MDrv_UART_SetRxMode(MS_BOOLbEnable, void *rx_buf, MS_U16 buf_len, ms_uart_rx_callback rx_cb)bEnable:Rx是否有效;rx_buf:设置Rx的缓存;buf_len:缓存的大小;rx_cb:设置Rx的callback,但为NULL时,设置的rx_buf无效,一般此处设个空函数,static void _rx_callback(int c){ //do not remove this function}
二,常见问题1.APP的串口的初始化会在操作系统启动时调用,不需要重复调用。2.串口的默认缓存只有16byte,一次发送数据超过16byte会接受不全,需要设置Rx的缓存,使用MDrv_UART_SetRxMode。3.mdrv_uart_read,MDrv_UART_GetChar,MDrv_UART_GetFile都是阻塞性函数,因此建议新建一个task去做。4.如果担心代码的打印信息影响串口通信,如果实在mboot下通信,请在mboot下在c**ole.c下208行修改#if 1//defined(CONFIG_JANUS) || defined(CONFIG_MARIA10) ,然后把宏里面的printf置空,在Stdio.h下把Printf的声明干掉。在HDMI初始化前设定MDrv_HDMITx_SetDbgLevel(0)这样以来就应该只剩GE_SetOnePixel这句了,这个可能需要改lib,不建议修改。如果是AP下通信,可在sysinit.c下把cyg_uart_putchar置空,然后在language_c_libc_stdio_printf.c里把printf从USBLOG_ENABLE这个宏里拿出来并置为空函数。5.如果需要清空缓存里的数据,可以用mdrv_uart_read,MDrv_UART_GetChar,MDrv_UART_GetFile把缓存的数据取走即可。
三,示范代码extern MS_S32 gs32CachedPoolID;extern MS_S32 gs32NonCachedPoolID; #define UART_TASK_STACK (4096 * 2) static MS_U32 _u32UARTDbgLevel = LDR_UART_DBG_ERR;static MS_S32 _s32uartTaskID = -1;static MS_U8 _uart_initd = 0;static MS_U8* _uartbuf = NULL;static MS_U32 _u32offset = 0;static MS_BOOL _bstarted = 0; static void _uartTaskEntry(void){ while (1) { if (_bstarted) { //mdrv_uart_read(_uart_hl,_uartbuf + _u32offset, 1); _uartbuf= MDrv_UART_GetChar(); _u32offset++; //MsOS_DelayTask(1); don't delay !!!! } else { MsOS_DelayTask(10); } }} static void _uartCreateTask(void){ void *puartTaskStack = NULL; // create filt task puartTaskStack = MsOS_AllocateMemory(UART_TASK_STACK, gs32CachedPoolID); UART_ASSERT(puartTaskStack > 0); _s32uartTaskID = MsOS_CreateTask((TaskEntry)_uartTaskEntry, (MS_U32)NULL, E_TASK_PRI_HIGH, TRUE, puartTaskStack, UART_TASK_STACK, (char*)"uart Task"); UART_ASSERT(_s32uartTaskID >= 0);} static void _rx_callback(int c){ //do not remove this function} L_INT32 Ldr_Uart_Init(L_VOID){ if (_uart_initd == 1) { return 0; } MDrv_UART_Init(E_UART_PIU_UART0, 115200); MDrv_UART_SetRxMode(TRUE, MsOS_AllocateMemory(40 * 1024,gs32NonCachedPoolID), 40 * 1024, _rx_callback); //_uart_hl = mdrv_uart_open(E_UART_PIU_UART0); if (NULL == _uartbuf) { _uartbuf = (MS_U8 *)MsOS_AllocateMemory(40 * 1024, gs32NonCachedPoolID); memset(_uartbuf, 0, 40 * 1024); UART_ASSERT(_uartbuf > 0); } _uartCreateTask(); _uart_initd = 1; return 0;} L_INT32Ldr_Uart_Read(L_UINT8*pReadBuffer, L_UINT32 *pLength, L_UINT32 uDelayTime){ UART_DBGMSG(LDR_UART_DBG_INFO, printf("%s\n", __FUNCTION__)); UART_ASSERT(pReadBuffer); UART_ASSERT(pLength); UART_ASSERT(_uart_initd); MS_U32 u32CurrentTime = MsOS_GetSystemTime(); _u32offset= 0; _bstarted = 1; while (MsOS_GetSystemTime() - u32CurrentTime < uDelayTime) { if (_u32offset == *pLength) { break; } else { MsOS_DelayTask(5); } } if (_u32offset > 0) { memcpy(pReadBuffer, _uartbuf, _u32offset); _u32offset = 0; _bstarted= 0; *pLength = _u32offset; return 0; } return -1;} L_INT32Ldr_Uart_Write(L_UINT8*pWriteBuffer, L_UINT32 *pLength, L_UINT32 uDelayTime){ UART_ASSERT(pWriteBuffer); UART_ASSERT(pLength); intilen = 0; while (ilen < *pLength) { MDrv_UART_PutChar(pWriteBuffer); ilen++; } return0;}
基本协议,非常详细说明了串口机制 好东西,感谢分享。
页:
[1]