Z-Stack中串口的使用,涉及到一个字符串指针的问题。串口写函数如下
uint16 HalUARTWrite(uint8 port, uint8 *buf, uint16 len)
port 自不必说,HAL_UART_PORT_0或者_1,我想说的是字符串的长度。
首先,我们定义这样一个字符串,如下所示
uint8 *txBuffer = "I am uartCallBack";
HalUARTWrite(HAL_UART_PORT_0,txBuffer,17);
第二种方法,通过osal_strlen()函数读取字符串的长度。
uint8 *txBuffer = "I am uartCallBack";
HalUARTWrite(HAL_UART_PORT_0,txBuffer,osal_strlen(txBuffer));
osal_strlen()函数如下:
int osal_strlen( char *pString )
return (int)( strlen( pString ) );
可以看到osal_strlen()函数调用的就是c语言中的strlen()函数。通过调试,osal_strlen()计算出的结果就是17。那么,
如果我们的字符串不是采用字符串指针,而是采用数组的方式,那么还是采用osal_strlen()函数吗?
为什么会有这个疑问?疑问的产生来自于,字符串是通常被认为是常量,是保存在一段固定的内存中的,这段内存是
以'\0'为结束符,这段内存通常只能通过一个指针来找到。字符数组其实和其他数组没什么区别,只是保存的数据
类型是字符类型(char),它没有强制要求最后的元素是否是'\0'。那么既然这样,那么osal_strlen()计算出的长度
是否包含'\0',
长度究竟为多少呢?继续分析:
uint8 ttxBuffer[] = "I am Array";
HalUARTWrite(HAL_UART_PORT_0,ttxBuffer,osal_strlen(ttxBuffer));
如果是默认加个/0,那么这个数组的长度就为10+1。这个长度我们可以通过sizeof来验证该数组所占内存空间,
但是osal_strlen()计算出的大小就只为10。这是因为strlen()函数,计算长度的时候,是忽略掉/0的。结果就一目
了然了,使用osal_strlen的长度就可以实现HalUARTWrite的读写,而uart也不需要输出末尾的\0。
但是有个让我们模糊的地方就是TI的官方例子中,AF_DataRequest函数,发送一个字符数组,具体情况如下:
char theMessageData[] = "Hello World";
if ( AF_DataRequest( &MyApp_DstAddr, (endPointDesc_t *)&MyApp_epDesc,
MyApp_CLUSTERID,
(byte)osal_strlen( theMessageData ) + 1,
(byte *)&theMessageData,
&MyApp_TransID,
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
可以看到这里它使用了osal_strlen( theMessageData)+1来计算长度,也就是说,它加入了默认的/0。
具体原因不明,与uart正好相反。根据楼主的经验,字符数组和字符串都是不能直接使用osal_mem_free()
函数来释放内存的,否则会导致出错,而且IAR是不会告诉你是你释放内存导致出错的。只有在使用osal_mem_alloc()
函数分配的,才可以使用free()函数来释放内存。
根据楼主查找API文档得知,此函数仅在内存已经通过调用osal_mem_alloc被分配才有效。
附带一句,如果需要连接字符串,可以使用sprintf()函数,此函数灰常强大。童鞋们可以自行查找。
另外对c语言中字符串和字符数组还是不明白的,可以详细看看这篇文章,链接如下,写的很详细。
http://blog.chinaunix.net/uid-20937170-id-3274607.html