📄 osal.c
字号:
/*********************************************************************
Filename: OSAL.c
Revised: $Date: 2006-10-26 11:15:57 -0700 (Thu, 26 Oct 2006) $
Revision: $Revision: 12421 $
Description:
This API allows the software components in the Z-stack to be
written independently of the specifics of the operating system,
kernel or tasking environment (including control loops or
connect-to-interrupt systems).
Copyright (c) 2006 by Texas Instruments, Inc.
All Rights Reserved. Permission to use, reproduce, copy, prepare
derivative works, modify, distribute, perform, display or sell this
software and/or its documentation for any purpose is prohibited
without the express written consent of Texas Instruments, Inc.
*********************************************************************/
/*********************************************************************
* INCLUDES
*/
//#ifdef WIN32
// #include <stdio.h>
//#endif
#include <stdlib.h>
#include <string.h>
#include "ZComDef.h"
#include "OSAL.h"
#include "OSAL_Tasks.h"
#include "OSAL_Custom.h"
#include "OSAL_Memory.h"
#include "OSAL_PwrMgr.h"
#include "hal_mcu.h"
#include "OnBoard.h"
/* HAL */
#include "hal_drivers.h"
/*********************************************************************
* MACROS
*/
#define OSAL_MSG_LEN(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->len
#define OSAL_MSG_ID(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->dest_id
/*********************************************************************
* CONSTANTS
*/
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
// Message Pool Definitions
osal_msg_q_t osal_qHead;
#if defined( OSAL_TOTAL_MEM )
UINT16 osal_msg_cnt;
#endif
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
/*********************************************************************
* LOCAL FUNCTION PROTOTYPES
*/
/*********************************************************************
* HELPER FUNCTIONS
*/
/* very ugly stub so Keil can compile */
#ifdef __KEIL__
char * itoa ( int value, char * buffer, int radix )
{
return(buffer);
}
#endif
/*********************************************************************
* @fn osal_strlen
*
* @brief
*
* Calculates the length of a string. The string must be null
* terminated.
*
* @param char *pString - pointer to text string
*
* @return int - number of characters
*/
int osal_strlen( char *pString )
{
return strlen( pString );
}
/*********************************************************************
* @fn osal_memcpy
*
* @brief
*
* Generic memory copy.
*
* Note: This function differs from the standard memcpy(), since
* it returns the pointer to the next destination byte. The
* standard memcpy() returns the original destination address.
*
* @param dst - destination address
* @param src - source address
* @param len - number of bytes to copy
*
* @return pointer to end of destination buffer
*/
void *osal_memcpy( void *dst, const void GENERIC *src, unsigned int len )
{
byte *pDst;
const byte GENERIC *pSrc;
pSrc = src;
pDst = dst;
while ( len-- )
*pDst++ = *pSrc++;
return ( pDst );
}
/*********************************************************************
* @fn osal_cpyExtAddr
*
* @brief
*
* Copy extended addresses. This function will copy 8 bytes.
*
* @param dest destination address pointer
* @param src source address pointer
*
* @return dest + Z_EXTADDR_LEN
*/
void *osal_cpyExtAddr( void *dest, void *src )
{
return osal_memcpy( dest, src, Z_EXTADDR_LEN );
}
/*********************************************************************
* @fn osal_memset
*
* @brief
*
* Set memory buffer to value.
*
* @param dest - pointer to buffer
* @param value - what to set each byte of the message
* @param size - how big
*
* @return value of next widget, 0 if no widget found
*/
void *osal_memset( void *dest, byte value, int len )
{
return memset( dest, value, len );
}
/*********************************************************************
* @fn osal_build_uint16
*
* @brief
*
* Build a uint16 out of 2 bytes (0 then 1).
*
* @param swapped - 0 then 1
*
* @return uint16
*/
uint16 osal_build_uint16( byte *swapped )
{
return ( BUILD_UINT16( swapped[0], swapped[1] ) );
}
/*********************************************************************
* @fn osal_build_uint32
*
* @brief
*
* Build a uint32 out of sequential bytes.
*
* @param swapped - sequential bytes
* @param len - number of bytes in the byte array
*
* @return uint32
*/
uint32 osal_build_uint32( byte *swapped, byte len )
{
if ( len == 2 )
return ( BUILD_UINT32( swapped[0], swapped[1], 0L, 0L ) );
else if ( len == 3 )
return ( BUILD_UINT32( swapped[0], swapped[1], swapped[2], 0L ) );
else if ( len == 4 )
return ( BUILD_UINT32( swapped[0], swapped[1], swapped[2], swapped[3] ) );
else
return ( (uint32)swapped[0] );
}
#if !defined ( ZBIT ) && !defined ( ZBIT2 )
/*********************************************************************
* @fn _ltoa
*
* @brief
*
* convert a long unsigned int to a string.
*
* @param l - long to convert
* @param buf - buffer to convert to
* @param radix - 10 dec, 16 hex
*
* @return pointer to buffer
*/
unsigned char * _ltoa(unsigned long l, unsigned char *buf, unsigned char radix)
{
#if defined( __GNUC__ )
return ( (char*)ltoa( l, buf, radix ) );
#else
unsigned char tmp1[10] = "", tmp2[10] = "", tmp3[10] = "";
unsigned short num1, num2, num3;
unsigned char i;
buf[0] = '\0';
if ( radix == 10 )
{
num1 = l % 10000;
num2 = (l / 10000) % 10000;
num3 = (unsigned short)(l / 100000000);
if (num3) _itoa(num3, tmp3, 10);
if (num2) _itoa(num2, tmp2, 10);
if (num1) _itoa(num1, tmp1, 10);
if (num3)
{
strcpy((char*)buf, (char const*)tmp3);
for (i = 0; i < 4 - strlen((char const*)tmp2); i++)
strcat((char*)buf, "0");
}
strcat((char*)buf, (char const*)tmp2);
if (num3 || num2)
{
for (i = 0; i < 4 - strlen((char const*)tmp1); i++)
strcat((char*)buf, "0");
}
strcat((char*)buf, (char const*)tmp1);
if (!num3 && !num2 && !num1)
strcpy((char*)buf, "0");
}
else if ( radix == 16 )
{
num1 = l & 0x0000FFFF;
num2 = l >> 16;
if (num2) _itoa(num2, tmp2, 16);
if (num1) _itoa(num1, tmp1, 16);
if (num2)
{
strcpy((char*)buf,(char const*)tmp2);
for (i = 0; i < 4 - strlen((char const*)tmp1); i++)
strcat((char*)buf, "0");
}
strcat((char*)buf, (char const*)tmp1);
if (!num2 && !num1)
strcpy((char*)buf, "0");
}
else
return NULL;
return buf;
#endif
}
#endif // !defined(ZBIT) && !defined(ZBIT2)
/*********************************************************************
* @fn osal_AddrEqual
*
* @brief Compares two address_t structures.
*
* @param a1 - first Address
* @param a2 - second endpoint
*
* @return true - addresses are equal, false - not equal
*/
byte osal_AddrEqual( zAddrType_t *a1, zAddrType_t *a2 )
{
if ( a1->addrMode != a2->addrMode )
return ( false );
else if (a1->addrMode == AddrNotPresent )
return ( true );
else if (a1->addrMode == Addr16Bit )
return ( a1->addr.shortAddr == a2->addr.shortAddr );
else if ( a1->addrMode == Addr64Bit )
return ( osal_ExtAddrEqual( a1->addr.extAddr, a2->addr.extAddr ) );
else
return ( false );
}
/*********************************************************************
* @fn osal_ExtAddrEqual()
*
* @brief Verify that the extended addresses are equal.
*
* @param extAddr1 - extended address
* @param extAddr2 - extended address
*
* @return TRUE - If addresses are same
* FALSE - If not same
*/
byte osal_ExtAddrEqual( byte *extAddr1, byte *extAddr2 )
{
byte i;
for ( i = Z_EXTADDR_LEN; i ; i-- )
{
if ( *extAddr1++ != *extAddr2++ )
return ( false );
}
return ( true );
}
/*********************************************************************
* @fn osal_rand
*
* @brief Random number generator
*
* @param none
*
* @return uint16 - new random number
*/
uint16 osal_rand( void )
{
return ( Onboard_rand() );
}
/*********************************************************************
* API FUNCTIONS
*********************************************************************/
/*********************************************************************
* @fn osal_msg_allocate
*
* @brief
*
* This function is called by a task to allocate a message buffer
* into which the task will encode the particular message it wishes
* to send. This common buffer scheme is used to strictly limit the
* creation of message buffers within the system due to RAM size
* limitations on the microprocessor. Note that all message buffers
* are a fixed size (at least initially). The parameter len is kept
* in case a message pool with varying fixed message sizes is later
* created (for example, a pool of message buffers of size LARGE,
* MEDIUM and SMALL could be maintained and allocated based on request
* from the tasks).
*
*
* @param byte len - wanted buffer length
*
*
* @return pointer to allocated buffer or NULL if allocation failed.
*/
byte * osal_msg_allocate( uint16 len )
{
osal_msg_hdr_t *hdr;
if ( len == 0 )
return ( NULL );
hdr = (osal_msg_hdr_t *) osal_mem_alloc( (short)(len + sizeof( osal_msg_hdr_t )) );
if ( hdr )
{
hdr->next = NULL;
hdr->len = len;
hdr->dest_id = TASK_NO_TASK;
#if defined( OSAL_TOTAL_MEM )
osal_msg_cnt++;
#endif
return ( (byte *) (hdr + 1) );
}
else
return ( NULL );
}
/*********************************************************************
* @fn osal_msg_deallocate
*
* @brief
*
* This function is used to deallocate a message buffer. This function
* is called by a task (or processing element) after it has finished
* processing a received message.
*
*
* @param byte *msg_ptr - pointer to new message buffer
*
* @return ZSUCCESS, INVALID_MSG_POINTER
*/
byte osal_msg_deallocate( byte *msg_ptr )
{
byte *x;
if ( msg_ptr == NULL )
return ( INVALID_MSG_POINTER );
// don't deallocate queued buffer
if ( OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK )
return ( MSG_BUFFER_NOT_AVAIL );
x = (byte *)((byte *)msg_ptr - sizeof( osal_msg_hdr_t ));
osal_mem_free( (void *)x );
#if defined( OSAL_TOTAL_MEM )
if ( osal_msg_cnt )
osal_msg_cnt--;
#endif
return ( ZSUCCESS );
}
#if defined( OSAL_TOTAL_MEM )
/*********************************************************************
* @fn osal_num_msgs
*
* @brief
*
* This function returns the number of allocated messages
*
* @param void
*
* @return UINT16 - number of msgs out
*/
UINT16 osal_num_msgs( void )
{
return ( osal_msg_cnt );
}
#endif
/*********************************************************************
* @fn osal_msg_send
*
* @brief
*
* This function is called by a task to send a command message to
* another task or processing element. The sending_task field must
* refer to a valid task, since the task ID will be used
* for the response message. This function will also set a message
* ready event in the destination tasks event list.
*
*
* @param byte destination task - Send msg to? Task ID
* @param byte *msg_ptr - pointer to new message buffer
* @param byte len - length of data in message
*
* @return ZSUCCESS, INVALID_SENDING_TASK, INVALID_DESTINATION_TASK,
* INVALID_MSG_POINTER, INVALID_LEN
*/
byte osal_msg_send( byte destination_task, byte *msg_ptr )
{
if ( msg_ptr == NULL )
return ( INVALID_MSG_POINTER );
if ( osalFindTask( destination_task ) == NULL )
{
osal_msg_deallocate( msg_ptr );
return ( INVALID_TASK );
}
// Check the message header
if ( OSAL_MSG_NEXT( msg_ptr ) != NULL ||
OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK )
{
osal_msg_deallocate( msg_ptr );
return ( INVALID_MSG_POINTER );
}
OSAL_MSG_ID( msg_ptr ) = destination_task;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -