Z-Stack中HalUARTWrite的使用以及osal_strlen()的使用

本文深入探讨了Z-Stack中串口的使用,特别是涉及字符串指针的问题。详细介绍了如何通过函数计算字符串长度,并对比了使用字符串指针与数组方式的区别。文章还分析了TI官方例子中AF_DataRequest函数的实现细节,以及字符串和字符数组在内存管理和释放上的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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





/************************************************************************************************** Filename: ZMain.c Revised: $Date: 2010-09-17 16:25:30 -0700 (Fri, 17 Sep 2010) $ Revision: $Revision: 23835 $ Description: Startup and shutdown code for ZStack Notes: This version targets the Chipcon CC2530 Copyright 2005-2010 Texas Instruments Incorporated. All rights reserved. IMPORTANT: Your use of this Software is limited to those specific rights granted under the terms of a software license agreement between the user who downloaded the software, his/her employer (which must be your employer) and Texas Instruments Incorporated (the "License"). You may not use this Software unless you agree to abide by the terms of the License. The License limits your use, and you acknowledge, that the Software may not be modified, copied or distributed unless embedded on a Texas Instruments microcontroller or used solely and exclusively in conjunction with a Texas Instruments radio frequency transceiver, which is integrated into your product. Other than for the foregoing purpose, you may not use, reproduce, copy, prepare derivative works of, modify, distribute, perform, display or sell this Software and/or its documentation for any purpose. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED 揂S IS?WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. Should you have any questions regarding your right to use this Software, contact Texas Instruments Incorporated at www.TI.com. **************************************************************************************************/ /********************************************************************* * INCLUDES */ #ifndef NONWK #include "AF.h" #endif #include "hal_adc.h" #include "hal_flash.h" #include "hal_lcd.h" #include "hal_led.h" #include "hal_drivers.h" #include "OnBoard.h" #include "OSAL.h" #include "OSAL_Nv.h" #include "ZComDef.h" #include "ZMAC.h" /********************************************************************* * LOCAL FUNCTIONS */ static void zmain_ext_addr( void ); #if defined ZCL_KEY_ESTABLISH static void zmain_cert_init( void ); #endif static void zmain_dev_info( void ); static void zmain_vdd_check( void ); #ifdef LCD_SUPPORTED static void zmain_lcd_init( void ); #endif /********************************************************************* * @fn main * @brief First function called after startup. * @return don't care */ int main( void ) { // Turn off interrupts osal_int_disable( INTS_ALL );//关闭中断 // Initialization for board related stuff such as LEDs HAL_BOARD_INIT();//电路板初始化 // Make sure supply voltage is high enough to run zmain_vdd_check();//供电电压检测 // Initialize board I/O InitBoard( OB_COLD );//初始电路板IO口 // Initialze HAL drivers HalDriverInit();//初始化硬件抽样层驱动 // Initialize NV System osal_nv_init( NULL );//初始化NVFLASH // Initialize the MAC ZMacInit();//初始化MAC地址 // Determine the extended address zmain_ext_addr();//读取扩展地址 #if defined ZCL_KEY_ESTABLISH // Initialize the Certicom certificate information. zmain_cert_init(); #endif // Initialize basic NV items zgInit(); #ifndef NONWK // Since the AF isn't a task, call it's initialization routine afInit(); #endif // Initialize the operating system osal_init_system(); // Allow interrupts osal_int_enable( INTS_ALL ); // Final board initialization InitBoard( OB_READY ); // Display information about this device zmain_dev_info(); /* Display the device info on the LCD */ #ifdef LCD_SUPPORTED zmain_lcd_init(); #endif #ifdef WDT_IN_PM1 /* If WDT is used, this is a good place to enable it. */ WatchDogEnable( WDTIMX ); #endif osal_start_system(); // No Return from here return 0; // Shouldn't get here. } // main() /********************************************************************* * @fn zmain_vdd_check * @brief Check if the Vdd is OK to run the processor. * @return Return if Vdd is ok; otherwise, flash LED, then reset *********************************************************************/ static void zmain_vdd_check( void ) { uint8 cnt = 16; do { while (!HalAdcCheckVdd(VDD_MIN_RUN)); } while (--cnt); } /************************************************************************************************** * @fn zmain_ext_addr * * @brief Execute a prioritized search for a valid extended address and write the results * into the OSAL NV system for use by the system. Temporary address not saved to NV. * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void zmain_ext_addr(void) { uint8 nullAddr[Z_EXTADDR_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8 writeNV = TRUE; // First check whether a non-erased extended address exists in the OSAL NV. if ((SUCCESS != osal_nv_item_init(ZCD_NV_EXTADDR, Z_EXTADDR_LEN, NULL)) || (SUCCESS != osal_nv_read(ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, aExtendedAddress)) || (osal_memcmp(aExtendedAddress, nullAddr, Z_EXTADDR_LEN))) { // Attempt to read the extended address from the location on the lock bits page // where the programming tools know to reserve it. HalFlashRead(HAL_FLASH_IEEE_PAGE, HAL_FLASH_IEEE_OSET, aExtendedAddress, Z_EXTADDR_LEN); if (osal_memcmp(aExtendedAddress, nullAddr, Z_EXTADDR_LEN)) { // Attempt to read the extended address from the designated location in the Info Page. if (!osal_memcmp((uint8 *)(P_INFOPAGE+HAL_INFOP_IEEE_OSET), nullAddr, Z_EXTADDR_LEN)) { osal_memcpy(aExtendedAddress, (uint8 *)(P_INFOPAGE+HAL_INFOP_IEEE_OSET), Z_EXTADDR_LEN); } else // No valid extended address was found. { uint8 idx; #if !defined ( NV_RESTORE ) writeNV = FALSE; // Make this a temporary IEEE address #endif /* Attempt to create a sufficiently random extended address for expediency. * Note: this is only valid/legal in a test environment and * must never be used for a commercial product. */ for (idx = 0; idx < (Z_EXTADDR_LEN - 2);) { uint16 randy = osal_rand(); aExtendedAddress[idx++] = LO_UINT16(randy); aExtendedAddress[idx++] = HI_UINT16(randy); } // Next-to-MSB identifies ZigBee devicetype. #if ZG_BUILD_COORDINATOR_TYPE && !ZG_BUILD_JOINING_TYPE aExtendedAddress[idx++] = 0x10; #elif ZG_BUILD_RTRONLY_TYPE aExtendedAddress[idx++] = 0x20; #else aExtendedAddress[idx++] = 0x30; #endif // MSB has historical signficance. aExtendedAddress[idx] = 0xF8; } } if (writeNV) { (void)osal_nv_write(ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, aExtendedAddress); } } // Set the MAC PIB extended address according to results from above. (void)ZMacSetReq(MAC_EXTENDED_ADDRESS, aExtendedAddress); } #if defined ZCL_KEY_ESTABLISH /************************************************************************************************** * @fn zmain_cert_init * * @brief Initialize the Certicom certificate information. * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void zmain_cert_init(void) { uint8 certData[ZCL_KE_IMPLICIT_CERTIFICATE_LEN]; uint8 nullData[ZCL_KE_IMPLICIT_CERTIFICATE_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; (void)osal_nv_item_init(ZCD_NV_IMPLICIT_CERTIFICATE, ZCL_KE_IMPLICIT_CERTIFICATE_LEN, NULL); (void)osal_nv_item_init(ZCD_NV_DEVICE_PRIVATE_KEY, ZCL_KE_DEVICE_PRIVATE_KEY_LEN, NULL); // First check whether non-null certificate data exists in the OSAL NV. To save on code space, // just use the ZCD_NV_CA_PUBLIC_KEY as the bellwether for all three. if ((SUCCESS != osal_nv_item_init(ZCD_NV_CA_PUBLIC_KEY, ZCL_KE_CA_PUBLIC_KEY_LEN, NULL)) || (SUCCESS != osal_nv_read(ZCD_NV_CA_PUBLIC_KEY, 0, ZCL_KE_CA_PUBLIC_KEY_LEN, certData)) || (osal_memcmp(certData, nullData, ZCL_KE_CA_PUBLIC_KEY_LEN))) { // Attempt to read the certificate data from its corresponding location on the lock bits page. HalFlashRead(HAL_FLASH_IEEE_PAGE, HAL_FLASH_CA_PUBLIC_KEY_OSET, certData, ZCL_KE_CA_PUBLIC_KEY_LEN); // If the certificate data is not NULL, use it to update the corresponding NV items. if (!osal_memcmp(certData, nullData, ZCL_KE_CA_PUBLIC_KEY_LEN)) { (void)osal_nv_write(ZCD_NV_CA_PUBLIC_KEY, 0, ZCL_KE_CA_PUBLIC_KEY_LEN, certData); HalFlashRead(HAL_FLASH_IEEE_PAGE, HAL_FLASH_IMPLICIT_CERT_OSET, certData, ZCL_KE_IMPLICIT_CERTIFICATE_LEN); (void)osal_nv_write(ZCD_NV_IMPLICIT_CERTIFICATE, 0, ZCL_KE_IMPLICIT_CERTIFICATE_LEN, certData); HalFlashRead(HAL_FLASH_IEEE_PAGE, HAL_FLASH_DEV_PRIVATE_KEY_OSET, certData, ZCL_KE_DEVICE_PRIVATE_KEY_LEN); (void)osal_nv_write(ZCD_NV_DEVICE_PRIVATE_KEY, 0, ZCL_KE_DEVICE_PRIVATE_KEY_LEN, certData); } } } #endif /************************************************************************************************** * @fn zmain_dev_info * * @brief This displays the IEEE (MSB to LSB) on the LCD. * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void zmain_dev_info(void) { #ifdef LCD_SUPPORTED uint8 i; uint8 *xad; uint8 lcd_buf[Z_EXTADDR_LEN*2+1]; // Display the extended address. xad = aExtendedAddress + Z_EXTADDR_LEN - 1; for (i = 0; i < Z_EXTADDR_LEN*2; xad--) { uint8 ch; ch = (*xad >> 4) & 0x0F; lcd_buf[i++] = ch + (( ch < 10 ) ? '0' : '7'); ch = *xad & 0x0F; lcd_buf[i++] = ch + (( ch < 10 ) ? '0' : '7'); } lcd_buf[Z_EXTADDR_LEN*2] = '\0'; HalLcdWriteString( "IEEE: ", HAL_LCD_LINE_1 ); HalLcdWriteString( (char*)lcd_buf, HAL_LCD_LINE_2 ); #endif } #ifdef LCD_SUPPORTED /********************************************************************* * @fn zmain_lcd_init * @brief Initialize LCD at start up. * @return none *********************************************************************/ static void zmain_lcd_init ( void ) { #ifdef SERIAL_DEBUG_SUPPORTED { HalLcdWriteString( "TexasInstruments", HAL_LCD_LINE_1 ); #if defined( MT_MAC_FUNC ) #if defined( ZDO_COORDINATOR ) HalLcdWriteString( "MAC-MT Coord", HAL_LCD_LINE_2 ); #else HalLcdWriteString( "MAC-MT Device", HAL_LCD_LINE_2 ); #endif // ZDO #elif defined( MT_NWK_FUNC ) #if defined( ZDO_COORDINATOR ) HalLcdWriteString( "NWK Coordinator", HAL_LCD_LINE_2 ); #else HalLcdWriteString( "NWK Device", HAL_LCD_LINE_2 ); #endif // ZDO #endif // MT_FUNC } #endif // SERIAL_DEBUG_SUPPORTED } #endif /********************************************************************* *********************************************************************/ 以上是DHT11代码,请帮我生成一个光敏代码
最新发布
06-25
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值