initial commit
This commit is contained in:
Vendored
+53
@@ -0,0 +1,53 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_assert.c
|
||||
*
|
||||
* \brief Assert implementation.
|
||||
*
|
||||
* $Date: 2014-04-17 16:13:59 -0700 (Thu, 17 Apr 2014) $
|
||||
* $Revision: 1398 $
|
||||
*
|
||||
* Copyright (c) 2009 Wicentric, Inc., all rights reserved.
|
||||
* Wicentric confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact Wicentric, Inc. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_os.h"
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \def WsfAssert
|
||||
*
|
||||
* \brief Perform an assert action.
|
||||
*
|
||||
* \param pFile Name of file originating assert.
|
||||
* \param line Line number of assert statement.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfAssert(const char *pFile, uint16_t line)
|
||||
{
|
||||
volatile uint8_t escape=0;
|
||||
|
||||
/* spin forever if fatal error occurred */
|
||||
for(;;)
|
||||
{
|
||||
/*
|
||||
* However, you can exit with a debugger by setting variable 'escape'.
|
||||
* Handy to see where the assert happened if you cannot view the call stack.
|
||||
*/
|
||||
if (escape)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+71
@@ -0,0 +1,71 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_assert.h
|
||||
*
|
||||
* \brief Assert macro.
|
||||
*
|
||||
* $Date: 2011-10-14 21:35:03 -0700 (Fri, 14 Oct 2011) $
|
||||
* $Revision: 191 $
|
||||
*
|
||||
* Copyright (c) 2009 Wicentric, Inc., all rights reserved.
|
||||
* Wicentric confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact Wicentric, Inc. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef WSF_ASSERT_H
|
||||
#define WSF_ASSERT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Prototypes
|
||||
**************************************************************************************************/
|
||||
|
||||
void WsfAssert(const char *pFile, uint16_t line);
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \def WSF_ASSERT
|
||||
*
|
||||
* \brief Run-time assert macro. The assert executes when the expression is FALSE.
|
||||
*
|
||||
* \param expr Boolean expression to be tested.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#if WSF_ASSERT_ENABLED == TRUE
|
||||
#define WSF_ASSERT(expr) if (!(expr)) {WsfAssert(__FILE__, (uint16_t) __LINE__);}
|
||||
#else
|
||||
#define WSF_ASSERT(expr)
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \def WSF_CT_ASSERT
|
||||
*
|
||||
* \brief Compile-time assert macro. This macro causes a compiler error when the
|
||||
* expression is FALSE. Note that this macro is generally used at file scope to
|
||||
* test constant expressions. Errors may result of it is used in executing code.
|
||||
*
|
||||
* \param expr Boolean expression to be tested.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#define WSF_CT_ASSERT(expr) extern char wsf_ct_assert[(expr) ? 1 : -1]
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* WSF_ASSERT_H */
|
||||
+484
@@ -0,0 +1,484 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_buf.c
|
||||
*
|
||||
* \brief Buffer pool service.
|
||||
*
|
||||
* $Date: 2017-03-04 13:45:34 -0600 (Sat, 04 Mar 2017) $
|
||||
* $Revision: 11379 $
|
||||
*
|
||||
* Copyright (c) 2009-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_buf.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_math.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "wsf_cs.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Configuration
|
||||
**************************************************************************************************/
|
||||
|
||||
/* check if trying to free a buffer that is already free */
|
||||
#ifndef WSF_BUF_FREE_CHECK
|
||||
#define WSF_BUF_FREE_CHECK TRUE
|
||||
#endif
|
||||
|
||||
/* assert on best-fit buffer allocation failure */
|
||||
#ifndef WSF_BUF_ALLOC_BEST_FIT_FAIL_ASSERT
|
||||
#define WSF_BUF_ALLOC_BEST_FIT_FAIL_ASSERT FALSE
|
||||
#endif
|
||||
|
||||
/* assert on buffer allocation failure */
|
||||
#ifndef WSF_BUF_ALLOC_FAIL_ASSERT
|
||||
#define WSF_BUF_ALLOC_FAIL_ASSERT TRUE
|
||||
#endif
|
||||
|
||||
/* buffer allocation stats */
|
||||
#ifndef WSF_BUF_STATS
|
||||
#define WSF_BUF_STATS FALSE
|
||||
#endif
|
||||
|
||||
/* buffer histogram stats */
|
||||
#ifndef WSF_BUF_STATS_HIST
|
||||
#define WSF_BUF_STATS_HIST FALSE
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/* magic number used to check for free buffer */
|
||||
#define WSF_BUF_FREE_NUM 0xFAABD00D
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/* Unit of memory storage-- a structure containing a pointer */
|
||||
typedef struct wsfBufMem_tag
|
||||
{
|
||||
struct wsfBufMem_tag *pNext;
|
||||
#if WSF_BUF_FREE_CHECK == TRUE
|
||||
uint32_t free;
|
||||
#endif
|
||||
} wsfBufMem_t;
|
||||
|
||||
/* Internal buffer pool */
|
||||
typedef struct
|
||||
{
|
||||
wsfBufPoolDesc_t desc; /* number of buffers and length */
|
||||
wsfBufMem_t *pStart; /* start of pool */
|
||||
wsfBufMem_t *pFree; /* first free buffer in pool */
|
||||
#if WSF_BUF_STATS == TRUE
|
||||
uint8_t numAlloc; /* number of buffers currently allocated from pool */
|
||||
uint8_t maxAlloc; /* maximum buffers ever allocated from pool */
|
||||
uint16_t maxReqLen; /* maximum request length from pool. */
|
||||
#endif
|
||||
} wsfBufPool_t;
|
||||
|
||||
/**************************************************************************************************
|
||||
Global Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/* Number of pools */
|
||||
uint8_t wsfBufNumPools;
|
||||
|
||||
/* Memory used for pools */
|
||||
wsfBufMem_t *wsfBufMem = NULL;
|
||||
|
||||
/* Currently use for debugging only */
|
||||
uint16_t wsfBufMemLen;
|
||||
|
||||
#if WSF_BUF_STATS_HIST == TRUE
|
||||
/* Buffer allocation counter */
|
||||
uint8_t wsfBufAllocCount[WSF_BUF_STATS_MAX_LEN];
|
||||
#endif
|
||||
|
||||
#if WSF_OS_DIAG == TRUE
|
||||
/* WSF buffer diagnostic callback function */
|
||||
static wsfBufDiagCback_t wsfBufDiagCback = NULL;
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfBufInit
|
||||
*
|
||||
* \brief Initialize the buffer pool service. This function should only be called once
|
||||
* upon system initialization.
|
||||
*
|
||||
* \param bufMemLen Length of free memory
|
||||
* \param pBufMem Free memory buffer for building buffer pools
|
||||
* \param numPools Number of buffer pools.
|
||||
* \param pDesc Array of buffer pool descriptors, one for each pool.
|
||||
*
|
||||
* \return Amount of pBufMem used or 0 for failures.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint16_t WsfBufInit(uint16_t bufMemLen, uint8_t *pBufMem, uint8_t numPools, wsfBufPoolDesc_t *pDesc)
|
||||
{
|
||||
wsfBufPool_t *pPool;
|
||||
wsfBufMem_t *pStart;
|
||||
uint16_t len;
|
||||
uint8_t i;
|
||||
|
||||
wsfBufMem = (wsfBufMem_t *) pBufMem;
|
||||
pPool = (wsfBufPool_t *) wsfBufMem;
|
||||
|
||||
/* buffer storage starts after the pool structs */
|
||||
pStart = (wsfBufMem_t *) (pPool + numPools);
|
||||
|
||||
wsfBufNumPools = numPools;
|
||||
|
||||
/* create each pool; see loop exit condition below */
|
||||
while (TRUE)
|
||||
{
|
||||
/* verify we didn't overrun memory; if we did, abort */
|
||||
if (pStart > &wsfBufMem[bufMemLen / sizeof(wsfBufMem_t)])
|
||||
{
|
||||
WSF_ASSERT(FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* exit loop after verification check */
|
||||
if (numPools-- == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* adjust pool lengths for minimum size and alignment */
|
||||
if (pDesc->len < sizeof(wsfBufMem_t))
|
||||
{
|
||||
pPool->desc.len = sizeof(wsfBufMem_t);
|
||||
}
|
||||
else if ((pDesc->len % sizeof(wsfBufMem_t)) != 0)
|
||||
{
|
||||
pPool->desc.len = pDesc->len + sizeof(wsfBufMem_t) - (pDesc->len % sizeof(wsfBufMem_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
pPool->desc.len = pDesc->len;
|
||||
}
|
||||
|
||||
pPool->desc.num = pDesc->num;
|
||||
pDesc++;
|
||||
|
||||
pPool->pStart = pStart;
|
||||
pPool->pFree = pStart;
|
||||
#if WSF_BUF_STATS == TRUE
|
||||
pPool->numAlloc = 0;
|
||||
pPool->maxAlloc = 0;
|
||||
pPool->maxReqLen = 0;
|
||||
#endif
|
||||
|
||||
WSF_TRACE_INFO2("Creating pool len=%u num=%u", pPool->desc.len, pPool->desc.num);
|
||||
WSF_TRACE_INFO1(" pStart=0x%x", (uint32_t)pPool->pStart);
|
||||
|
||||
/* initialize free list */
|
||||
len = pPool->desc.len / sizeof(wsfBufMem_t);
|
||||
for (i = pPool->desc.num; i > 1; i--)
|
||||
{
|
||||
/* verify we didn't overrun memory; if we did, abort */
|
||||
if (pStart > &wsfBufMem[bufMemLen / sizeof(wsfBufMem_t)])
|
||||
{
|
||||
WSF_ASSERT(FALSE);
|
||||
return 0;
|
||||
}
|
||||
/* pointer to the next free buffer is stored in the buffer itself */
|
||||
pStart->pNext = pStart + len;
|
||||
pStart += len;
|
||||
}
|
||||
|
||||
/* verify we didn't overrun memory; if we did, abort */
|
||||
if (pStart > &wsfBufMem[bufMemLen / sizeof(wsfBufMem_t)])
|
||||
{
|
||||
WSF_ASSERT(FALSE);
|
||||
return 0;
|
||||
}
|
||||
/* last one in list points to NULL */
|
||||
pStart->pNext = NULL;
|
||||
pStart += len;
|
||||
|
||||
/* next pool */
|
||||
pPool++;
|
||||
}
|
||||
|
||||
wsfBufMemLen = (uint8_t *) pStart - (uint8_t *) wsfBufMem;
|
||||
WSF_TRACE_INFO1("Created buffer pools; using %u bytes", wsfBufMemLen);
|
||||
|
||||
return wsfBufMemLen;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfBufAlloc
|
||||
*
|
||||
* \brief Allocate a buffer.
|
||||
*
|
||||
* \param len Length of buffer to allocate.
|
||||
*
|
||||
* \return Pointer to allocated buffer or NULL if allocation fails.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void *WsfBufAlloc(uint16_t len)
|
||||
{
|
||||
wsfBufPool_t *pPool;
|
||||
wsfBufMem_t *pBuf;
|
||||
uint8_t i;
|
||||
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
WSF_ASSERT(len > 0);
|
||||
|
||||
pPool = (wsfBufPool_t *) wsfBufMem;
|
||||
|
||||
for (i = wsfBufNumPools; i > 0; i--, pPool++)
|
||||
{
|
||||
/* if buffer is big enough */
|
||||
if (len <= pPool->desc.len)
|
||||
{
|
||||
/* enter critical section */
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
/* if buffers available */
|
||||
if (pPool->pFree != NULL)
|
||||
{
|
||||
/* allocation succeeded */
|
||||
pBuf = pPool->pFree;
|
||||
|
||||
/* next free buffer is stored inside current free buffer */
|
||||
pPool->pFree = pBuf->pNext;
|
||||
|
||||
#if WSF_BUF_FREE_CHECK == TRUE
|
||||
pBuf->free = 0;
|
||||
#endif
|
||||
#if WSF_BUF_STATS_HIST == TRUE
|
||||
/* increment count for buffers of this length */
|
||||
if (len < WSF_BUF_STATS_MAX_LEN)
|
||||
{
|
||||
wsfBufAllocCount[len]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
wsfBufAllocCount[0]++;
|
||||
}
|
||||
#endif
|
||||
#if WSF_BUF_STATS == TRUE
|
||||
if (++pPool->numAlloc > pPool->maxAlloc)
|
||||
{
|
||||
pPool->maxAlloc = pPool->numAlloc;
|
||||
}
|
||||
pPool->maxReqLen = WSF_MAX(pPool->maxReqLen, len);
|
||||
#endif
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
WSF_TRACE_ALLOC2("WsfBufAlloc len:%u pBuf:%08x", pPool->desc.len, pBuf);
|
||||
|
||||
return pBuf;
|
||||
}
|
||||
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
#if WSF_BUF_ALLOC_BEST_FIT_FAIL_ASSERT == TRUE
|
||||
WSF_ASSERT(FALSE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* allocation failed */
|
||||
#if WSF_OS_DIAG == TRUE
|
||||
if (wsfBufDiagCback != NULL)
|
||||
{
|
||||
WsfBufDiag_t info;
|
||||
|
||||
info.type = WSF_BUF_ALLOC_FAILED;
|
||||
info.param.alloc.taskId = WSF_OS_GET_ACTIVE_HANDLER_ID();
|
||||
info.param.alloc.len = len;
|
||||
|
||||
wsfBufDiagCback(&info);
|
||||
}
|
||||
else
|
||||
{
|
||||
WSF_TRACE_WARN2("WsfBufAlloc failed len:%u - task:%u", len, WSF_OS_GET_ACTIVE_HANDLER_ID());
|
||||
}
|
||||
#else
|
||||
WSF_TRACE_WARN1("WsfBufAlloc failed len:%u", len);
|
||||
#endif
|
||||
|
||||
#if WSF_BUF_ALLOC_FAIL_ASSERT == TRUE
|
||||
WSF_ASSERT(FALSE);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfBufFree
|
||||
*
|
||||
* \brief Free a buffer.
|
||||
*
|
||||
* \param pBuf Buffer to free.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfBufFree(void *pBuf)
|
||||
{
|
||||
wsfBufPool_t *pPool;
|
||||
wsfBufMem_t *p = pBuf;
|
||||
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
/* verify pointer is within range */
|
||||
#if WSF_BUF_FREE_CHECK == TRUE
|
||||
WSF_ASSERT(p >= ((wsfBufPool_t *) wsfBufMem)->pStart);
|
||||
WSF_ASSERT(p < (wsfBufMem_t *)(((uint8_t *) wsfBufMem) + wsfBufMemLen));
|
||||
#endif
|
||||
|
||||
/* iterate over pools starting from last pool */
|
||||
pPool = (wsfBufPool_t *) wsfBufMem + (wsfBufNumPools - 1);
|
||||
while (pPool >= (wsfBufPool_t *) wsfBufMem)
|
||||
{
|
||||
/* if the buffer memory is located inside this pool */
|
||||
if (p >= pPool->pStart)
|
||||
{
|
||||
/* enter critical section */
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
#if WSF_BUF_FREE_CHECK == TRUE
|
||||
WSF_ASSERT(p->free != WSF_BUF_FREE_NUM);
|
||||
p->free = WSF_BUF_FREE_NUM;
|
||||
#endif
|
||||
#if WSF_BUF_STATS == TRUE
|
||||
pPool->numAlloc--;
|
||||
#endif
|
||||
|
||||
/* pool found; put buffer back in free list */
|
||||
p->pNext = pPool->pFree;
|
||||
pPool->pFree = p;
|
||||
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
WSF_TRACE_FREE2("WsfBufFree len:%u pBuf:%08x", pPool->desc.len, pBuf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* next pool */
|
||||
pPool--;
|
||||
}
|
||||
|
||||
/* should never get here */
|
||||
WSF_ASSERT(FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfBufGetAllocStats
|
||||
*
|
||||
* \brief Diagnostic function to get the buffer allocation statistics.
|
||||
*
|
||||
* \return Buffer allocation statistics array.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t *WsfBufGetAllocStats(void)
|
||||
{
|
||||
#if WSF_BUF_STATS_HIST == TRUE
|
||||
return wsfBufAllocCount;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfBufGetNumPool
|
||||
*
|
||||
* \brief Get number of pools.
|
||||
*
|
||||
* \return Number of pools.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t WsfBufGetNumPool(void)
|
||||
{
|
||||
return wsfBufNumPools;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfBufGetPoolStats
|
||||
*
|
||||
* \brief Get statistics for each pool.
|
||||
*
|
||||
* \param pBuf Buffer to store the statistics.
|
||||
* \param poolId Pool ID.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfBufGetPoolStats(WsfBufPoolStat_t *pStat, uint8_t poolId)
|
||||
{
|
||||
wsfBufPool_t *pPool;
|
||||
|
||||
if (poolId >= wsfBufNumPools)
|
||||
{
|
||||
pStat->bufSize = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
WSF_CS_INIT(cs);
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
pPool = (wsfBufPool_t *) wsfBufMem;
|
||||
|
||||
pStat->bufSize = pPool[poolId].desc.len;
|
||||
pStat->numBuf = pPool[poolId].desc.num;
|
||||
#if WSF_BUF_STATS == TRUE
|
||||
pStat->numAlloc = pPool[poolId].numAlloc;
|
||||
pStat->maxAlloc = pPool[poolId].maxAlloc;
|
||||
pStat->maxReqLen = pPool[poolId].maxReqLen;
|
||||
#else
|
||||
pStat->numAlloc = 0;
|
||||
pStat->maxAlloc = 0;
|
||||
pStat->maxReqLen = 0;
|
||||
#endif
|
||||
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfBufDiagRegister
|
||||
*
|
||||
* \brief Called to register the buffer diagnostics callback function.
|
||||
*
|
||||
* \param pCallback Pointer to the callback function.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfBufDiagRegister(wsfBufDiagCback_t callback)
|
||||
{
|
||||
#if WSF_OS_DIAG == TRUE
|
||||
wsfBufDiagCback = callback;
|
||||
#endif
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_cs.h
|
||||
*
|
||||
* \brief Critical section macros.
|
||||
*
|
||||
* $Date: 2012-11-20 00:27:38 -0800 (Tue, 20 Nov 2012) $
|
||||
* $Revision: 377 $
|
||||
*
|
||||
* Copyright (c) 2009 Wicentric, Inc., all rights reserved.
|
||||
* Wicentric confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact Wicentric, Inc. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef WSF_CS_H
|
||||
#define WSF_CS_H
|
||||
|
||||
#include "wsf_os.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \def WSF_CS_INIT
|
||||
*
|
||||
* \brief Initialize critical section. This macro may define a variable.
|
||||
*
|
||||
* \param cs Critical section variable to be defined.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#define WSF_CS_INIT(cs)
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \def WSF_CS_ENTER
|
||||
*
|
||||
* \brief Enter a critical section.
|
||||
*
|
||||
* \param cs Critical section variable.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#define WSF_CS_ENTER(cs) WsfCsEnter()
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \def WSF_CS_EXIT
|
||||
*
|
||||
* \brief Exit a critical section.
|
||||
*
|
||||
* \param cs Critical section variable.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#define WSF_CS_EXIT(cs) WsfCsExit()
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Declarations
|
||||
**************************************************************************************************/
|
||||
void WsfCsEnter(void);
|
||||
void WsfCsExit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* WSF_CS_H */
|
||||
+681
@@ -0,0 +1,681 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_efs.c
|
||||
*
|
||||
* \brief Embedded File System service.
|
||||
*
|
||||
* $Date: 2017-03-09 12:18:38 -0600 (Thu, 09 Mar 2017) $
|
||||
* $Revision: 11460 $
|
||||
*
|
||||
* Copyright (c) 2014-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_efs.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "wsf_cs.h"
|
||||
#include "bstream.h"
|
||||
|
||||
/* Media Control Block */
|
||||
static pWsfEfsMedia_t wsfEfsMediaTbl[WSF_EFS_MAX_MEDIA];
|
||||
|
||||
/* File Control Block */
|
||||
static wsfEfsControl_t wsfEfsFileTbl[WSF_EFS_MAX_FILES];
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn wsfEfsMediaValid
|
||||
*
|
||||
* \brief Checks if the given physical media identifier has been registered with the file system.
|
||||
*
|
||||
* \param media The physical media identifier
|
||||
*
|
||||
* \return TRUE if valid, else FALSE.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static bool_t wsfEfsMediaValid(uint8_t media)
|
||||
{
|
||||
if (media < WSF_EFS_MAX_MEDIA && wsfEfsMediaTbl[media])
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsGetFileByHandle
|
||||
*
|
||||
* \brief Returns the file control block for the given handle.
|
||||
*
|
||||
* \param handle Handle of the file
|
||||
*
|
||||
* \return File control block, or NULL.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
wsfEfsControl_t *WsfEfsGetFileByHandle(wsfEfsHandle_t handle)
|
||||
{
|
||||
if ((handle < WSF_EFS_MAX_FILES) &&
|
||||
(wsfEfsFileTbl[handle].maxSize != WSF_EFS_INVALID_SIZE))
|
||||
{
|
||||
return &wsfEfsFileTbl[handle];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn wsfEfsFileOverlap
|
||||
*
|
||||
* \brief Checks if the given offset and size overlaps with a given file.
|
||||
*
|
||||
* \param handle The handle of the file to check against
|
||||
* \param media The physical medium the new file will be in
|
||||
* \param address The starting address in the physical medium
|
||||
* \param size The max size of the file
|
||||
*
|
||||
* \return TRUE if overlap, else FALSE.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static bool_t wsfEfsFileOverlap(wsfEfsHandle_t handle, uint8_t media, uint32_t address, uint32_t size)
|
||||
{
|
||||
if (wsfEfsMediaValid(media))
|
||||
{
|
||||
/* Check if the table entry is in use and the physical media are the same */
|
||||
if (size && (wsfEfsFileTbl[handle].maxSize) &&
|
||||
(wsfEfsFileTbl[handle].maxSize != WSF_EFS_INVALID_SIZE) &&
|
||||
(wsfEfsFileTbl[handle].media == media))
|
||||
{
|
||||
/* Calculate the top and bottom addresses of the files */
|
||||
uint32_t top1 = wsfEfsFileTbl[handle].address;
|
||||
uint32_t bottom1 = wsfEfsFileTbl[handle].address + wsfEfsFileTbl[handle].maxSize - 1;
|
||||
uint32_t top2 = address;
|
||||
uint32_t bottom2 = address + size - 1;
|
||||
|
||||
/* Check for overlap */
|
||||
if ((top2 >= top1) && (top2 <= bottom1))
|
||||
return TRUE;
|
||||
|
||||
if ((bottom2 >= top1) && (bottom2 <= bottom1))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn wsfEfsFindAvailableOffset
|
||||
*
|
||||
* \brief Finds the offset of an unused area of the physical media big enough for a file
|
||||
* of the given size.
|
||||
*
|
||||
* \param media The physical medium
|
||||
* \param size The max size of the file
|
||||
*
|
||||
* \return The next available offset.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint32_t wsfEfsFindAvailableOffset(uint8_t media, uint32_t size)
|
||||
{
|
||||
if (wsfEfsMediaValid(media))
|
||||
{
|
||||
int8_t i;
|
||||
uint32_t address = wsfEfsMediaTbl[media]->startAddress;
|
||||
|
||||
for (i=0; i<WSF_EFS_MAX_FILES; i++)
|
||||
{
|
||||
if (wsfEfsFileOverlap(i, media, address, size))
|
||||
{
|
||||
/* The offset overlaps another file. Move the offset to the end of the overlapping */
|
||||
/* file and retest. */
|
||||
address = wsfEfsFileTbl[i].address + wsfEfsFileTbl[i].maxSize;
|
||||
address += address % wsfEfsMediaTbl[media]->pageSize;
|
||||
i = -1;
|
||||
|
||||
if (address + size > wsfEfsMediaTbl[media]->endAddress)
|
||||
return WSF_EFS_INVALID_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
return WSF_EFS_INVALID_OFFSET;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsInit
|
||||
*
|
||||
* \brief Initialize the embedded file system.
|
||||
*
|
||||
* \return none.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfEfsInit(void)
|
||||
{
|
||||
int8_t i;
|
||||
|
||||
/* Clear control structures */
|
||||
memset((void *) wsfEfsMediaTbl, 0, sizeof(wsfEfsMediaTbl));
|
||||
|
||||
/* Set maxSize to invalid indicating file is unused */
|
||||
for (i=0; i<WSF_EFS_MAX_FILES; i++)
|
||||
{
|
||||
wsfEfsFileTbl[i].maxSize = WSF_EFS_INVALID_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsAddFile
|
||||
*
|
||||
* \brief Create a file in the embedded file system.
|
||||
*
|
||||
* \param maxSize Number of bytes to reserve for the file.
|
||||
* \param media Identifier of the media where the file is stored.
|
||||
* \param pAttr Attributes of the file
|
||||
* \param offset Offset address of the file in the memory space.
|
||||
*
|
||||
* \return File Handle, or WSF_EFS_INVALID_HANDLE if the operation failed.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
wsfEfsHandle_t WsfEfsAddFile(uint32_t maxSize, uint8_t media, wsfEsfAttributes_t *pAttr, uint32_t offset)
|
||||
{
|
||||
wsfEfsHandle_t handle;
|
||||
uint32_t address = offset;
|
||||
wsfEfsControl_t *pFile = NULL;
|
||||
|
||||
if (wsfEfsMediaValid(media))
|
||||
{
|
||||
/* Find an available slot in the file table (wsfEfsFileTbl) */
|
||||
for (handle = 0; handle < WSF_EFS_MAX_FILES; handle++)
|
||||
{
|
||||
if (wsfEfsFileTbl[handle].maxSize == WSF_EFS_INVALID_SIZE)
|
||||
{
|
||||
pFile = &wsfEfsFileTbl[handle];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pFile)
|
||||
{
|
||||
if (address == WSF_EFS_FILE_OFFSET_ANY)
|
||||
{
|
||||
address = wsfEfsFindAvailableOffset(media, maxSize);
|
||||
|
||||
if (address == WSF_EFS_INVALID_OFFSET)
|
||||
return WSF_EFS_INVALID_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
/* The user specifies a zero based offset when adding a file */
|
||||
/* This offset must be incremented by the media StartAddress */
|
||||
/* to become the file's address in the wsfEfsMediaTbl. */
|
||||
address += wsfEfsMediaTbl[media]->startAddress;
|
||||
|
||||
/* Increment the address to a page boundry */
|
||||
if (wsfEfsMediaTbl[media]->pageSize)
|
||||
{
|
||||
address += address % wsfEfsMediaTbl[media]->pageSize;
|
||||
}
|
||||
|
||||
/* Verify the given offset doesn't overlap another file */
|
||||
for (i=0; i<WSF_EFS_MAX_FILES; i++)
|
||||
{
|
||||
if (wsfEfsFileOverlap(i, media, address, maxSize) == TRUE)
|
||||
return WSF_EFS_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in the file control structure */
|
||||
pFile->size = 0;
|
||||
pFile->media = media;
|
||||
pFile->address = address;
|
||||
memcpy(&pFile->attributes, pAttr, sizeof(wsfEsfAttributes_t));
|
||||
|
||||
/* Set the maxSize, and increment the maxSize such that it */
|
||||
/* occupies a full page in the physical medium */
|
||||
pFile->maxSize = maxSize;
|
||||
if (wsfEfsMediaTbl[media]->pageSize)
|
||||
{
|
||||
pFile->maxSize += maxSize % wsfEfsMediaTbl[media]->pageSize;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
return WSF_EFS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsRemoveFile
|
||||
*
|
||||
* \brief Deletes a file in the embedded file system.
|
||||
*
|
||||
* \param handle Handle identifying the file.
|
||||
*
|
||||
* \return WSF_EFS_SUCCESS or WSF_EFS_FAILURE.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t WsfEfsRemoveFile(wsfEfsHandle_t handle)
|
||||
{
|
||||
if (handle < WSF_EFS_MAX_FILES)
|
||||
{
|
||||
wsfEfsFileTbl[handle].maxSize = WSF_EFS_INVALID_SIZE;
|
||||
return WSF_EFS_SUCCESS;
|
||||
}
|
||||
|
||||
return WSF_EFS_FAILURE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsErase
|
||||
*
|
||||
* \brief Clears the contents of a file without deleting the file.
|
||||
*
|
||||
* \param handle Handle identifying the file.
|
||||
*
|
||||
* \return WSF_EFS_SUCCESS or WSF_EFS_FAILURE.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t WsfEfsErase(wsfEfsHandle_t handle)
|
||||
{
|
||||
uint8_t status = WSF_EFS_FAILURE;
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if ((pFile = WsfEfsGetFileByHandle(handle)) != NULL)
|
||||
{
|
||||
if (pFile->attributes.permissions & (WSF_EFS_REMOTE_ERASE_PERMITTED | WSF_EFS_LOCAL_ERASE_PERMITTED))
|
||||
{
|
||||
uint8_t media = pFile->media;
|
||||
|
||||
if (wsfEfsMediaTbl[media]->erase)
|
||||
{
|
||||
uint32_t address = pFile->address;
|
||||
uint32_t size = pFile->maxSize;
|
||||
|
||||
status = wsfEfsMediaTbl[media]->erase(address, size);
|
||||
pFile->size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsGetAttributes
|
||||
*
|
||||
* \brief Gets the attributes of a file.
|
||||
*
|
||||
* \param handle Handle identifying the file.
|
||||
* \param pAttr Pointer to memory to store the attributes.
|
||||
*
|
||||
* \return WSF_EFS_SUCCESS or WSF_EFS_FAILURE.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t WsfEfsGetAttributes(wsfEfsHandle_t handle, wsfEsfAttributes_t *pAttr)
|
||||
{
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if (((pFile = WsfEfsGetFileByHandle(handle)) != NULL) && pAttr)
|
||||
{
|
||||
memcpy(pAttr, &pFile->attributes, sizeof(wsfEsfAttributes_t));
|
||||
return WSF_EFS_SUCCESS;
|
||||
}
|
||||
|
||||
return WSF_EFS_FAILURE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsSetAttributes
|
||||
*
|
||||
* \brief Updates the attributes of a file.
|
||||
*
|
||||
* \param handle Handle identifying the file.
|
||||
* \param pAttr Pointer to memory to with the new attributes.
|
||||
*
|
||||
* \return WSF_EFS_SUCCESS or WSF_EFS_FAILURE.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t WsfEfsSetAttributes(wsfEfsHandle_t handle, wsfEsfAttributes_t *pAttr)
|
||||
{
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if (((pFile = WsfEfsGetFileByHandle(handle)) != NULL) && pAttr)
|
||||
{
|
||||
memcpy(&pFile->attributes, pAttr, sizeof(wsfEsfAttributes_t));
|
||||
return WSF_EFS_SUCCESS;
|
||||
}
|
||||
|
||||
return WSF_EFS_FAILURE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsGet
|
||||
*
|
||||
* \brief Copies data from a file.
|
||||
*
|
||||
* \param handle Handle identifying the file.
|
||||
* \param offset Offset into the file to begin copying from.
|
||||
* \param pBuffer Location to copy the data to.
|
||||
* \param len Number of bytes to copy into pBuffer.
|
||||
*
|
||||
* \return The number of bytes read from the file.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint16_t WsfEfsGet(wsfEfsHandle_t handle, uint32_t offset, uint8_t *pBuffer, uint16_t len)
|
||||
{
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if (((pFile = WsfEfsGetFileByHandle(handle)) != NULL) && pBuffer)
|
||||
{
|
||||
if (pFile->attributes.permissions & (WSF_EFS_REMOTE_GET_PERMITTED | WSF_EFS_LOCAL_GET_PERMITTED))
|
||||
{
|
||||
uint8_t media = pFile->media;
|
||||
|
||||
if (wsfEfsMediaTbl[media]->read)
|
||||
{
|
||||
if (pFile->attributes.type == WSF_EFS_FILE_TYPE_STREAM)
|
||||
{
|
||||
wsfEfsMediaTbl[media]->read(pBuffer, 0, len);
|
||||
return len;
|
||||
}
|
||||
else if (offset < pFile->size)
|
||||
{
|
||||
uint32_t address = pFile->address + offset;
|
||||
|
||||
if (offset + len > pFile->size)
|
||||
{
|
||||
len = (uint16_t) (pFile->size - offset);
|
||||
}
|
||||
|
||||
wsfEfsMediaTbl[media]->read(pBuffer, address, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsPut
|
||||
*
|
||||
* \brief Writes data to a file.
|
||||
*
|
||||
* \param handle Handle identifying the file.
|
||||
* \param offset Offset into the file to begin writing to.
|
||||
* \param pBuffer Data to write to the file.
|
||||
* \param len Number of bytes to write to the file.
|
||||
*
|
||||
* \return The number of bytes written to the file
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint16_t WsfEfsPut(wsfEfsHandle_t handle, uint32_t offset, const uint8_t *pBuffer, uint16_t len)
|
||||
{
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if (((pFile = WsfEfsGetFileByHandle(handle)) != NULL) && pBuffer)
|
||||
{
|
||||
if (pFile->attributes.permissions & (WSF_EFS_REMOTE_PUT_PERMITTED | WSF_EFS_LOCAL_PUT_PERMITTED))
|
||||
{
|
||||
uint8_t media = pFile->media;
|
||||
|
||||
if (wsfEfsMediaTbl[media]->write)
|
||||
{
|
||||
if (pFile->attributes.type == WSF_EFS_FILE_TYPE_STREAM)
|
||||
{
|
||||
wsfEfsMediaTbl[media]->write(pBuffer, 0, len);
|
||||
return len;
|
||||
}
|
||||
else if (offset < pFile->maxSize)
|
||||
{
|
||||
uint32_t address = pFile->address + offset;
|
||||
|
||||
if (offset + len > pFile->maxSize)
|
||||
{
|
||||
len = (uint16_t) (pFile->maxSize - offset);
|
||||
}
|
||||
|
||||
wsfEfsMediaTbl[media]->write(pBuffer, address, len);
|
||||
|
||||
/* If writing to the end of the file, update the file size */
|
||||
if (offset + len > pFile->size)
|
||||
{
|
||||
pFile->size = offset + len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsGetFileName
|
||||
*
|
||||
* \brief Get the name of a file.
|
||||
*
|
||||
* \param handle File Handle.
|
||||
*
|
||||
* \return Filename string of a file.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
char *WsfEfsGetFileName(wsfEfsHandle_t handle)
|
||||
{
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if (((pFile = WsfEfsGetFileByHandle(handle)) != NULL))
|
||||
{
|
||||
return pFile->attributes.name;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsGetFileVersion
|
||||
*
|
||||
* \brief Get the version of a file.
|
||||
*
|
||||
* \param handle File Handle.
|
||||
*
|
||||
* \return Version string of a file.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
char *WsfEfsGetFileVersion(wsfEfsHandle_t handle)
|
||||
{
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if (((pFile = WsfEfsGetFileByHandle(handle)) != NULL))
|
||||
{
|
||||
return pFile->attributes.version;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsGetFileMaxSize
|
||||
*
|
||||
* \brief Get the number of bytes of memory reserved for use by a file.
|
||||
*
|
||||
* \param handle File Handle.
|
||||
*
|
||||
* \return Max size of the file.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t WsfEfsGetFileMaxSize(wsfEfsHandle_t handle)
|
||||
{
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if (((pFile = WsfEfsGetFileByHandle(handle)) != NULL))
|
||||
{
|
||||
return pFile->maxSize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsGetFileSize
|
||||
*
|
||||
* \brief Get the size of a file.
|
||||
*
|
||||
* \param handle File Handle.
|
||||
*
|
||||
* \return Size of the file.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t WsfEfsGetFileSize(wsfEfsHandle_t handle)
|
||||
{
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if (((pFile = WsfEfsGetFileByHandle(handle)) != NULL))
|
||||
{
|
||||
return pFile->size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsGetFileType
|
||||
*
|
||||
* \brief Get the type of a file.
|
||||
*
|
||||
* \param handle File Handle.
|
||||
*
|
||||
* \return Type of file (bulk or stream).
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t WsfEfsGetFileType(wsfEfsHandle_t handle)
|
||||
{
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if (((pFile = WsfEfsGetFileByHandle(handle)) != NULL))
|
||||
{
|
||||
return pFile->attributes.type;
|
||||
}
|
||||
|
||||
return WSF_EFS_FILE_TYPE_BULK;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsGetFilePermissions
|
||||
*
|
||||
* \brief Get the permissions of a file.
|
||||
*
|
||||
* \param handle File Handle.
|
||||
*
|
||||
* \return Permissions of the file.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint16_t WsfEfsGetFilePermissions(wsfEfsHandle_t handle)
|
||||
{
|
||||
wsfEfsControl_t *pFile;
|
||||
|
||||
if (((pFile = WsfEfsGetFileByHandle(handle)) != NULL))
|
||||
{
|
||||
return pFile->attributes.permissions;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsMediaSpecificCommand
|
||||
*
|
||||
* \brief Execute a media specific command on a file.
|
||||
*
|
||||
* \param handle File Handle.
|
||||
* \param cmd Media specific command identifier.
|
||||
* \param param Ccommand specific parameter.
|
||||
*
|
||||
* \return Status of the operation.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t WsfEfsMediaSpecificCommand(wsfEfsHandle_t handle, uint8_t cmd, uint32_t param)
|
||||
{
|
||||
if (WsfEfsGetFileByHandle(handle))
|
||||
{
|
||||
uint8_t media = wsfEfsFileTbl[handle].media;
|
||||
|
||||
/* Call the command handler if it exists */
|
||||
if (wsfEfsMediaTbl[media]->handleCmd)
|
||||
{
|
||||
return wsfEfsMediaTbl[media]->handleCmd(cmd, param);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfEfsRegisterMedia
|
||||
*
|
||||
* \brief Registers a File Storage Medium with the Embedded File System.
|
||||
*
|
||||
* \param pMedia Pointer to the media control structure.
|
||||
* \param mediaID Identifier of the media.
|
||||
*
|
||||
* \return WSF_EFS_SUCCESS or WSF_EFS_FAILURE.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t WsfEfsRegisterMedia(const wsfEfsMedia_t *pMediaCtrl, uint8_t mediaID)
|
||||
{
|
||||
if (mediaID < WSF_EFS_MAX_MEDIA && pMediaCtrl)
|
||||
{
|
||||
wsfEfsMediaTbl[mediaID] = pMediaCtrl;
|
||||
|
||||
/* Call the initialization function for the media */
|
||||
if (pMediaCtrl->init)
|
||||
{
|
||||
pMediaCtrl->init();
|
||||
}
|
||||
|
||||
return WSF_EFS_SUCCESS;
|
||||
}
|
||||
|
||||
return WSF_EFS_FAILURE;
|
||||
}
|
||||
Vendored
+123
@@ -0,0 +1,123 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_intrinsic.h
|
||||
*
|
||||
* \brief CPU core intrinsic functions.
|
||||
*
|
||||
* $Date: 2013-05-22 15:52:25 -0700 (Wed, 22 May 2013) $
|
||||
* $Revision: 660 $
|
||||
*
|
||||
* Copyright (c) 2009 Wicentric, Inc., all rights reserved.
|
||||
* Wicentric confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact Wicentric, Inc. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef WSF_INTRINSIC_H
|
||||
#define WSF_INTRINSIC_H
|
||||
|
||||
#ifdef __arm__
|
||||
#include "device_cm3.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \def WsfLeadingMsbZeros
|
||||
*
|
||||
* \brief Count leading MSB zero.
|
||||
*
|
||||
* \param value Value to count leading zeros.
|
||||
*
|
||||
* \return Number of leading zeros.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifdef __arm__
|
||||
#define WsfClzMsb(v) __CLZ(v)
|
||||
#else
|
||||
static inline uint8_t WsfClzMsb(uint32_t value)
|
||||
{
|
||||
/* Stub for platform specific implementation. */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \def WsfLeadingMsbOnes
|
||||
*
|
||||
* \brief Count leading MSB ones.
|
||||
*
|
||||
* \param value Value to count leading ones.
|
||||
*
|
||||
* \return Number of leading ones.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifdef __arm__
|
||||
#define WsfCloMsb(v) __CLZ(~v)
|
||||
#else
|
||||
static inline uint8_t WsfCloMsb(uint32_t value)
|
||||
{
|
||||
return WsfClzMsb(~value);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \def WsfLeadingLsbZeros
|
||||
*
|
||||
* \brief Count leading LSB zero.
|
||||
*
|
||||
* \param value Value to count leading zeros.
|
||||
*
|
||||
* \return Number of leading zeros.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifdef __arm__
|
||||
#define WsfClzLsb(v) __CLZ(__REV(v))
|
||||
#else
|
||||
static inline uint8_t WsfClzLsb(uint32_t value)
|
||||
{
|
||||
/* Stub for platform specific implementation. */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \def WsfLeadingLsbOnes
|
||||
*
|
||||
* \brief Count leading LSB ones.
|
||||
*
|
||||
* \param value Value to count leading ones.
|
||||
*
|
||||
* \return Number of leading ones.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifdef __arm__
|
||||
#define WsfCloLsb(v) __CLZ(__REV(~v))
|
||||
#else
|
||||
static inline uint8_t WsfCloLsb(uint32_t value)
|
||||
{
|
||||
return WsfClzLsb(~value);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* WSF_INTRINSIC_H */
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_math.c
|
||||
*
|
||||
* \brief Common math utilities generic implementation file.
|
||||
*
|
||||
* $Date: 2014-09-16 13:19:18 -0700 (Tue, 16 Sep 2014) $
|
||||
* $Revision: 1816 $
|
||||
*
|
||||
* Copyright (c) 2013 Wicentric, Inc., all rights reserved.
|
||||
* Wicentric confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact Wicentric, Inc. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "wsf_math.h"
|
||||
#include <string.h>
|
||||
|
||||
/**************************************************************************************************
|
||||
Global Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
static uint32_t wsfRngW = 88675123;
|
||||
static uint32_t wsfRngX = 123456789;
|
||||
static uint32_t wsfRngY = 362436069;
|
||||
static uint32_t wsfRngZ = 521288629;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfMathInit
|
||||
*
|
||||
* \brief Initialize math routines.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfMathInit(void)
|
||||
{
|
||||
/* Seed PRNG. */
|
||||
wsfRngW = 88675123;
|
||||
wsfRngX = 123456789;
|
||||
wsfRngY = 362436069;
|
||||
wsfRngZ = 521288629;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfRandNum
|
||||
*
|
||||
* \brief Generate random number.
|
||||
*
|
||||
* \return 32-bit random number.
|
||||
*
|
||||
* This software implementation uses a xorshift random number generator.
|
||||
* George Marsaglia (2003), "Xorshift RNGs", Journal of Statistical Software
|
||||
*
|
||||
* \note This routine is not a cryptographic grade random number generator.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t WsfRandNum(void)
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
t = wsfRngX ^ (wsfRngX << 11);
|
||||
wsfRngX = wsfRngY;
|
||||
wsfRngY = wsfRngZ;
|
||||
wsfRngZ = wsfRngW;
|
||||
wsfRngW = wsfRngW ^ (wsfRngW >> 19) ^ (t ^ (t >> 8));
|
||||
return wsfRngW;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfAesEcb
|
||||
*
|
||||
* \brief Calculate AES ECB.
|
||||
*
|
||||
* \param pKey Encryption key.
|
||||
* \param pOut Output data.
|
||||
* \param pIn Input data.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfAesEcb(const uint8_t *pKey, uint8_t *pOut, const uint8_t *pIn)
|
||||
{
|
||||
/* TODO implementation required. */
|
||||
const unsigned int KEY_LEN = 16;
|
||||
memcpy(pOut, pIn, KEY_LEN);
|
||||
}
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_msg.c
|
||||
*
|
||||
* \brief Message passing service.
|
||||
*
|
||||
* $Date: 2017-03-10 14:08:37 -0600 (Fri, 10 Mar 2017) $
|
||||
* $Revision: 11501 $
|
||||
*
|
||||
* Copyright (c) 2009-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_msg.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_buf.h"
|
||||
#include "wsf_queue.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "wsf_os.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/* Internal message buf structure */
|
||||
typedef struct wsfMsg_tag
|
||||
{
|
||||
struct wsfMsg_tag *pNext;
|
||||
wsfHandlerId_t handlerId;
|
||||
} wsfMsg_t;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfMsgDataAlloc
|
||||
*
|
||||
* \brief Allocate a data message buffer to be sent with WsfMsgSend().
|
||||
*
|
||||
* \param len Message length in bytes.
|
||||
* \param tailroom Tailroom length in bytes.
|
||||
*
|
||||
* \return Pointer to data message buffer or NULL if allocation failed.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void *WsfMsgDataAlloc(uint16_t len, uint8_t tailroom)
|
||||
{
|
||||
return WsfMsgAlloc(len + tailroom);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfMsgAlloc
|
||||
*
|
||||
* \brief Allocate a message buffer to be sent with WsfMsgSend().
|
||||
*
|
||||
* \param len Message length in bytes.
|
||||
*
|
||||
* \return Pointer to message buffer or NULL if allocation failed.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void *WsfMsgAlloc(uint16_t len)
|
||||
{
|
||||
wsfMsg_t *pMsg;
|
||||
|
||||
pMsg = WsfBufAlloc(len + sizeof(wsfMsg_t));
|
||||
|
||||
/* hide header */
|
||||
if (pMsg != NULL)
|
||||
{
|
||||
pMsg++;
|
||||
}
|
||||
|
||||
return pMsg;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfMsgFree
|
||||
*
|
||||
* \brief Free a message buffer allocated with WsfMsgAlloc().
|
||||
*
|
||||
* \param pMsg Pointer to message buffer.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfMsgFree(void *pMsg)
|
||||
{
|
||||
WsfBufFree(((wsfMsg_t *) pMsg) - 1);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfMsgSend
|
||||
*
|
||||
* \brief Send a message to an event handler.
|
||||
*
|
||||
* \param handlerId Event handler ID.
|
||||
* \param pMsg Pointer to message buffer.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfMsgSend(wsfHandlerId_t handlerId, void *pMsg)
|
||||
{
|
||||
WSF_TRACE_MSG1("WsfMsgSend handlerId:%u", handlerId);
|
||||
|
||||
/* get queue for this handler and enqueue message */
|
||||
WsfMsgEnq(WsfTaskMsgQueue(handlerId), handlerId, pMsg);
|
||||
|
||||
/* set task for this handler as ready to run */
|
||||
WsfTaskSetReady(handlerId, WSF_MSG_QUEUE_EVENT);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfMsgEnq
|
||||
*
|
||||
* \brief Enqueue a message.
|
||||
*
|
||||
* \param pQueue Pointer to queue.
|
||||
* \param handerId Set message handler ID to this value.
|
||||
* \param pElem Pointer to message buffer.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfMsgEnq(wsfQueue_t *pQueue, wsfHandlerId_t handlerId, void *pMsg)
|
||||
{
|
||||
wsfMsg_t *p;
|
||||
|
||||
WSF_ASSERT(pMsg != NULL);
|
||||
|
||||
/* get message header */
|
||||
p = ((wsfMsg_t *) pMsg) - 1;
|
||||
|
||||
/* set handler ID */
|
||||
p->handlerId = handlerId;
|
||||
|
||||
WsfQueueEnq(pQueue, p);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfMsgDeq
|
||||
*
|
||||
* \brief Dequeue a message.
|
||||
*
|
||||
* \param pQueue Pointer to queue.
|
||||
* \param pHandlerId Handler ID of returned message; this is a return parameter.
|
||||
*
|
||||
* \return Pointer to message that has been dequeued or NULL if queue is empty.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void *WsfMsgDeq(wsfQueue_t *pQueue, wsfHandlerId_t *pHandlerId)
|
||||
{
|
||||
wsfMsg_t *pMsg;
|
||||
|
||||
if ((pMsg = WsfQueueDeq(pQueue)) != NULL)
|
||||
{
|
||||
*pHandlerId = pMsg->handlerId;
|
||||
|
||||
/* hide header */
|
||||
pMsg++;
|
||||
}
|
||||
|
||||
return pMsg;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfMsgPeek
|
||||
*
|
||||
* \brief Get the next message without removing it from the queue.
|
||||
*
|
||||
* \param pQueue Pointer to queue.
|
||||
* \param pHandlerId Handler ID of returned message; this is a return parameter.
|
||||
*
|
||||
* \return Pointer to the next message on the queue or NULL if queue is empty.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void *WsfMsgPeek(wsfQueue_t *pQueue, wsfHandlerId_t *pHandlerId)
|
||||
{
|
||||
wsfMsg_t *pMsg = pQueue->pHead;
|
||||
|
||||
if (pMsg != NULL)
|
||||
{
|
||||
*pHandlerId = pMsg->handlerId;
|
||||
|
||||
/* hide header */
|
||||
pMsg++;
|
||||
}
|
||||
|
||||
return pMsg;
|
||||
}
|
||||
+426
@@ -0,0 +1,426 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_os.c
|
||||
*
|
||||
* \brief Software foundation OS main module.
|
||||
*
|
||||
* $Date: 2015-09-09 09:35:06 -0700 (Wed, 09 Sep 2015) $
|
||||
* $Revision: 3809 $
|
||||
*
|
||||
* Copyright (c) 2009 Wicentric, Inc., all rights reserved.
|
||||
* Wicentric confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact Wicentric, Inc. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#include <intrinsics.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_os.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "wsf_timer.h"
|
||||
#include "wsf_queue.h"
|
||||
#include "wsf_buf.h"
|
||||
#include "wsf_msg.h"
|
||||
#include "wsf_cs.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Compile time assert checks
|
||||
**************************************************************************************************/
|
||||
|
||||
WSF_CT_ASSERT(sizeof(uint8_t) == 1);
|
||||
WSF_CT_ASSERT(sizeof(uint16_t) == 2);
|
||||
WSF_CT_ASSERT(sizeof(uint32_t) == 4);
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/* maximum number of event handlers per task */
|
||||
#ifndef WSF_MAX_HANDLERS
|
||||
#define WSF_MAX_HANDLERS 9
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/* Task structure */
|
||||
typedef struct
|
||||
{
|
||||
wsfEventHandler_t handler[WSF_MAX_HANDLERS];
|
||||
wsfEventMask_t handlerEventMask[WSF_MAX_HANDLERS];
|
||||
wsfQueue_t msgQueue;
|
||||
wsfTaskEvent_t taskEventMask;
|
||||
uint8_t numHandler;
|
||||
} wsfOsTask_t;
|
||||
|
||||
/* OS structure */
|
||||
typedef struct
|
||||
{
|
||||
wsfOsTask_t task;
|
||||
} wsfOs_t;
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
uint8_t csNesting = 0;
|
||||
|
||||
wsfOs_t wsfOs;
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "event_groups.h"
|
||||
EventGroupHandle_t xRadioTaskEventObject = NULL;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfCsEnter
|
||||
*
|
||||
* \brief Enter a critical section.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfCsEnter(void)
|
||||
{
|
||||
if (csNesting == 0)
|
||||
{
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
__disable_interrupt();
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
__asm volatile ("cpsid i");
|
||||
#endif
|
||||
#ifdef __CC_ARM
|
||||
__disable_irq();
|
||||
#endif
|
||||
|
||||
}
|
||||
csNesting++;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfCsEnter
|
||||
*
|
||||
* \brief Enter a critical section.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfCsExit(void)
|
||||
{
|
||||
WSF_ASSERT(csNesting != 0);
|
||||
|
||||
csNesting--;
|
||||
if (csNesting == 0)
|
||||
{
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
__enable_interrupt();
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
__asm volatile ("cpsie i");
|
||||
#endif
|
||||
#ifdef __CC_ARM
|
||||
__enable_irq();
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTaskLock
|
||||
*
|
||||
* \brief Lock task scheduling.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfTaskLock(void)
|
||||
{
|
||||
WsfCsEnter();
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTaskUnlock
|
||||
*
|
||||
* \brief Unock task scheduling.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfTaskUnlock(void)
|
||||
{
|
||||
WsfCsExit();
|
||||
}
|
||||
|
||||
void WsfSetOsSpecificEvent(void)
|
||||
{
|
||||
if(xRadioTaskEventObject != NULL)
|
||||
{
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken, xResult;
|
||||
|
||||
if(xPortIsInsideInterrupt() == pdTRUE) {
|
||||
|
||||
//
|
||||
// Send an event to the main radio task
|
||||
//
|
||||
xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
xResult = xEventGroupSetBitsFromISR(xRadioTaskEventObject, 1,
|
||||
&xHigherPriorityTaskWoken);
|
||||
|
||||
//
|
||||
// If the radio task is higher-priority than the context we're currently
|
||||
// running from, we should yield now and run the radio task.
|
||||
//
|
||||
if ( xResult != pdFAIL )
|
||||
{
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
xResult = xEventGroupSetBits(xRadioTaskEventObject, 1);
|
||||
//
|
||||
// If the radio task is higher priority than the context we're currently
|
||||
// running from, we should yield now and run the radio task.
|
||||
//
|
||||
if ( xResult != pdFAIL )
|
||||
{
|
||||
portYIELD();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfSetEvent
|
||||
*
|
||||
* \brief Set an event for an event handler.
|
||||
*
|
||||
* \param handlerId Handler ID.
|
||||
* \param event Event or events to set.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfSetEvent(wsfHandlerId_t handlerId, wsfEventMask_t event)
|
||||
{
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
WSF_ASSERT(WSF_HANDLER_FROM_ID(handlerId) < WSF_MAX_HANDLERS);
|
||||
|
||||
WSF_TRACE_INFO2("WsfSetEvent handlerId:%u event:%u", handlerId, event);
|
||||
|
||||
WSF_CS_ENTER(cs);
|
||||
wsfOs.task.handlerEventMask[WSF_HANDLER_FROM_ID(handlerId)] |= event;
|
||||
wsfOs.task.taskEventMask |= WSF_HANDLER_EVENT;
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
/* set event in OS */
|
||||
|
||||
WsfSetOsSpecificEvent();
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTaskSetReady
|
||||
*
|
||||
* \brief Set the task used by the given handler as ready to run.
|
||||
*
|
||||
* \param handlerId Event handler ID.
|
||||
* \param event Task event mask.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfTaskSetReady(wsfHandlerId_t handlerId, wsfTaskEvent_t event)
|
||||
{
|
||||
/* Unused parameter */
|
||||
(void)handlerId;
|
||||
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
WSF_CS_ENTER(cs);
|
||||
wsfOs.task.taskEventMask |= event;
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
/* set event in OS */
|
||||
|
||||
WsfSetOsSpecificEvent();
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTaskMsgQueue
|
||||
*
|
||||
* \brief Return the message queue used by the given handler.
|
||||
*
|
||||
* \param handlerId Event handler ID.
|
||||
*
|
||||
* \return Task message queue.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
wsfQueue_t *WsfTaskMsgQueue(wsfHandlerId_t handlerId)
|
||||
{
|
||||
/* Unused parameter */
|
||||
(void)handlerId;
|
||||
|
||||
return &(wsfOs.task.msgQueue);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfOsSetNextHandler
|
||||
*
|
||||
* \brief Set the next WSF handler function in the WSF OS handler array. This function
|
||||
* should only be called as part of the stack initialization procedure.
|
||||
*
|
||||
* \param handler WSF handler function.
|
||||
*
|
||||
* \return WSF handler ID for this handler.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
wsfHandlerId_t WsfOsSetNextHandler(wsfEventHandler_t handler)
|
||||
{
|
||||
wsfHandlerId_t handlerId = wsfOs.task.numHandler++;
|
||||
|
||||
WSF_ASSERT(handlerId < WSF_MAX_HANDLERS);
|
||||
|
||||
wsfOs.task.handler[handlerId] = handler;
|
||||
|
||||
return handlerId;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn wsfOsReadyToSleep
|
||||
*
|
||||
* \brief Check if WSF is ready to sleep. This function should be called when interrupts
|
||||
* are disabled.
|
||||
*
|
||||
* \param None.
|
||||
*
|
||||
* \return Return TRUE if there are no pending WSF task events set, FALSE otherwise.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
bool_t wsfOsReadyToSleep(void)
|
||||
{
|
||||
return (wsfOs.task.taskEventMask == 0);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize OS control structure.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfOsInit(void)
|
||||
{
|
||||
memset(&wsfOs, 0, sizeof(wsfOs));
|
||||
|
||||
if( xRadioTaskEventObject == NULL)
|
||||
{
|
||||
xRadioTaskEventObject = xEventGroupCreate();
|
||||
|
||||
WSF_ASSERT(xRadioTaskEventObject != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn wsfOsDispatcher
|
||||
*
|
||||
* \brief Event dispatched. Designed to be called repeatedly from infinite loop.
|
||||
*
|
||||
* \param None.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void wsfOsDispatcher(void)
|
||||
{
|
||||
wsfOsTask_t *pTask;
|
||||
void *pMsg;
|
||||
wsfTimer_t *pTimer;
|
||||
wsfEventMask_t eventMask;
|
||||
wsfTaskEvent_t taskEventMask;
|
||||
wsfHandlerId_t handlerId;
|
||||
uint8_t i;
|
||||
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
pTask = &wsfOs.task;
|
||||
|
||||
WsfTimerUpdateTicks();
|
||||
|
||||
while (pTask->taskEventMask)
|
||||
{
|
||||
/* get and then clear task event mask */
|
||||
WSF_CS_ENTER(cs);
|
||||
taskEventMask = pTask->taskEventMask;
|
||||
pTask->taskEventMask = 0;
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
if (taskEventMask & WSF_MSG_QUEUE_EVENT)
|
||||
{
|
||||
/* handle msg queue */
|
||||
while ((pMsg = WsfMsgDeq(&pTask->msgQueue, &handlerId)) != NULL)
|
||||
{
|
||||
WSF_ASSERT(handlerId < WSF_MAX_HANDLERS);
|
||||
(*pTask->handler[handlerId])(0, pMsg);
|
||||
WsfMsgFree(pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
if (taskEventMask & WSF_TIMER_EVENT)
|
||||
{
|
||||
/* service timers */
|
||||
while ((pTimer = WsfTimerServiceExpired(0)) != NULL)
|
||||
{
|
||||
WSF_ASSERT(pTimer->handlerId < WSF_MAX_HANDLERS);
|
||||
(*pTask->handler[pTimer->handlerId])(0, &pTimer->msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (taskEventMask & WSF_HANDLER_EVENT)
|
||||
{
|
||||
/* service handlers */
|
||||
for (i = 0; i < WSF_MAX_HANDLERS; i++)
|
||||
{
|
||||
if ((pTask->handlerEventMask[i] != 0) && (pTask->handler[i] != NULL))
|
||||
{
|
||||
WSF_CS_ENTER(cs);
|
||||
eventMask = pTask->handlerEventMask[i];
|
||||
pTask->handlerEventMask[i] = 0;
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
(*pTask->handler[i])(eventMask, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xEventGroupWaitBits(xRadioTaskEventObject, 1, pdTRUE,
|
||||
pdFALSE, portMAX_DELAY);
|
||||
}
|
||||
|
||||
Vendored
+118
@@ -0,0 +1,118 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_os_int.h
|
||||
*
|
||||
* \brief Software foundation OS platform-specific interface file.
|
||||
*
|
||||
* $Date: 2012-10-01 13:53:07 -0700 (Mon, 01 Oct 2012) $
|
||||
* $Revision: 357 $
|
||||
*
|
||||
* Copyright (c) 2009 Wicentric, Inc., all rights reserved.
|
||||
* Wicentric confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact Wicentric, Inc. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef WSF_OS_INT_H
|
||||
#define WSF_OS_INT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/* Task events */
|
||||
#define WSF_MSG_QUEUE_EVENT 0x01 /* Message queued for event handler */
|
||||
#define WSF_TIMER_EVENT 0x02 /* Timer expired for event handler */
|
||||
#define WSF_HANDLER_EVENT 0x04 /* Event set for event handler */
|
||||
|
||||
/* Derive task from handler ID */
|
||||
#define WSF_TASK_FROM_ID(handlerID) (((handlerID) >> 4) & 0x0F)
|
||||
|
||||
/* Derive handler from handler ID */
|
||||
#define WSF_HANDLER_FROM_ID(handlerID) ((handlerID) & 0x0F)
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/* Event handler ID data type */
|
||||
typedef uint8_t wsfHandlerId_t;
|
||||
|
||||
/* Event handler event mask data type */
|
||||
typedef uint8_t wsfEventMask_t;
|
||||
|
||||
/* Task ID data type */
|
||||
typedef wsfHandlerId_t wsfTaskId_t;
|
||||
|
||||
/* Task event mask data type */
|
||||
typedef uint8_t wsfTaskEvent_t;
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Declarations
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn wsfOsReadyToSleep
|
||||
*
|
||||
* \brief Check if WSF is ready to sleep.
|
||||
*
|
||||
* \param None.
|
||||
*
|
||||
* \return Return TRUE if there are no pending WSF task events set, FALSE otherwise.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
bool_t wsfOsReadyToSleep(void);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfOsInit
|
||||
*
|
||||
* \brief Initialized WsfOs module.
|
||||
*
|
||||
* \param None.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfOsInit(void);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn wsfOsDispatcher
|
||||
*
|
||||
* \brief Event dispatched. Designed to be called repeatedly from infinite loop.
|
||||
*
|
||||
* \param None.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void wsfOsDispatcher(void);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfOsShutdown
|
||||
*
|
||||
* \brief Shutdown OS.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfOsShutdown(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* WSF_OS_INT_H */
|
||||
+329
@@ -0,0 +1,329 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_queue.c
|
||||
*
|
||||
* \brief General purpose queue service.
|
||||
*
|
||||
* $Date: 2017-01-06 13:47:48 -0600 (Fri, 06 Jan 2017) $
|
||||
* $Revision: 10864 $
|
||||
*
|
||||
* Copyright (c) 2009-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_queue.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_cs.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/* Get next queue element */
|
||||
#define WSF_QUEUE_NEXT(p) (((wsfQueueElem_t *)(p))->pNext)
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/* Queue element */
|
||||
typedef struct wsfQueueElem_tag
|
||||
{
|
||||
struct wsfQueueElem_tag *pNext; /* pointer to next element */
|
||||
} wsfQueueElem_t;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfQueueEnq
|
||||
*
|
||||
* \brief Enqueue and element to the tail of a queue.
|
||||
*
|
||||
* \param pQueue Pointer to queue.
|
||||
* \param pElem Pointer to element.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfQueueEnq(wsfQueue_t *pQueue, void *pElem)
|
||||
{
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
WSF_ASSERT(pQueue != NULL);
|
||||
WSF_ASSERT(pElem != NULL);
|
||||
|
||||
/* initialize next pointer */
|
||||
WSF_QUEUE_NEXT(pElem) = NULL;
|
||||
|
||||
/* enter critical section */
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
/* if queue empty */
|
||||
if (pQueue->pHead == NULL)
|
||||
{
|
||||
pQueue->pHead = pElem;
|
||||
pQueue->pTail = pElem;
|
||||
}
|
||||
/* else enqueue element to the tail of queue */
|
||||
else
|
||||
{
|
||||
WSF_QUEUE_NEXT(pQueue->pTail) = pElem;
|
||||
pQueue->pTail = pElem;
|
||||
}
|
||||
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfQueueDeq
|
||||
*
|
||||
* \brief Dequeue and element from the head of a queue.
|
||||
*
|
||||
* \param pQueue Pointer to queue.
|
||||
*
|
||||
* \return Pointer to element that has been dequeued or NULL if queue is empty.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void *WsfQueueDeq(wsfQueue_t *pQueue)
|
||||
{
|
||||
wsfQueueElem_t *pElem;
|
||||
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
WSF_ASSERT(pQueue != NULL);
|
||||
|
||||
/* enter critical section */
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
pElem = pQueue->pHead;
|
||||
|
||||
/* if queue is not empty */
|
||||
if (pElem != NULL)
|
||||
{
|
||||
/* set head to next element in queue */
|
||||
pQueue->pHead = WSF_QUEUE_NEXT(pElem);
|
||||
|
||||
/* check for empty queue */
|
||||
if (pQueue->pHead == NULL)
|
||||
{
|
||||
pQueue->pTail = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
return pElem;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfQueuePush
|
||||
*
|
||||
* \brief Push and element to the head of a queue.
|
||||
*
|
||||
* \param pQueue Pointer to queue.
|
||||
* \param pElem Pointer to element.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfQueuePush(wsfQueue_t *pQueue, void *pElem)
|
||||
{
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
WSF_ASSERT(pQueue != NULL);
|
||||
WSF_ASSERT(pElem != NULL);
|
||||
|
||||
/* enter critical section */
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
/* else push element to head of queue */
|
||||
WSF_QUEUE_NEXT(pElem) = pQueue->pHead;
|
||||
|
||||
/* if queue was empty set tail */
|
||||
if (pQueue->pHead == NULL)
|
||||
{
|
||||
pQueue->pTail = pElem;
|
||||
}
|
||||
|
||||
/* set head */
|
||||
pQueue->pHead = pElem;
|
||||
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfQueueInsert
|
||||
*
|
||||
* \brief Insert an element into a queue. This function is typically used when iterating
|
||||
* over a queue.
|
||||
*
|
||||
* \param pQueue Pointer to queue.
|
||||
* \param pElem Pointer to element to be inserted.
|
||||
* \param pPrev Pointer to previous element in the queue before element to be inserted.
|
||||
* Note: set pPrev to NULL if pElem is first element in queue.
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfQueueInsert(wsfQueue_t *pQueue, void *pElem, void *pPrev)
|
||||
{
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
WSF_ASSERT(pQueue != NULL);
|
||||
WSF_ASSERT(pElem != NULL);
|
||||
|
||||
/* enter critical section */
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
/* if queue empty or inserting at tail */
|
||||
if (pQueue->pHead == NULL || pPrev == pQueue->pTail)
|
||||
{
|
||||
/* queue as normal */
|
||||
WsfQueueEnq(pQueue, pElem);
|
||||
}
|
||||
/* else if inserting at head */
|
||||
else if (pPrev == NULL)
|
||||
{
|
||||
/* push to head */
|
||||
WsfQueuePush(pQueue, pElem);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* insert in middle of queue */
|
||||
WSF_QUEUE_NEXT(pElem) = WSF_QUEUE_NEXT(pPrev);
|
||||
WSF_QUEUE_NEXT(pPrev) = pElem;
|
||||
}
|
||||
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfQueueRemove
|
||||
*
|
||||
* \brief Remove an element from a queue. This function is typically used when iterating
|
||||
* over a queue.
|
||||
*
|
||||
* \param pQueue Pointer to queue.
|
||||
* \param pElem Pointer to element to be removed.
|
||||
* \param pPrev Pointer to previous element in the queue before element to be removed.
|
||||
* Note: set pPrev to NULL if pElem is first element in queue.
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfQueueRemove(wsfQueue_t *pQueue, void *pElem, void *pPrev)
|
||||
{
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
WSF_ASSERT(pQueue != NULL);
|
||||
WSF_ASSERT(pQueue->pHead != NULL);
|
||||
WSF_ASSERT(pElem != NULL);
|
||||
|
||||
/* enter critical section */
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
/* if first element */
|
||||
if (pElem == pQueue->pHead)
|
||||
{
|
||||
/* remove from head of queue */
|
||||
pQueue->pHead = WSF_QUEUE_NEXT(pElem);
|
||||
}
|
||||
else if (pPrev)
|
||||
{
|
||||
/* remove from middle of queue, pPrev will never be null */
|
||||
WSF_QUEUE_NEXT(pPrev) = WSF_QUEUE_NEXT(pElem);
|
||||
}
|
||||
|
||||
/* if last element */
|
||||
if (pElem == pQueue->pTail)
|
||||
{
|
||||
/* update tail */
|
||||
pQueue->pTail = pPrev;
|
||||
}
|
||||
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfQueueCount
|
||||
*
|
||||
* \brief Count the number of elements in a queue.
|
||||
*
|
||||
* \param pQueue Pointer to queue.
|
||||
*
|
||||
* \return Number of elements in queue.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint16_t WsfQueueCount(wsfQueue_t *pQueue)
|
||||
{
|
||||
wsfQueueElem_t *pElem;
|
||||
uint16_t count = 0;
|
||||
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
WSF_ASSERT(pQueue != NULL);
|
||||
|
||||
/* enter critical section */
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
pElem = pQueue->pHead;
|
||||
|
||||
/* iterate over queue */
|
||||
while (pElem != NULL)
|
||||
{
|
||||
count++;
|
||||
pElem = pElem->pNext;
|
||||
}
|
||||
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfQueueEmpty
|
||||
*
|
||||
* \brief Return TRUE if queue is empty.
|
||||
*
|
||||
* \param pQueue Pointer to queue.
|
||||
*
|
||||
* \return TRUE if queue is empty, FALSE otherwise.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
bool_t WsfQueueEmpty(wsfQueue_t *pQueue)
|
||||
{
|
||||
bool_t empty;
|
||||
|
||||
WSF_CS_INIT(cs);
|
||||
|
||||
WSF_ASSERT(pQueue != NULL);
|
||||
|
||||
/* enter critical section */
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
empty = (pQueue->pHead == NULL);
|
||||
|
||||
/* exit critical section */
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
return empty;
|
||||
}
|
||||
+407
@@ -0,0 +1,407 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_timer.c
|
||||
*
|
||||
* \brief Timer service.
|
||||
*
|
||||
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
|
||||
* $Revision: 10805 $
|
||||
*
|
||||
* Copyright (c) 2009-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_queue.h"
|
||||
#include "wsf_timer.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "timers.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/* convert seconds to timer ticks */
|
||||
#define WSF_TIMER_SEC_TO_TICKS(sec) ((1000 / WSF_MS_PER_TICK) * (sec))
|
||||
|
||||
/* convert milliseconds to timer ticks */
|
||||
#define WSF_TIMER_MS_TO_TICKS(ms) ((ms) / WSF_MS_PER_TICK)
|
||||
|
||||
#define CLK_TICKS_PER_WSF_TICKS (WSF_MS_PER_TICK*configTICK_RATE_HZ/1000)
|
||||
|
||||
/**************************************************************************************************
|
||||
Global Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
wsfQueue_t wsfTimerTimerQueue; /*!< Timer queue */
|
||||
TimerHandle_t xWsfTimer;
|
||||
static uint32_t g_ui32LastTime = 0;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn wsfTimerRemove
|
||||
*
|
||||
* \brief Remove a timer from queue. Note this function does not lock task scheduling.
|
||||
*
|
||||
* \param pTimer Pointer to timer.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void wsfTimerRemove(wsfTimer_t *pTimer)
|
||||
{
|
||||
wsfTimer_t *pElem;
|
||||
wsfTimer_t *pPrev = NULL;
|
||||
|
||||
pElem = (wsfTimer_t *) wsfTimerTimerQueue.pHead;
|
||||
|
||||
/* find timer in queue */
|
||||
while (pElem != NULL)
|
||||
{
|
||||
if (pElem == pTimer)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pPrev = pElem;
|
||||
pElem = pElem->pNext;
|
||||
}
|
||||
|
||||
/* if timer found remove from queue */
|
||||
if (pElem != NULL)
|
||||
{
|
||||
WsfQueueRemove(&wsfTimerTimerQueue, pTimer, pPrev);
|
||||
|
||||
pTimer->isStarted = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn wsfTimerInsert
|
||||
*
|
||||
* \brief Insert a timer into the queue sorted by the timer expiration.
|
||||
*
|
||||
* \param pTimer Pointer to timer.
|
||||
* \param ticks Timer ticks until expiration.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void wsfTimerInsert(wsfTimer_t *pTimer, wsfTimerTicks_t ticks)
|
||||
{
|
||||
wsfTimer_t *pElem;
|
||||
wsfTimer_t *pPrev = NULL;
|
||||
|
||||
/* task schedule lock */
|
||||
WsfTaskLock();
|
||||
|
||||
/* if timer is already running stop it first */
|
||||
if (pTimer->isStarted)
|
||||
{
|
||||
wsfTimerRemove(pTimer);
|
||||
}
|
||||
|
||||
pTimer->isStarted = TRUE;
|
||||
pTimer->ticks = ticks;
|
||||
|
||||
pElem = (wsfTimer_t *) wsfTimerTimerQueue.pHead;
|
||||
|
||||
/* find insertion point in queue */
|
||||
while (pElem != NULL)
|
||||
{
|
||||
if (pTimer->ticks < pElem->ticks)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pPrev = pElem;
|
||||
pElem = pElem->pNext;
|
||||
}
|
||||
|
||||
/* insert timer into queue */
|
||||
WsfQueueInsert(&wsfTimerTimerQueue, pTimer, pPrev);
|
||||
|
||||
/* task schedule unlock */
|
||||
WsfTaskUnlock();
|
||||
}
|
||||
|
||||
static void WsfTimer_handler(TimerHandle_t xTimer)
|
||||
{
|
||||
WsfTaskSetReady(0, WSF_TIMER_EVENT);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTimerInit
|
||||
*
|
||||
* \brief Initialize the timer service. This function should only be called once
|
||||
* upon system initialization.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfTimerInit(void)
|
||||
{
|
||||
WSF_QUEUE_INIT(&wsfTimerTimerQueue);
|
||||
|
||||
if(xWsfTimer == NULL)
|
||||
{
|
||||
xWsfTimer = xTimerCreate("WSF Timer", pdMS_TO_TICKS(WSF_MS_PER_TICK),
|
||||
pdFALSE, NULL, WsfTimer_handler);
|
||||
configASSERT(xWsfTimer);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTimerStartSec
|
||||
*
|
||||
* \brief Start a timer in units of seconds.
|
||||
*
|
||||
* \param pTimer Pointer to timer.
|
||||
* \param sec Seconds until expiration.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfTimerStartSec(wsfTimer_t *pTimer, wsfTimerTicks_t sec)
|
||||
{
|
||||
WSF_TRACE_INFO2("WsfTimerStartSec pTimer:0x%x ticks:%u", (uint32_t)pTimer, WSF_TIMER_SEC_TO_TICKS(sec));
|
||||
|
||||
/* insert timer into queue */
|
||||
wsfTimerInsert(pTimer, WSF_TIMER_SEC_TO_TICKS(sec));
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTimerStartMs
|
||||
*
|
||||
* \brief Start a timer in units of milliseconds.
|
||||
*
|
||||
* \param pTimer Pointer to timer.
|
||||
* \param ms Milliseconds until expiration.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfTimerStartMs(wsfTimer_t *pTimer, wsfTimerTicks_t ms)
|
||||
{
|
||||
WSF_TRACE_INFO2("WsfTimerStartMs pTimer:0x%x ticks:%u", (uint32_t)pTimer, WSF_TIMER_MS_TO_TICKS(ms));
|
||||
|
||||
/* insert timer into queue */
|
||||
wsfTimerInsert(pTimer, WSF_TIMER_MS_TO_TICKS(ms));
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTimerStop
|
||||
*
|
||||
* \brief Stop a timer.
|
||||
*
|
||||
* \param pTimer Pointer to timer.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfTimerStop(wsfTimer_t *pTimer)
|
||||
{
|
||||
WSF_TRACE_INFO1("WsfTimerStop pTimer:0x%x", pTimer);
|
||||
|
||||
/* task schedule lock */
|
||||
WsfTaskLock();
|
||||
|
||||
wsfTimerRemove(pTimer);
|
||||
|
||||
/* task schedule unlock */
|
||||
WsfTaskUnlock();
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTimerUpdate
|
||||
*
|
||||
* \brief Update the timer service with the number of elapsed ticks.
|
||||
*
|
||||
* \param ticks Number of ticks since last update.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfTimerUpdate(wsfTimerTicks_t ticks)
|
||||
{
|
||||
wsfTimer_t *pElem;
|
||||
|
||||
/* task schedule lock */
|
||||
WsfTaskLock();
|
||||
|
||||
pElem = (wsfTimer_t *) wsfTimerTimerQueue.pHead;
|
||||
|
||||
/* iterate over timer queue */
|
||||
while (pElem != NULL)
|
||||
{
|
||||
/* decrement ticks while preventing underflow */
|
||||
if (pElem->ticks > ticks)
|
||||
{
|
||||
pElem->ticks -= ticks;
|
||||
}
|
||||
else
|
||||
{
|
||||
pElem->ticks = 0;
|
||||
|
||||
/* timer expired; set task for this timer as ready */
|
||||
WsfTaskSetReady(pElem->handlerId, WSF_TIMER_EVENT);
|
||||
}
|
||||
|
||||
pElem = pElem->pNext;
|
||||
}
|
||||
|
||||
/* task schedule unlock */
|
||||
WsfTaskUnlock();
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTimerNextExpiration
|
||||
*
|
||||
* \brief Return the number of ticks until the next timer expiration. Note that this
|
||||
* function can return zero even if a timer is running, indicating a timer
|
||||
* has expired but has not yet been serviced.
|
||||
*
|
||||
* \param pTimerRunning Returns TRUE if a timer is running, FALSE if no timers running.
|
||||
*
|
||||
* \return The number of ticks until the next timer expiration.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
wsfTimerTicks_t WsfTimerNextExpiration(bool_t *pTimerRunning)
|
||||
{
|
||||
wsfTimerTicks_t ticks;
|
||||
|
||||
/* task schedule lock */
|
||||
WsfTaskLock();
|
||||
|
||||
if (wsfTimerTimerQueue.pHead == NULL)
|
||||
{
|
||||
*pTimerRunning = FALSE;
|
||||
ticks = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pTimerRunning = TRUE;
|
||||
ticks = ((wsfTimer_t *) wsfTimerTimerQueue.pHead)->ticks;
|
||||
}
|
||||
|
||||
/* task schedule unlock */
|
||||
WsfTaskUnlock();
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTimerServiceExpired
|
||||
*
|
||||
* \brief Service expired timers for the given task.
|
||||
*
|
||||
* \param taskId Task ID.
|
||||
*
|
||||
* \return Pointer to timer or NULL.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
wsfTimer_t *WsfTimerServiceExpired(wsfTaskId_t taskId)
|
||||
{
|
||||
wsfTimer_t *pElem;
|
||||
wsfTimer_t *pPrev = NULL;
|
||||
|
||||
/* Unused parameters */
|
||||
(void)taskId;
|
||||
|
||||
/* task schedule lock */
|
||||
WsfTaskLock();
|
||||
|
||||
/* find expired timers in queue */
|
||||
if (((pElem = (wsfTimer_t *) wsfTimerTimerQueue.pHead) != NULL) &&
|
||||
(pElem->ticks == 0))
|
||||
{
|
||||
/* remove timer from queue */
|
||||
WsfQueueRemove(&wsfTimerTimerQueue, pElem, pPrev);
|
||||
|
||||
pElem->isStarted = FALSE;
|
||||
|
||||
/* task schedule unlock */
|
||||
WsfTaskUnlock();
|
||||
|
||||
WSF_TRACE_INFO1("Timer expired pTimer:0x%x", pElem);
|
||||
|
||||
/* return timer */
|
||||
return pElem;
|
||||
}
|
||||
|
||||
/* task schedule unlock */
|
||||
WsfTaskUnlock();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Calculate the elapsed time, and update the WSF software timers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void WsfTimerUpdateTicks(void)
|
||||
{
|
||||
uint32_t ui32CurrentTime, ui32ElapsedTime;
|
||||
bool_t bTimerRunning;
|
||||
wsfTimerTicks_t xNextExpiration;
|
||||
|
||||
//
|
||||
// Read the continuous timer.
|
||||
//
|
||||
ui32CurrentTime = xTaskGetTickCount();
|
||||
|
||||
//
|
||||
// Figure out how long it has been since the last time we've read the
|
||||
// continuous timer. We should be reading often enough that we'll never
|
||||
// have more than one overflow.
|
||||
//
|
||||
ui32ElapsedTime = ui32CurrentTime - g_ui32LastTime;
|
||||
|
||||
//
|
||||
// Check to see if any WSF ticks need to happen.
|
||||
//
|
||||
if ( (ui32ElapsedTime / CLK_TICKS_PER_WSF_TICKS) > 0 )
|
||||
{
|
||||
//
|
||||
// Update the WSF timers and save the current time as our "last
|
||||
// update".
|
||||
//
|
||||
WsfTimerUpdate(ui32ElapsedTime / CLK_TICKS_PER_WSF_TICKS);
|
||||
|
||||
g_ui32LastTime = ui32CurrentTime;
|
||||
}
|
||||
|
||||
//
|
||||
// Check to see when the next timer expiration should happen.
|
||||
//
|
||||
xNextExpiration = WsfTimerNextExpiration(&bTimerRunning);
|
||||
|
||||
//
|
||||
// If there's a pending WSF timer event, set an interrupt to wake us up in
|
||||
// time to service it.
|
||||
//
|
||||
if ( xNextExpiration )
|
||||
{
|
||||
configASSERT(pdPASS == xTimerChangePeriod( xWsfTimer,
|
||||
pdMS_TO_TICKS(xNextExpiration*CLK_TICKS_PER_WSF_TICKS), 100)) ;
|
||||
}
|
||||
}
|
||||
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_trace.c
|
||||
*
|
||||
* \brief Trace message implementation.
|
||||
*
|
||||
* $Date: 2014-08-06 15:13:15 -0700 (Wed, 06 Aug 2014) $
|
||||
* $Revision: 1708 $
|
||||
*
|
||||
* Copyright (c) 2009 Wicentric, Inc., all rights reserved.
|
||||
* Wicentric confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact Wicentric, Inc. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_cs.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "am_util_debug.h"
|
||||
#include "am_util_stdio.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef WSF_RING_BUF_SIZE
|
||||
/*! \brief Size of token ring buffer (multiple of 2^N). */
|
||||
#define WSF_RING_BUF_SIZE 32
|
||||
#endif
|
||||
|
||||
/*! \brief Ring buffer flow control condition detected. */
|
||||
#define WSF_TOKEN_FLAG_FLOW_CTRL (1 << 28)
|
||||
|
||||
/**************************************************************************************************
|
||||
Data types
|
||||
**************************************************************************************************/
|
||||
|
||||
#if WSF_TOKEN_ENABLED
|
||||
|
||||
/*! \brief Trace control block. */
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t token; /*!< Token. */
|
||||
uint32_t param; /*!< Parameter. */
|
||||
} ringBuf[WSF_RING_BUF_SIZE]; /*!< Tokenized tracing ring buffer. */
|
||||
|
||||
volatile uint32_t prodIdx; /*!< Ring buffer producer index. */
|
||||
volatile uint32_t consIdx; /*!< Ring buffer consumer index. */
|
||||
|
||||
WsfTokenHandler_t pendCback; /*!< Pending event handler. */
|
||||
|
||||
bool_t ringBufEmpty; /*!< Ring buffer state. */
|
||||
} wsfTraceCb;
|
||||
|
||||
#endif
|
||||
|
||||
#if WSF_TRACE_ENABLED == TRUE
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfPacketTrace
|
||||
*
|
||||
* \brief Print raw HCI data as a trace message.
|
||||
*
|
||||
* \param ui8Type HCI packet type byte
|
||||
* \param ui32Len Length of the HCI packet
|
||||
* \param pui8Buf Pointer to the buffer of HCI data
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfPacketTrace(uint8_t ui8Type, uint32_t ui32Len, uint8_t *pui8Buf)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
am_util_debug_printf("%02X ", ui8Type);
|
||||
|
||||
for(i = 0; i < ui32Len; i++)
|
||||
{
|
||||
if ((i % 8) == 0)
|
||||
{
|
||||
am_util_debug_printf("\n");
|
||||
}
|
||||
|
||||
am_util_debug_printf("%02X ", *pui8Buf++);
|
||||
}
|
||||
|
||||
am_util_debug_printf("\n\n");
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfTrace
|
||||
*
|
||||
* \brief Print a trace message.
|
||||
*
|
||||
* \param pStr Message format string
|
||||
* \param ... Additional aguments, printf-style
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfTrace(const char *pStr, ...)
|
||||
{
|
||||
char pTraceMsg[AM_PRINTF_BUFSIZE];
|
||||
uint32_t ui32NumChars;
|
||||
va_list args;
|
||||
|
||||
va_start(args, pStr);
|
||||
am_util_stdio_vsprintf(pTraceMsg, pStr, args);
|
||||
//vprintf(pStr, args);
|
||||
va_end(args);
|
||||
ui32NumChars = am_util_debug_printf(pTraceMsg);
|
||||
if (!(ui32NumChars < AM_PRINTF_BUFSIZE))
|
||||
WsfAssert(__FILE__, (uint16_t) __LINE__);
|
||||
am_util_debug_printf("\n");
|
||||
}
|
||||
|
||||
#elif WSF_TOKEN_ENABLED == TRUE
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WsfToken
|
||||
*
|
||||
* \brief Output tokenized message.
|
||||
*
|
||||
* \param tok Token
|
||||
* \param var Variable
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WsfToken(uint32_t tok, uint32_t var)
|
||||
{
|
||||
static uint32_t flags = 0;
|
||||
|
||||
WSF_CS_INIT(cs);
|
||||
WSF_CS_ENTER(cs);
|
||||
|
||||
uint32_t prodIdx = (wsfTraceCb.prodIdx + 1) & (WSF_RING_BUF_SIZE - 1);
|
||||
|
||||
if (prodIdx != wsfTraceCb.consIdx)
|
||||
{
|
||||
wsfTraceCb.ringBuf[wsfTraceCb.prodIdx].token = tok | flags;
|
||||
wsfTraceCb.ringBuf[wsfTraceCb.prodIdx].param = var;
|
||||
wsfTraceCb.prodIdx = prodIdx;
|
||||
flags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = WSF_TOKEN_FLAG_FLOW_CTRL;
|
||||
}
|
||||
|
||||
WSF_CS_EXIT(cs);
|
||||
|
||||
if (wsfTraceCb.pendCback && wsfTraceCb.ringBufEmpty)
|
||||
{
|
||||
wsfTraceCb.ringBufEmpty = FALSE;
|
||||
wsfTraceCb.pendCback();
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn wsfTokenService
|
||||
*
|
||||
* \brief Service the trace ring buffer.
|
||||
*
|
||||
* \return TRUE if trace messages pending, FALSE otherwise.
|
||||
*
|
||||
* This routine is called in the main loop for a "push" type trace systems.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
bool_t WsfTokenService(void)
|
||||
{
|
||||
static uint8_t outBuf[sizeof(wsfTraceCb.ringBuf[0])];
|
||||
static uint8_t outBufIdx = sizeof(wsfTraceCb.ringBuf[0]);
|
||||
|
||||
if (outBufIdx < sizeof(wsfTraceCb.ringBuf[0]))
|
||||
{
|
||||
outBufIdx += WsfTokenIOWrite(outBuf + outBufIdx, sizeof(wsfTraceCb.ringBuf[0]) - outBufIdx);
|
||||
|
||||
if (outBufIdx < sizeof(wsfTraceCb.ringBuf[0]))
|
||||
{
|
||||
/* I/O device is flow controlled. */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (wsfTraceCb.consIdx != wsfTraceCb.prodIdx)
|
||||
{
|
||||
memcpy(&outBuf, &wsfTraceCb.ringBuf[wsfTraceCb.consIdx], sizeof(wsfTraceCb.ringBuf[0]));
|
||||
outBufIdx = 0;
|
||||
|
||||
wsfTraceCb.consIdx = (wsfTraceCb.consIdx + 1) & (WSF_RING_BUF_SIZE - 1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_trace.h
|
||||
*
|
||||
* \brief Trace message interface.
|
||||
*
|
||||
* $Date: 2015-08-11 07:08:51 -0700 (Tue, 11 Aug 2015) $
|
||||
* $Revision: 3555 $
|
||||
*
|
||||
* Copyright (c) 2009 Wicentric, Inc., all rights reserved.
|
||||
* Wicentric confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact Wicentric, Inc. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef WSF_TRACE_H
|
||||
#define WSF_TRACE_H
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Token event handler. */
|
||||
typedef void (*WsfTokenHandler_t)(void);
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Prototypes
|
||||
**************************************************************************************************/
|
||||
|
||||
void WsfTrace(const char *pStr, ...);
|
||||
void WsfToken(uint32_t tok, uint32_t var);
|
||||
void WsfPacketTrace(uint8_t ui8Type, uint32_t ui32Len, uint8_t *pui8Buf);
|
||||
|
||||
/* Token management. */
|
||||
bool_t WsfTokenService(void);
|
||||
uint8_t WsfTokenIOWrite(uint8_t *pBuf, uint8_t len);
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
#ifdef WSF_TRACE_ENABLED
|
||||
#ifndef AM_DEBUG_PRINTF
|
||||
#undef WSF_TRACE_ENABLED
|
||||
#warning "AM_DEBUG_PRINTF is needed when WSF_TRACE_ENABLED is defined"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TOKEN_GENERATION
|
||||
|
||||
#define WSF_TOKEN(subsys, stat, msg) \
|
||||
__WSF_TOKEN_DEFINE__( \
|
||||
/* token: */ MODULE_ID, __LINE__, \
|
||||
/* origin: */ __FILE__, subsys, \
|
||||
/* message: */ stat, msg)
|
||||
|
||||
#define WSF_TRACE0(subsys, stat, msg) WSF_TOKEN(subsys, stat, msg)
|
||||
#define WSF_TRACE1(subsys, stat, msg, var1) WSF_TOKEN(subsys, stat, msg)
|
||||
#define WSF_TRACE2(subsys, stat, msg, var1, var2) WSF_TOKEN(subsys, stat, msg)
|
||||
#define WSF_TRACE3(subsys, stat, msg, var1, var2, var3) WSF_TOKEN(subsys, stat, msg)
|
||||
|
||||
#define PACKET_TRACE(type, len, buf)
|
||||
|
||||
#elif WSF_TRACE_ENABLED == TRUE
|
||||
|
||||
#define WSF_TRACE0(subsys, stat, msg) WsfTrace(msg)
|
||||
#define WSF_TRACE1(subsys, stat, msg, var1) WsfTrace(msg, var1)
|
||||
#define WSF_TRACE2(subsys, stat, msg, var1, var2) WsfTrace(msg, var1, var2)
|
||||
#define WSF_TRACE3(subsys, stat, msg, var1, var2, var3) WsfTrace(msg, var1, var2, var3)
|
||||
|
||||
#define PACKET_TRACE(type, len, buf) WsfPacketTrace(type, len, buf)
|
||||
|
||||
#elif WSF_TOKEN_ENABLED == TRUE
|
||||
|
||||
#define WSF_TRACE0(subsys, stat, msg) \
|
||||
WsfToken(((__LINE__ & 0xFFF) << 16) | MODULE_ID, 0)
|
||||
#define WSF_TRACE1(subsys, stat, msg, var1) \
|
||||
WsfToken(((__LINE__ & 0xFFF) << 16) | MODULE_ID, (uint32_t)(var1))
|
||||
#define WSF_TRACE2(subsys, stat, msg, var1, var2) \
|
||||
WsfToken(((__LINE__ & 0xFFF) << 16) | MODULE_ID, (uint32_t)(((var2) << 16) | ((var1) & 0xFFFF)))
|
||||
#define WSF_TRACE3(subsys, stat, msg, var1, var2, var3) \
|
||||
WsfToken(((__LINE__ & 0xFFF) << 16) | MODULE_ID, (uint32_t)((((var3) & 0xFF) << 16) | (((var2) & 0xFF) << 8) | ((var1) & 0xFF)))
|
||||
|
||||
#define PACKET_TRACE(type, len, buf)
|
||||
|
||||
#else
|
||||
|
||||
#define WSF_TRACE0(subsys, stat, msg)
|
||||
#define WSF_TRACE1(subsys, stat, msg, var1)
|
||||
#define WSF_TRACE2(subsys, stat, msg, var1, var2)
|
||||
#define WSF_TRACE3(subsys, stat, msg, var1, var2, var3)
|
||||
#define PACKET_TRACE(type, len, buf)
|
||||
|
||||
#endif
|
||||
|
||||
#define WSF_TRACE_INFO0(msg)
|
||||
#define WSF_TRACE_INFO1(msg, var1)
|
||||
#define WSF_TRACE_INFO2(msg, var1, var2)
|
||||
#define WSF_TRACE_INFO3(msg, var1, var2, var3)
|
||||
#define WSF_TRACE_WARN0(msg) WSF_TRACE0("WSF", "WARN", msg)
|
||||
#define WSF_TRACE_WARN1(msg, var1) WSF_TRACE1("WSF", "WARN", msg, var1)
|
||||
#define WSF_TRACE_WARN2(msg, var1, var2) WSF_TRACE2("WSF", "WARN", msg, var1, var2)
|
||||
#define WSF_TRACE_WARN3(msg, var1, var2, var3) WSF_TRACE3("WSF", "WARN", msg, var1, var2, var3)
|
||||
#define WSF_TRACE_ERR0(msg) WSF_TRACE0("WSF", "ERR", msg)
|
||||
#define WSF_TRACE_ERR1(msg, var1) WSF_TRACE1("WSF", "ERR", msg, var1)
|
||||
#define WSF_TRACE_ERR2(msg, var1, var2) WSF_TRACE2("WSF", "ERR", msg, var1, var2)
|
||||
#define WSF_TRACE_ERR3(msg, var1, var2, var3) WSF_TRACE3("WSF", "ERR", msg, var1, var2, var3)
|
||||
#define WSF_TRACE_ALLOC0(msg)
|
||||
#define WSF_TRACE_ALLOC1(msg, var1)
|
||||
#define WSF_TRACE_ALLOC2(msg, var1, var2)
|
||||
#define WSF_TRACE_ALLOC3(msg, var1, var2, var3)
|
||||
#define WSF_TRACE_FREE0(msg)
|
||||
#define WSF_TRACE_FREE1(msg, var1)
|
||||
#define WSF_TRACE_FREE2(msg, var1, var2)
|
||||
#define WSF_TRACE_FREE3(msg, var1, var2, var3)
|
||||
#define WSF_TRACE_MSG0(msg)
|
||||
#define WSF_TRACE_MSG1(msg, var1)
|
||||
#define WSF_TRACE_MSG2(msg, var1, var2)
|
||||
#define WSF_TRACE_MSG3(msg, var1, var2, var3)
|
||||
|
||||
#ifdef HCI_TRACE_ENABLED
|
||||
#define HCI_TRACE_INFO0(msg) WSF_TRACE0("HCI", "INFO", msg)
|
||||
#define HCI_TRACE_INFO1(msg, var1) WSF_TRACE1("HCI", "INFO", msg, var1)
|
||||
#define HCI_TRACE_INFO2(msg, var1, var2) WSF_TRACE2("HCI", "INFO", msg, var1, var2)
|
||||
#define HCI_TRACE_INFO3(msg, var1, var2, var3) WSF_TRACE3("HCI", "INFO", msg, var1, var2, var3)
|
||||
#define HCI_TRACE_WARN0(msg) WSF_TRACE0("HCI", "WARN", msg)
|
||||
#define HCI_TRACE_WARN1(msg, var1) WSF_TRACE1("HCI", "WARN", msg, var1)
|
||||
#define HCI_TRACE_WARN2(msg, var1, var2) WSF_TRACE2("HCI", "WARN", msg, var1, var2)
|
||||
#define HCI_TRACE_WARN3(msg, var1, var2, var3) WSF_TRACE3("HCI", "WARN", msg, var1, var2, var3)
|
||||
#define HCI_TRACE_ERR0(msg) WSF_TRACE0("HCI", "ERR", msg)
|
||||
#define HCI_TRACE_ERR1(msg, var1) WSF_TRACE1("HCI", "ERR", msg, var1)
|
||||
#define HCI_TRACE_ERR2(msg, var1, var2) WSF_TRACE2("HCI", "ERR", msg, var1, var2)
|
||||
#define HCI_TRACE_ERR3(msg, var1, var2, var3) WSF_TRACE3("HCI", "ERR", msg, var1, var2, var3)
|
||||
|
||||
#define HCI_PDUMP_CMD(len, pBuf) PACKET_TRACE(0x1, len, pBuf)
|
||||
#define HCI_PDUMP_EVT(len, pBuf) PACKET_TRACE(0x4, len, pBuf)
|
||||
#define HCI_PDUMP_TX_ACL(len, pBuf) PACKET_TRACE(0x2, len, pBuf)
|
||||
#define HCI_PDUMP_RX_ACL(len, pBuf) PACKET_TRACE(0x2, len, pBuf)
|
||||
#else
|
||||
#define HCI_TRACE_INFO0(msg)
|
||||
#define HCI_TRACE_INFO1(msg, var1)
|
||||
#define HCI_TRACE_INFO2(msg, var1, var2)
|
||||
#define HCI_TRACE_INFO3(msg, var1, var2, var3)
|
||||
#define HCI_TRACE_WARN0(msg)
|
||||
#define HCI_TRACE_WARN1(msg, var1)
|
||||
#define HCI_TRACE_WARN2(msg, var1, var2)
|
||||
#define HCI_TRACE_WARN3(msg, var1, var2, var3)
|
||||
#define HCI_TRACE_ERR0(msg)
|
||||
#define HCI_TRACE_ERR1(msg, var1)
|
||||
#define HCI_TRACE_ERR2(msg, var1, var2)
|
||||
#define HCI_TRACE_ERR3(msg, var1, var2, var3)
|
||||
|
||||
#define HCI_PDUMP_CMD(len, pBuf)
|
||||
#define HCI_PDUMP_EVT(len, pBuf)
|
||||
#define HCI_PDUMP_TX_ACL(len, pBuf)
|
||||
#define HCI_PDUMP_RX_ACL(len, pBuf)
|
||||
|
||||
#endif //HCI_TRACE_ENABLED
|
||||
|
||||
#define DM_TRACE_INFO0(msg) WSF_TRACE0("DM", "INFO", msg)
|
||||
#define DM_TRACE_INFO1(msg, var1) WSF_TRACE1("DM", "INFO", msg, var1)
|
||||
#define DM_TRACE_INFO2(msg, var1, var2) WSF_TRACE2("DM", "INFO", msg, var1, var2)
|
||||
#define DM_TRACE_INFO3(msg, var1, var2, var3) WSF_TRACE3("DM", "INFO", msg, var1, var2, var3)
|
||||
#define DM_TRACE_WARN0(msg) WSF_TRACE0("DM", "WARN", msg)
|
||||
#define DM_TRACE_WARN1(msg, var1) WSF_TRACE1("DM", "WARN", msg, var1)
|
||||
#define DM_TRACE_WARN2(msg, var1, var2) WSF_TRACE2("DM", "WARN", msg, var1, var2)
|
||||
#define DM_TRACE_WARN3(msg, var1, var2, var3) WSF_TRACE3("DM", "WARN", msg, var1, var2, var3)
|
||||
#define DM_TRACE_ERR0(msg) WSF_TRACE0("DM", "ERR", msg)
|
||||
#define DM_TRACE_ERR1(msg, var1) WSF_TRACE1("DM", "ERR", msg, var1)
|
||||
#define DM_TRACE_ERR2(msg, var1, var2) WSF_TRACE2("DM", "ERR", msg, var1, var2)
|
||||
#define DM_TRACE_ERR3(msg, var1, var2, var3) WSF_TRACE3("DM", "ERR", msg, var1, var2, var3)
|
||||
#define DM_TRACE_ALLOC0(msg) WSF_TRACE0("DM", "ALLOC", msg)
|
||||
#define DM_TRACE_ALLOC1(msg, var1) WSF_TRACE1("DM", "ALLOC", msg, var1)
|
||||
#define DM_TRACE_ALLOC2(msg, var1, var2) WSF_TRACE2("DM", "ALLOC", msg, var1, var2)
|
||||
#define DM_TRACE_ALLOC3(msg, var1, var2, var3) WSF_TRACE3("DM", "ALLOC", msg, var1, var2, var3)
|
||||
#define DM_TRACE_FREE0(msg) WSF_TRACE0("DM", "FREE", msg)
|
||||
#define DM_TRACE_FREE1(msg, var1) WSF_TRACE1("DM", "FREE", msg, var1)
|
||||
#define DM_TRACE_FREE2(msg, var1, var2) WSF_TRACE2("DM", "FREE", msg, var1, var2)
|
||||
#define DM_TRACE_FREE3(msg, var1, var2, var3) WSF_TRACE3("DM", "FREE", msg, var1, var2, var3)
|
||||
|
||||
#define L2C_TRACE_INFO0(msg) WSF_TRACE0("L2C", "INFO", msg)
|
||||
#define L2C_TRACE_INFO1(msg, var1) WSF_TRACE1("L2C", "INFO", msg, var1)
|
||||
#define L2C_TRACE_INFO2(msg, var1, var2) WSF_TRACE2("L2C", "INFO", msg, var1, var2)
|
||||
#define L2C_TRACE_INFO3(msg, var1, var2, var3) WSF_TRACE3("L2C", "INFO", msg, var1, var2, var3)
|
||||
#define L2C_TRACE_WARN0(msg) WSF_TRACE0("L2C", "WARN", msg)
|
||||
#define L2C_TRACE_WARN1(msg, var1) WSF_TRACE1("L2C", "WARN", msg, var1)
|
||||
#define L2C_TRACE_WARN2(msg, var1, var2) WSF_TRACE2("L2C", "WARN", msg, var1, var2)
|
||||
#define L2C_TRACE_WARN3(msg, var1, var2, var3) WSF_TRACE3("L2C", "WARN", msg, var1, var2, var3)
|
||||
#define L2C_TRACE_ERR0(msg) WSF_TRACE0("L2C", "ERR", msg)
|
||||
#define L2C_TRACE_ERR1(msg, var1) WSF_TRACE1("L2C", "ERR", msg, var1)
|
||||
#define L2C_TRACE_ERR2(msg, var1, var2) WSF_TRACE2("L2C", "ERR", msg, var1, var2)
|
||||
#define L2C_TRACE_ERR3(msg, var1, var2, var3) WSF_TRACE3("L2C", "ERR", msg, var1, var2, var3)
|
||||
|
||||
#define ATT_TRACE_INFO0(msg) WSF_TRACE0("ATT", "INFO", msg)
|
||||
#define ATT_TRACE_INFO1(msg, var1) WSF_TRACE1("ATT", "INFO", msg, var1)
|
||||
#define ATT_TRACE_INFO2(msg, var1, var2) WSF_TRACE2("ATT", "INFO", msg, var1, var2)
|
||||
#define ATT_TRACE_INFO3(msg, var1, var2, var3) WSF_TRACE3("ATT", "INFO", msg, var1, var2, var3)
|
||||
#define ATT_TRACE_WARN0(msg) WSF_TRACE0("ATT", "WARN", msg)
|
||||
#define ATT_TRACE_WARN1(msg, var1) WSF_TRACE1("ATT", "WARN", msg, var1)
|
||||
#define ATT_TRACE_WARN2(msg, var1, var2) WSF_TRACE2("ATT", "WARN", msg, var1, var2)
|
||||
#define ATT_TRACE_WARN3(msg, var1, var2, var3) WSF_TRACE3("ATT", "WARN", msg, var1, var2, var3)
|
||||
#define ATT_TRACE_ERR0(msg) WSF_TRACE0("ATT", "ERR", msg)
|
||||
#define ATT_TRACE_ERR1(msg, var1) WSF_TRACE1("ATT", "ERR", msg, var1)
|
||||
#define ATT_TRACE_ERR2(msg, var1, var2) WSF_TRACE2("ATT", "ERR", msg, var1, var2)
|
||||
#define ATT_TRACE_ERR3(msg, var1, var2, var3) WSF_TRACE3("ATT", "ERR", msg, var1, var2, var3)
|
||||
|
||||
#define SMP_TRACE_INFO0(msg) WSF_TRACE0("SMP", "INFO", msg)
|
||||
#define SMP_TRACE_INFO1(msg, var1) WSF_TRACE1("SMP", "INFO", msg, var1)
|
||||
#define SMP_TRACE_INFO2(msg, var1, var2) WSF_TRACE2("SMP", "INFO", msg, var1, var2)
|
||||
#define SMP_TRACE_INFO3(msg, var1, var2, var3) WSF_TRACE3("SMP", "INFO", msg, var1, var2, var3)
|
||||
#define SMP_TRACE_WARN0(msg) WSF_TRACE0("SMP", "WARN", msg)
|
||||
#define SMP_TRACE_WARN1(msg, var1) WSF_TRACE1("SMP", "WARN", msg, var1)
|
||||
#define SMP_TRACE_WARN2(msg, var1, var2) WSF_TRACE2("SMP", "WARN", msg, var1, var2)
|
||||
#define SMP_TRACE_WARN3(msg, var1, var2, var3) WSF_TRACE3("SMP", "WARN", msg, var1, var2, var3)
|
||||
#define SMP_TRACE_ERR0(msg) WSF_TRACE0("SMP", "ERR", msg)
|
||||
#define SMP_TRACE_ERR1(msg, var1) WSF_TRACE1("SMP", "ERR", msg, var1)
|
||||
#define SMP_TRACE_ERR2(msg, var1, var2) WSF_TRACE2("SMP", "ERR", msg, var1, var2)
|
||||
#define SMP_TRACE_ERR3(msg, var1, var2, var3) WSF_TRACE3("SMP", "ERR", msg, var1, var2, var3)
|
||||
|
||||
#define APP_TRACE_INFO0(msg) WSF_TRACE0("APP", "INFO", msg)
|
||||
#define APP_TRACE_INFO1(msg, var1) WSF_TRACE1("APP", "INFO", msg, var1)
|
||||
#define APP_TRACE_INFO2(msg, var1, var2) WSF_TRACE2("APP", "INFO", msg, var1, var2)
|
||||
#define APP_TRACE_INFO3(msg, var1, var2, var3) WSF_TRACE3("APP", "INFO", msg, var1, var2, var3)
|
||||
#define APP_TRACE_WARN0(msg) WSF_TRACE0("APP", "WARN", msg)
|
||||
#define APP_TRACE_WARN1(msg, var1) WSF_TRACE1("APP", "WARN", msg, var1)
|
||||
#define APP_TRACE_WARN2(msg, var1, var2) WSF_TRACE2("APP", "WARN", msg, var1, var2)
|
||||
#define APP_TRACE_WARN3(msg, var1, var2, var3) WSF_TRACE3("APP", "WARN", msg, var1, var2, var3)
|
||||
#define APP_TRACE_ERR0(msg) WSF_TRACE0("APP", "ERR", msg)
|
||||
#define APP_TRACE_ERR1(msg, var1) WSF_TRACE1("APP", "ERR", msg, var1)
|
||||
#define APP_TRACE_ERR2(msg, var1, var2) WSF_TRACE2("APP", "ERR", msg, var1, var2)
|
||||
#define APP_TRACE_ERR3(msg, var1, var2, var3) WSF_TRACE3("APP", "ERR", msg, var1, var2, var3)
|
||||
|
||||
#define LL_TRACE_INFO0(msg) WSF_TRACE0("LL", "INFO", msg)
|
||||
#define LL_TRACE_INFO1(msg, var1) WSF_TRACE1("LL", "INFO", msg, var1)
|
||||
#define LL_TRACE_INFO2(msg, var1, var2) WSF_TRACE2("LL", "INFO", msg, var1, var2)
|
||||
#define LL_TRACE_INFO3(msg, var1, var2, var3) WSF_TRACE3("LL", "INFO", msg, var1, var2, var3)
|
||||
#define LL_TRACE_WARN0(msg) WSF_TRACE0("LL", "WARN", msg)
|
||||
#define LL_TRACE_WARN1(msg, var1) WSF_TRACE1("LL", "WARN", msg, var1)
|
||||
#define LL_TRACE_WARN2(msg, var1, var2) WSF_TRACE2("LL", "WARN", msg, var1, var2)
|
||||
#define LL_TRACE_WARN3(msg, var1, var2, var3) WSF_TRACE3("LL", "WARN", msg, var1, var2, var3)
|
||||
#define LL_TRACE_ERR0(msg) WSF_TRACE0("LL", "ERR", msg)
|
||||
#define LL_TRACE_ERR1(msg, var1) WSF_TRACE1("LL", "ERR", msg, var1)
|
||||
#define LL_TRACE_ERR2(msg, var1, var2) WSF_TRACE2("LL", "ERR", msg, var1, var2)
|
||||
#define LL_TRACE_ERR3(msg, var1, var2, var3) WSF_TRACE3("LL", "ERR", msg, var1, var2, var3)
|
||||
|
||||
#endif /* WSF_TRACE_H */
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wsf_types.h
|
||||
*
|
||||
* \brief Platform-independent data types.
|
||||
*
|
||||
* $Date: 2015-05-14 14:58:23 -0700 (Thu, 14 May 2015) $
|
||||
* $Revision: 2837 $
|
||||
*
|
||||
* Copyright (c) 2009 Wicentric, Inc., all rights reserved.
|
||||
* Wicentric confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact Wicentric, Inc. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef WSF_TYPES_H
|
||||
#define WSF_TYPES_H
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/* Integer data types */
|
||||
#if ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) && \
|
||||
(!defined(__ICC8051__) || (__ICC8051__ == 0)))
|
||||
#include <stdint.h>
|
||||
#else
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed long int32_t;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#endif
|
||||
|
||||
/* Boolean data type */
|
||||
typedef uint8_t bool_t;
|
||||
|
||||
#endif /* WSF_TYPES_H */
|
||||
@@ -0,0 +1,127 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file bda.c
|
||||
*
|
||||
* \brief Bluetooth device address utilities.
|
||||
*
|
||||
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
|
||||
* $Revision: 10805 $
|
||||
*
|
||||
* Copyright (c) 2009-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "wsf_types.h"
|
||||
#include "bda.h"
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn BdaCpy
|
||||
*
|
||||
* \brief Copy a BD address from source to destination.
|
||||
*
|
||||
* \param pDst Pointer to destination.
|
||||
* \param pSrc Pointer to source.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void BdaCpy(uint8_t *pDst, const uint8_t *pSrc)
|
||||
{
|
||||
memcpy(pDst, pSrc, BDA_ADDR_LEN);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn BdaCmp
|
||||
*
|
||||
* \brief Compare two BD addresses.
|
||||
*
|
||||
* \param pAddr1 First address.
|
||||
* \param pAddr2 Second address.
|
||||
*
|
||||
* \return TRUE if addresses match, FALSE otherwise.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
bool_t BdaCmp(const uint8_t *pAddr1, const uint8_t *pAddr2)
|
||||
{
|
||||
return (memcmp(pAddr1, pAddr2, BDA_ADDR_LEN) == 0);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn BdaClr
|
||||
*
|
||||
* \brief Set a BD address to all zeros.
|
||||
*
|
||||
* \param pDst Pointer to destination.
|
||||
*
|
||||
* \return pDst + BDA_ADDR_LEN
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t *BdaClr(uint8_t *pDst)
|
||||
{
|
||||
memset(pDst, 0, BDA_ADDR_LEN);
|
||||
|
||||
return (pDst + BDA_ADDR_LEN);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn BdaIsZeros
|
||||
*
|
||||
* \brief Check if a BD address is all zeros.
|
||||
*
|
||||
* \param pAddr Pointer to address.
|
||||
*
|
||||
* \return TRUE if address is all zeros, FALSE otherwise.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
bool_t BdaIsZeros(const uint8_t *pAddr)
|
||||
{
|
||||
uint8_t addrZeros[BDA_ADDR_LEN] = { 0 };
|
||||
|
||||
return (memcmp(pAddr, addrZeros, BDA_ADDR_LEN) == 0);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn Bda2Str
|
||||
*
|
||||
* \brief Convert a BD address to a string.
|
||||
*
|
||||
* \param pAddr Pointer to BD address.
|
||||
*
|
||||
* \return Pointer to string.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
char *Bda2Str(const uint8_t *pAddr)
|
||||
{
|
||||
static const char hex[] = "0123456789ABCDEF";
|
||||
static char str[BDA_ADDR_STR_LEN + 1];
|
||||
char *pStr = str;
|
||||
|
||||
/* address is little endian so copy in reverse */
|
||||
pAddr += BDA_ADDR_LEN;
|
||||
|
||||
while (pStr < &str[BDA_ADDR_STR_LEN])
|
||||
{
|
||||
*pStr++ = hex[*--pAddr >> 4];
|
||||
*pStr++ = hex[*pAddr & 0x0F];
|
||||
}
|
||||
|
||||
/* null terminate string */
|
||||
*pStr = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file bda.h
|
||||
*
|
||||
* \brief Bluetooth device address utilities.
|
||||
*
|
||||
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
|
||||
* $Revision: 10805 $
|
||||
*
|
||||
* Copyright (c) 2009-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef BDA_H
|
||||
#define BDA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief BD address length */
|
||||
#define BDA_ADDR_LEN 6
|
||||
|
||||
/*! \brief BD address string length */
|
||||
#define BDA_ADDR_STR_LEN (BDA_ADDR_LEN * 2)
|
||||
|
||||
/*! \brief BDA RPA check */
|
||||
#define BDA_ADDR_IS_RPA(bda) (((bda)[5] & 0xC0) == 0x40)
|
||||
|
||||
/*! \brief BDA NRPA check */
|
||||
#define BDA_ADDR_IS_NRPA(bda) (((bda)[5] & 0xC0) == 0x00)
|
||||
|
||||
/*! \brief BDA static random check */
|
||||
#define BDA_ADDR_IS_STATIC(bda) (((bda)[5] & 0xC0) == 0xC0)
|
||||
|
||||
/*! \brief BDA64 RPA check */
|
||||
#define BDA64_ADDR_IS_RPA(bda64) ((((bda64) >> 40) & 0xC0) == 0x40)
|
||||
|
||||
/*! \brief BDA64 NRPA check */
|
||||
#define BDA64_ADDR_IS_NRPA(bda64) ((((bda64) >> 40) & 0xC0) == 0x00)
|
||||
|
||||
/*! \brief BDA64 static random check */
|
||||
#define BDA64_ADDR_IS_STATIC(bda64) ((((bda64) >> 40) & 0xC0) == 0xC0)
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief BD address data type */
|
||||
typedef uint8_t bdAddr_t[BDA_ADDR_LEN];
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Declarations
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn BdaCpy
|
||||
*
|
||||
* \brief Copy a BD address from source to destination.
|
||||
*
|
||||
* \param pDst Pointer to destination.
|
||||
* \param pSrc Pointer to source.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void BdaCpy(uint8_t *pDst, const uint8_t *pSrc);
|
||||
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn BdaCmp
|
||||
*
|
||||
* \brief Compare two BD addresses.
|
||||
*
|
||||
* \param pAddr1 First address.
|
||||
* \param pAddr2 Second address.
|
||||
*
|
||||
* \return TRUE if addresses match, FALSE otherwise.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
bool_t BdaCmp(const uint8_t *pAddr1, const uint8_t *pAddr2);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn BdaClr
|
||||
*
|
||||
* \brief Set a BD address to all zeros.
|
||||
*
|
||||
* \param pDst Pointer to destination.
|
||||
*
|
||||
* \return pDst + BDA_ADDR_LEN
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t *BdaClr(uint8_t *pDst);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn BdaIsZeros
|
||||
*
|
||||
* \brief Check if a BD address is all zeros.
|
||||
*
|
||||
* \param pAddr Pointer to address.
|
||||
*
|
||||
* \return TRUE if address is all zeros, FALSE otherwise.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
bool_t BdaIsZeros(const uint8_t *pAddr);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn Bda2Str
|
||||
*
|
||||
* \brief Convert a BD address to a string.
|
||||
*
|
||||
* \param pAddr Pointer to BD address.
|
||||
*
|
||||
* \return Pointer to string.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
char *Bda2Str(const uint8_t *pAddr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* BDA_H */
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file bstream.h
|
||||
*
|
||||
* \brief Byte stream to integer conversion functions.
|
||||
*
|
||||
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
|
||||
* $Revision: 10805 $
|
||||
*
|
||||
* Copyright (c) 2009-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "bstream.h"
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Convert bstream to uint64_t.
|
||||
*
|
||||
* \param p Bstream pointer.
|
||||
*
|
||||
* \return Resulting uint64_t number.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint64_t BstreamToUint64(const uint8_t *p)
|
||||
{
|
||||
return ((uint64_t)p[0] << 0) |
|
||||
((uint64_t)p[1] << 8) |
|
||||
((uint64_t)p[2] << 16) |
|
||||
((uint64_t)p[3] << 24) |
|
||||
((uint64_t)p[4] << 32) |
|
||||
((uint64_t)p[5] << 40) |
|
||||
((uint64_t)p[6] << 48) |
|
||||
((uint64_t)p[7] << 56);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Convert uint64_t to bstream.
|
||||
*
|
||||
* \param p Bstream pointer.
|
||||
* \param n uint64_t number.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void Uint64ToBstream(uint8_t *p, uint64_t n)
|
||||
{
|
||||
p[0] = (uint8_t)(n >> 0);
|
||||
p[1] = (uint8_t)(n >> 8);
|
||||
p[2] = (uint8_t)(n >> 16);
|
||||
p[3] = (uint8_t)(n >> 24);
|
||||
p[4] = (uint8_t)(n >> 32);
|
||||
p[5] = (uint8_t)(n >> 40);
|
||||
p[6] = (uint8_t)(n >> 48);
|
||||
p[7] = (uint8_t)(n >> 56);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Convert bstream to BDA64.
|
||||
*
|
||||
* \param p Bstream pointer.
|
||||
*
|
||||
* \return Resulting BDA64 number.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint64_t BstreamToBda64(const uint8_t *p)
|
||||
{
|
||||
return (uint64_t)p[0] << 0 |
|
||||
(uint64_t)p[1] << 8 |
|
||||
(uint64_t)p[2] << 16 |
|
||||
(uint64_t)p[3] << 24 |
|
||||
(uint64_t)p[4] << 32 |
|
||||
(uint64_t)p[5] << 40;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Convert BDA64 to bstream.
|
||||
*
|
||||
* \param p Bstream pointer.
|
||||
* \param bda uint64_t BDA.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void Bda64ToBstream(uint8_t *p, uint64_t bda)
|
||||
{
|
||||
p[0] = (uint8_t)(bda >> 0);
|
||||
p[1] = (uint8_t)(bda >> 8);
|
||||
p[2] = (uint8_t)(bda >> 16);
|
||||
p[3] = (uint8_t)(bda >> 24);
|
||||
p[4] = (uint8_t)(bda >> 32);
|
||||
p[5] = (uint8_t)(bda >> 40);
|
||||
}
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file bstream.h
|
||||
*
|
||||
* \brief Byte stream to integer conversion macros.
|
||||
*
|
||||
* $Date: 2017-02-06 19:25:09 -0600 (Mon, 06 Feb 2017) $
|
||||
* $Revision: 11104 $
|
||||
*
|
||||
* Copyright (c) 2009-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef BSTREAM_H
|
||||
#define BSTREAM_H
|
||||
|
||||
#include "bda.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*!
|
||||
* Macros for converting a little endian byte buffer to integers.
|
||||
*/
|
||||
#define BYTES_TO_UINT16(n, p) {n = ((uint16_t)(p)[0] + ((uint16_t)(p)[1] << 8));}
|
||||
|
||||
#define BYTES_TO_UINT24(n, p) {n = ((uint16_t)(p)[0] + ((uint16_t)(p)[1] << 8) + \
|
||||
((uint16_t)(p)[2] << 16));}
|
||||
|
||||
#define BYTES_TO_UINT32(n, p) {n = ((uint32_t)(p)[0] + ((uint32_t)(p)[1] << 8) + \
|
||||
((uint32_t)(p)[2] << 16) + ((uint32_t)(p)[3] << 24));}
|
||||
|
||||
#define BYTES_TO_UINT40(n, p) {n = ((uint64_t)(p)[0] + ((uint64_t)(p)[1] << 8) + \
|
||||
((uint64_t)(p)[2] << 16) + ((uint64_t)(p)[3] << 24) + \
|
||||
((uint64_t)(p)[4] << 32));}
|
||||
|
||||
#define BYTES_TO_UINT64(n, p) {n = ((uint64_t)(p)[0] + ((uint64_t)(p)[1] << 8) + \
|
||||
((uint64_t)(p)[2] << 16) + ((uint64_t)(p)[3] << 24) + \
|
||||
((uint64_t)(p)[4] << 32) + ((uint64_t)(p)[5] << 40) + \
|
||||
((uint64_t)(p)[6] << 48) + ((uint64_t)(p)[7] << 56));}
|
||||
|
||||
/*!
|
||||
* Macros for converting little endian integers to array of bytes
|
||||
*/
|
||||
#define UINT16_TO_BYTES(n) ((uint8_t) (n)), ((uint8_t)((n) >> 8))
|
||||
#define UINT32_TO_BYTES(n) ((uint8_t) (n)), ((uint8_t)((n) >> 8)), ((uint8_t)((n) >> 16)), ((uint8_t)((n) >> 24))
|
||||
|
||||
/*!
|
||||
* Macros for converting little endian integers to single bytes
|
||||
*/
|
||||
#define UINT16_TO_BYTE0(n) ((uint8_t) (n))
|
||||
#define UINT16_TO_BYTE1(n) ((uint8_t) ((n) >> 8))
|
||||
|
||||
#define UINT32_TO_BYTE0(n) ((uint8_t) (n))
|
||||
#define UINT32_TO_BYTE1(n) ((uint8_t) ((n) >> 8))
|
||||
#define UINT32_TO_BYTE2(n) ((uint8_t) ((n) >> 16))
|
||||
#define UINT32_TO_BYTE3(n) ((uint8_t) ((n) >> 24))
|
||||
|
||||
/*!
|
||||
* Macros for converting a little endian byte stream to integers, with increment.
|
||||
*/
|
||||
#define BSTREAM_TO_INT8(n, p) {n = (int8_t)(*(p)++);}
|
||||
#define BSTREAM_TO_UINT8(n, p) {n = (uint8_t)(*(p)++);}
|
||||
#define BSTREAM_TO_UINT16(n, p) {BYTES_TO_UINT16(n, p); p += 2;}
|
||||
#define BSTREAM_TO_UINT24(n, p) {BYTES_TO_UINT24(n, p); p += 3;}
|
||||
#define BSTREAM_TO_UINT32(n, p) {BYTES_TO_UINT32(n, p); p += 4;}
|
||||
#define BSTREAM_TO_UINT40(n, p) {BYTES_TO_UINT40(n, p); p += 5;}
|
||||
#define BSTREAM_TO_UINT64(n, p) {n = BstreamToUint64(p); p += 8;}
|
||||
#define BSTREAM_TO_BDA(bda, p) {BdaCpy(bda, p); p += BDA_ADDR_LEN;}
|
||||
#define BSTREAM_TO_BDA64(bda, p) {bda = BstreamToBda64(p); p += BDA_ADDR_LEN;}
|
||||
|
||||
/*!
|
||||
* Macros for converting integers to a little endian byte stream, with increment.
|
||||
*/
|
||||
#define UINT8_TO_BSTREAM(p, n) {*(p)++ = (uint8_t)(n);}
|
||||
#define UINT16_TO_BSTREAM(p, n) {*(p)++ = (uint8_t)(n); *(p)++ = (uint8_t)((n) >> 8);}
|
||||
#define UINT24_TO_BSTREAM(p, n) {*(p)++ = (uint8_t)(n); *(p)++ = (uint8_t)((n) >> 8); \
|
||||
*(p)++ = (uint8_t)((n) >> 16);}
|
||||
#define UINT32_TO_BSTREAM(p, n) {*(p)++ = (uint8_t)(n); *(p)++ = (uint8_t)((n) >> 8); \
|
||||
*(p)++ = (uint8_t)((n) >> 16); *(p)++ = (uint8_t)((n) >> 24);}
|
||||
#define UINT40_TO_BSTREAM(p, n) {*(p)++ = (uint8_t)(n); *(p)++ = (uint8_t)((n) >> 8); \
|
||||
*(p)++ = (uint8_t)((n) >> 16); *(p)++ = (uint8_t)((n) >> 24); \
|
||||
*(p)++ = (uint8_t)((n) >> 32);}
|
||||
#define UINT64_TO_BSTREAM(p, n) {Uint64ToBstream(p, n); p += sizeof(uint64_t);}
|
||||
#define BDA_TO_BSTREAM(p, bda) {BdaCpy(p, bda); p += BDA_ADDR_LEN;}
|
||||
#define BDA64_TO_BSTREAM(p, bda) {Bda64ToBstream(p, bda); p += BDA_ADDR_LEN;}
|
||||
|
||||
/*!
|
||||
* Macros for converting integers to a little endian byte stream, without increment.
|
||||
*/
|
||||
#define UINT16_TO_BUF(p, n) {(p)[0] = (uint8_t)(n); (p)[1] = (uint8_t)((n) >> 8);}
|
||||
#define UINT24_TO_BUF(p, n) {(p)[0] = (uint8_t)(n); (p)[1] = (uint8_t)((n) >> 8); \
|
||||
(p)[2] = (uint8_t)((n) >> 16);}
|
||||
#define UINT32_TO_BUF(p, n) {(p)[0] = (uint8_t)(n); (p)[1] = (uint8_t)((n) >> 8); \
|
||||
(p)[2] = (uint8_t)((n) >> 16); (p)[3] = (uint8_t)((n) >> 24);}
|
||||
#define UINT40_TO_BUF(p, n) {(p)[0] = (uint8_t)(n); (p)[1] = (uint8_t)((n) >> 8); \
|
||||
(p)[2] = (uint8_t)((n) >> 16); (p)[3] = (uint8_t)((n) >> 24);\
|
||||
(p)[4] = (uint8_t)((n) >> 32);}
|
||||
|
||||
/*!
|
||||
* Macros for comparing a little endian byte buffer to integers.
|
||||
*/
|
||||
#define BYTES_UINT16_CMP(p, n) ((p)[1] == UINT16_TO_BYTE1(n) && (p)[0] == UINT16_TO_BYTE0(n))
|
||||
|
||||
/*!
|
||||
* Macros for IEEE FLOAT type: exponent = byte 3, mantissa = bytes 2-0
|
||||
*/
|
||||
#define FLT_TO_UINT32(m, e) ((m) | ((int32_t)(e) << 24))
|
||||
#define UINT32_TO_FLT(m, e, n) {m = UINT32_TO_FLT_M(n); e = UINT32_TO_FLT_E(n);}
|
||||
#define UINT32_TO_FLT_M(n) ((((n) & 0x00FFFFFF) >= 0x00800000) ? \
|
||||
((int32_t)(((n) | 0xFF000000))) : ((int32_t)((n) & 0x00FFFFFF)))
|
||||
#define UINT32_TO_FLT_E(n) ((int8_t)(n >> 24))
|
||||
/*!
|
||||
* Macros for IEEE SFLOAT type: exponent = bits 15-12, mantissa = bits 11-0
|
||||
*/
|
||||
#define SFLT_TO_UINT16(m, e) ((m) | ((int16_t)(e) << 12))
|
||||
#define UINT16_TO_SFLT(m, e, n) {m = UINT16_TO_SFLT_M(n); e = UINT16_TO_SFLT_E(n);}
|
||||
#define UINT16_TO_SFLT_M(n) ((((n) & 0x0FFF) >= 0x0800) ? \
|
||||
((int16_t)(((n) | 0xF000))) : ((int16_t)((n) & 0x0FFF)))
|
||||
#define UINT16_TO_SFLT_E(n) (((n >> 12) >= 0x0008) ? \
|
||||
((int8_t)(((n >> 12) | 0xF0))) : ((int8_t)(n >> 12)))
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Declarations
|
||||
**************************************************************************************************/
|
||||
|
||||
uint64_t BstreamToBda64(const uint8_t *p);
|
||||
uint64_t BstreamToUint64(const uint8_t *p);
|
||||
void Bda64ToBstream(uint8_t *p, uint64_t bda);
|
||||
void Uint64ToBstream(uint8_t *p, uint64_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* BSTREAM_H */
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file calc128.c
|
||||
*
|
||||
* \brief 128-bit integer utilities.
|
||||
*
|
||||
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
|
||||
* $Revision: 10805 $
|
||||
*
|
||||
* Copyright (c) 2010-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "wsf_types.h"
|
||||
#include "calc128.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Global Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/* 128-bit zero value */
|
||||
const uint8_t calc128Zeros[CALC128_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Declarations
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn Calc128Cpy
|
||||
*
|
||||
* \brief Copy a 128-bit integer from source to destination.
|
||||
*
|
||||
* \param pDst Pointer to destination.
|
||||
* \param pSrc Pointer to source.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void Calc128Cpy(uint8_t *pDst, uint8_t *pSrc)
|
||||
{
|
||||
memcpy(pDst, pSrc, CALC128_LEN);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn Calc128Cpy64
|
||||
*
|
||||
* \brief Copy a 64-bit integer from source to destination.
|
||||
*
|
||||
* \param pDst Pointer to destination.
|
||||
* \param pSrc Pointer to source.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void Calc128Cpy64(uint8_t *pDst, uint8_t *pSrc)
|
||||
{
|
||||
memcpy(pDst, pSrc, CALC128_LEN/2);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn Calc128Xor
|
||||
*
|
||||
* \brief Exclusive-or two 128-bit integers and return the result in pDst.
|
||||
*
|
||||
* \param pDst Pointer to destination.
|
||||
* \param pSrc Pointer to source.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void Calc128Xor(uint8_t *pDst, uint8_t *pSrc)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = CALC128_LEN; i > 0; i--)
|
||||
{
|
||||
*pDst++ ^= *pSrc++;
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file calc128.h
|
||||
*
|
||||
* \brief 128-bit integer utilities.
|
||||
*
|
||||
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
|
||||
* $Revision: 10805 $
|
||||
*
|
||||
* Copyright (c) 2010-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef CALC128_H
|
||||
#define CALC128_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! 128-bit integer length in bytes */
|
||||
#define CALC128_LEN 16
|
||||
|
||||
/**************************************************************************************************
|
||||
Global Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! 128-bit zero value */
|
||||
extern const uint8_t calc128Zeros[CALC128_LEN];
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Declarations
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn Calc128Cpy
|
||||
*
|
||||
* \brief Copy a 128-bit integer from source to destination.
|
||||
*
|
||||
* \param pDst Pointer to destination.
|
||||
* \param pSrc Pointer to source.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void Calc128Cpy(uint8_t *pDst, uint8_t *pSrc);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn Calc128Cpy64
|
||||
*
|
||||
* \brief Copy a 64-bit integer from source to destination.
|
||||
*
|
||||
* \param pDst Pointer to destination.
|
||||
* \param pSrc Pointer to source.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void Calc128Cpy64(uint8_t *pDst, uint8_t *pSrc);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn Calc128Xor
|
||||
*
|
||||
* \brief Exclusive-or two 128-bit integers and return the result in pDst.
|
||||
*
|
||||
* \param pDst Pointer to destination.
|
||||
* \param pSrc Pointer to source.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void Calc128Xor(uint8_t *pDst, uint8_t *pSrc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* CALC128_H */
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file crc32.c
|
||||
*
|
||||
* \brief CRC-32 utilities.
|
||||
*
|
||||
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
|
||||
* $Revision: 10805 $
|
||||
*
|
||||
* Copyright (c) 2010-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "crc32.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Variables
|
||||
**************************************************************************************************/
|
||||
static const uint32_t crc32Table[256] =
|
||||
{
|
||||
0x00000000U, 0x77073096U, 0xEE0E612CU, 0x990951BAU,
|
||||
0x076DC419U, 0x706AF48FU, 0xE963A535U, 0x9E6495A3U,
|
||||
0x0EDB8832U, 0x79DCB8A4U, 0xE0D5E91EU, 0x97D2D988U,
|
||||
0x09B64C2BU, 0x7EB17CBDU, 0xE7B82D07U, 0x90BF1D91U,
|
||||
0x1DB71064U, 0x6AB020F2U, 0xF3B97148U, 0x84BE41DEU,
|
||||
0x1ADAD47DU, 0x6DDDE4EBU, 0xF4D4B551U, 0x83D385C7U,
|
||||
0x136C9856U, 0x646BA8C0U, 0xFD62F97AU, 0x8A65C9ECU,
|
||||
0x14015C4FU, 0x63066CD9U, 0xFA0F3D63U, 0x8D080DF5U,
|
||||
0x3B6E20C8U, 0x4C69105EU, 0xD56041E4U, 0xA2677172U,
|
||||
0x3C03E4D1U, 0x4B04D447U, 0xD20D85FDU, 0xA50AB56BU,
|
||||
0x35B5A8FAU, 0x42B2986CU, 0xDBBBC9D6U, 0xACBCF940U,
|
||||
0x32D86CE3U, 0x45DF5C75U, 0xDCD60DCFU, 0xABD13D59U,
|
||||
0x26D930ACU, 0x51DE003AU, 0xC8D75180U, 0xBFD06116U,
|
||||
0x21B4F4B5U, 0x56B3C423U, 0xCFBA9599U, 0xB8BDA50FU,
|
||||
0x2802B89EU, 0x5F058808U, 0xC60CD9B2U, 0xB10BE924U,
|
||||
0x2F6F7C87U, 0x58684C11U, 0xC1611DABU, 0xB6662D3DU,
|
||||
0x76DC4190U, 0x01DB7106U, 0x98D220BCU, 0xEFD5102AU,
|
||||
0x71B18589U, 0x06B6B51FU, 0x9FBFE4A5U, 0xE8B8D433U,
|
||||
0x7807C9A2U, 0x0F00F934U, 0x9609A88EU, 0xE10E9818U,
|
||||
0x7F6A0DBBU, 0x086D3D2DU, 0x91646C97U, 0xE6635C01U,
|
||||
0x6B6B51F4U, 0x1C6C6162U, 0x856530D8U, 0xF262004EU,
|
||||
0x6C0695EDU, 0x1B01A57BU, 0x8208F4C1U, 0xF50FC457U,
|
||||
0x65B0D9C6U, 0x12B7E950U, 0x8BBEB8EAU, 0xFCB9887CU,
|
||||
0x62DD1DDFU, 0x15DA2D49U, 0x8CD37CF3U, 0xFBD44C65U,
|
||||
0x4DB26158U, 0x3AB551CEU, 0xA3BC0074U, 0xD4BB30E2U,
|
||||
0x4ADFA541U, 0x3DD895D7U, 0xA4D1C46DU, 0xD3D6F4FBU,
|
||||
0x4369E96AU, 0x346ED9FCU, 0xAD678846U, 0xDA60B8D0U,
|
||||
0x44042D73U, 0x33031DE5U, 0xAA0A4C5FU, 0xDD0D7CC9U,
|
||||
0x5005713CU, 0x270241AAU, 0xBE0B1010U, 0xC90C2086U,
|
||||
0x5768B525U, 0x206F85B3U, 0xB966D409U, 0xCE61E49FU,
|
||||
0x5EDEF90EU, 0x29D9C998U, 0xB0D09822U, 0xC7D7A8B4U,
|
||||
0x59B33D17U, 0x2EB40D81U, 0xB7BD5C3BU, 0xC0BA6CADU,
|
||||
0xEDB88320U, 0x9ABFB3B6U, 0x03B6E20CU, 0x74B1D29AU,
|
||||
0xEAD54739U, 0x9DD277AFU, 0x04DB2615U, 0x73DC1683U,
|
||||
0xE3630B12U, 0x94643B84U, 0x0D6D6A3EU, 0x7A6A5AA8U,
|
||||
0xE40ECF0BU, 0x9309FF9DU, 0x0A00AE27U, 0x7D079EB1U,
|
||||
0xF00F9344U, 0x8708A3D2U, 0x1E01F268U, 0x6906C2FEU,
|
||||
0xF762575DU, 0x806567CBU, 0x196C3671U, 0x6E6B06E7U,
|
||||
0xFED41B76U, 0x89D32BE0U, 0x10DA7A5AU, 0x67DD4ACCU,
|
||||
0xF9B9DF6FU, 0x8EBEEFF9U, 0x17B7BE43U, 0x60B08ED5U,
|
||||
0xD6D6A3E8U, 0xA1D1937EU, 0x38D8C2C4U, 0x4FDFF252U,
|
||||
0xD1BB67F1U, 0xA6BC5767U, 0x3FB506DDU, 0x48B2364BU,
|
||||
0xD80D2BDAU, 0xAF0A1B4CU, 0x36034AF6U, 0x41047A60U,
|
||||
0xDF60EFC3U, 0xA867DF55U, 0x316E8EEFU, 0x4669BE79U,
|
||||
0xCB61B38CU, 0xBC66831AU, 0x256FD2A0U, 0x5268E236U,
|
||||
0xCC0C7795U, 0xBB0B4703U, 0x220216B9U, 0x5505262FU,
|
||||
0xC5BA3BBEU, 0xB2BD0B28U, 0x2BB45A92U, 0x5CB36A04U,
|
||||
0xC2D7FFA7U, 0xB5D0CF31U, 0x2CD99E8BU, 0x5BDEAE1DU,
|
||||
0x9B64C2B0U, 0xEC63F226U, 0x756AA39CU, 0x026D930AU,
|
||||
0x9C0906A9U, 0xEB0E363FU, 0x72076785U, 0x05005713U,
|
||||
0x95BF4A82U, 0xE2B87A14U, 0x7BB12BAEU, 0x0CB61B38U,
|
||||
0x92D28E9BU, 0xE5D5BE0DU, 0x7CDCEFB7U, 0x0BDBDF21U,
|
||||
0x86D3D2D4U, 0xF1D4E242U, 0x68DDB3F8U, 0x1FDA836EU,
|
||||
0x81BE16CDU, 0xF6B9265BU, 0x6FB077E1U, 0x18B74777U,
|
||||
0x88085AE6U, 0xFF0F6A70U, 0x66063BCAU, 0x11010B5CU,
|
||||
0x8F659EFFU, 0xF862AE69U, 0x616BFFD3U, 0x166CCF45U,
|
||||
0xA00AE278U, 0xD70DD2EEU, 0x4E048354U, 0x3903B3C2U,
|
||||
0xA7672661U, 0xD06016F7U, 0x4969474DU, 0x3E6E77DBU,
|
||||
0xAED16A4AU, 0xD9D65ADCU, 0x40DF0B66U, 0x37D83BF0U,
|
||||
0xA9BCAE53U, 0xDEBB9EC5U, 0x47B2CF7FU, 0x30B5FFE9U,
|
||||
0xBDBDF21CU, 0xCABAC28AU, 0x53B39330U, 0x24B4A3A6U,
|
||||
0xBAD03605U, 0xCDD70693U, 0x54DE5729U, 0x23D967BFU,
|
||||
0xB3667A2EU, 0xC4614AB8U, 0x5D681B02U, 0x2A6F2B94U,
|
||||
0xB40BBE37U, 0xC30C8EA1U, 0x5A05DF1BU, 0x2D02EF8DU
|
||||
};
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn CalcCrc32
|
||||
*
|
||||
* \brief Calculate the CRC-32 of the given buffer.
|
||||
*
|
||||
* \param crcInit Initial value of the CRC.
|
||||
* \param len Length of the buffer.
|
||||
* \param pBuf Buffer to compute the CRC.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* This routine was originally generated with crcmod.py using the following parameters:
|
||||
* - polynomial 0x104C11DB7
|
||||
* - bit reverse algorithm
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t CalcCrc32(uint32_t crcInit, uint32_t len, uint8_t *pBuf)
|
||||
{
|
||||
uint32_t crc = crcInit;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
crc = crc32Table[*pBuf ^ (uint8_t)crc] ^ (crc >> 8);
|
||||
pBuf++;
|
||||
len--;
|
||||
}
|
||||
|
||||
crc = crc ^ 0xFFFFFFFFU;
|
||||
|
||||
return crc;
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file crc32.h
|
||||
*
|
||||
* \brief CRC-32 utilities.
|
||||
*
|
||||
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
|
||||
* $Revision: 10805 $
|
||||
*
|
||||
* Copyright (c) 2010-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef CRC32_H
|
||||
#define CRC32_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn CalcCrc32
|
||||
*
|
||||
* \brief Calculate the CRC-32 of the given buffer.
|
||||
*
|
||||
* \param crcInit Initial value of the CRC.
|
||||
* \param len Length of the buffer.
|
||||
* \param pBuf Buffer to compute the CRC.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* This routine was originally generated with crcmod.py using the following parameters:
|
||||
* - polynomial 0x104C11DB7
|
||||
* - bit reverse algorithm
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t CalcCrc32(uint32_t crcInit, uint32_t len, uint8_t *pBuf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* CRC32_H */
|
||||
+308
@@ -0,0 +1,308 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file print.c
|
||||
*
|
||||
* \brief Utility functions.
|
||||
*
|
||||
* $Date: 2016-03-29 14:55:12 -0700 (Tue, 29 Mar 2016) $
|
||||
* $Revision: 6524 $
|
||||
*
|
||||
* Copyright (c) 2015-2017 ARM Ltd., all rights reserved.
|
||||
* ARM confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "print.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Detect hexadecimal digits. */
|
||||
#define PRINT_IS_XDIGIT(c) (((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) || \
|
||||
((c >= 'A') && (c <= 'F')))
|
||||
|
||||
/*! \brief Convert hexadecimal digit to integer. */
|
||||
#define PRINT_XDIGIT_TO_INT(c) (((c >= '0') && (c <= '9')) ? (uint8_t)(c - '0') : \
|
||||
((c >= 'a') && (c <= 'f')) ? (uint8_t)(c - 'a' + 10u) : \
|
||||
((c >= 'A') && (c <= 'F')) ? (uint8_t)(c - 'A' + 10u) : 0u)
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn printFmtInt
|
||||
*
|
||||
* \brief Format an integer.
|
||||
*
|
||||
* \param pStr Storage for formatted integer.
|
||||
* \param maxLen Maximum number of characters to store.
|
||||
* \param i Integer to format.
|
||||
* \param base Integer base.
|
||||
* \param sign TRUE if sign should be printed.
|
||||
* \param width Width of field.
|
||||
*
|
||||
* \return Number of characters stored.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static int printFmtInt(char *pStr, int maxLen, int i, uint8_t base, bool_t sign, int width)
|
||||
{
|
||||
char *s, *p = pStr;
|
||||
unsigned int u = (unsigned int) i;
|
||||
uint8_t use_width;
|
||||
int t;
|
||||
|
||||
use_width = width;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
s = "0\0";
|
||||
width--;
|
||||
goto almost;
|
||||
}
|
||||
|
||||
if (sign && base == 10 && i < 0)
|
||||
{
|
||||
*pStr++ = '-';
|
||||
u = (unsigned int)-i;
|
||||
width--;
|
||||
}
|
||||
s = pStr + maxLen - 1;
|
||||
*s = '\0';
|
||||
|
||||
while (u && (!use_width || (width > 0)))
|
||||
{
|
||||
t = (unsigned int)u % base;
|
||||
if (t >= 10)
|
||||
{
|
||||
t += 'A' - '0' - 10;
|
||||
}
|
||||
*--s = (char)(t + '0');
|
||||
u /= base;
|
||||
width--;
|
||||
}
|
||||
|
||||
almost:
|
||||
while (width > 0)
|
||||
{
|
||||
*pStr++ = '0';
|
||||
width--;
|
||||
}
|
||||
strcpy(pStr, s);
|
||||
|
||||
return strlen(p);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn printParseInt
|
||||
*
|
||||
* \brief Parse an integer from a string.
|
||||
*
|
||||
* \param pStr String to parse.
|
||||
* \param pInt Storage for parsed integer.
|
||||
* \param base Integer base.
|
||||
*
|
||||
* \return Number of characters consumed.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static int32_t printParseInt(const char *pStr, uint32_t *pInt, uint32_t base)
|
||||
{
|
||||
int32_t r = 0;
|
||||
|
||||
if (base == 0)
|
||||
{
|
||||
if (*pStr == '0')
|
||||
{
|
||||
if (((*(pStr + 1) == 'x') || (*(pStr + 1) == 'X')) && PRINT_IS_XDIGIT(*(pStr + 2)))
|
||||
{
|
||||
r += 2;
|
||||
pStr += 2;
|
||||
base = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
base = 10;
|
||||
}
|
||||
}
|
||||
else if (base == 16)
|
||||
{
|
||||
if (*pStr == '0')
|
||||
{
|
||||
if (((*(pStr + 1) == 'x') || (*(pStr + 1) == 'X')) && PRINT_IS_XDIGIT(*(pStr + 2)))
|
||||
{
|
||||
r += 2;
|
||||
pStr += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* One character is required; all characters must be consumed. */
|
||||
*pInt = 0;
|
||||
do
|
||||
{
|
||||
char c;
|
||||
uint8_t t;
|
||||
|
||||
c = *pStr++;
|
||||
if (!PRINT_IS_XDIGIT(c))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
t = PRINT_XDIGIT_TO_INT(c);
|
||||
if (t >= base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
*pInt *= base;
|
||||
*pInt += t;
|
||||
r++;
|
||||
} while (*pStr != '\0');
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn PrintVsn
|
||||
*
|
||||
* \brief Print a trace message.
|
||||
*
|
||||
* \param pStr Storage for formatted string.
|
||||
* \param size Maximum number of characters to store.
|
||||
* \param pFmt Format string.
|
||||
* \param ap Arguments.
|
||||
*
|
||||
* \return Number of characters stored.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t PrintVsn(char *pStr, uint32_t size, const char *pFmt, va_list ap)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
*pStr = 0;
|
||||
size--; /* Ensure we null-terminate within our buffer */
|
||||
|
||||
while ((*pFmt != '\0') && (len < size))
|
||||
{
|
||||
uint32_t width = 0;
|
||||
|
||||
/* normal */
|
||||
if (*pFmt != '%')
|
||||
{
|
||||
*pStr++ = *pFmt++;
|
||||
len++;
|
||||
continue;
|
||||
}
|
||||
|
||||
pFmt++;
|
||||
if (*pFmt == '%')
|
||||
{
|
||||
*pStr++ = '%';
|
||||
len++;
|
||||
pFmt++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* width */
|
||||
if (*pFmt == '0')
|
||||
{
|
||||
pFmt += printParseInt(pFmt, &width, 10u);
|
||||
}
|
||||
|
||||
/* long (ignore) */
|
||||
if (*pFmt == 'l')
|
||||
{
|
||||
pFmt++;
|
||||
}
|
||||
|
||||
switch(*pFmt)
|
||||
{
|
||||
/* character */
|
||||
case 'c':
|
||||
{
|
||||
char tmp = va_arg(ap, int);
|
||||
*pStr++ = tmp;
|
||||
len++;
|
||||
break;
|
||||
}
|
||||
/* unsigned decimal integer */
|
||||
case 'u':
|
||||
{
|
||||
unsigned int tmp = va_arg(ap, unsigned int);
|
||||
uint8_t lenTmp = printFmtInt(pStr, size - len, tmp, 10, 0, width);
|
||||
pStr += lenTmp;
|
||||
len += lenTmp;
|
||||
break;
|
||||
}
|
||||
/* signed decimal integer */
|
||||
case 'd':
|
||||
{
|
||||
int tmp = va_arg(ap, int);
|
||||
uint8_t lenTmp = printFmtInt(pStr, size - len, tmp, 10, 1, width);
|
||||
pStr += lenTmp;
|
||||
len += lenTmp;
|
||||
break;
|
||||
}
|
||||
/* pointer */
|
||||
case 'p':
|
||||
{
|
||||
unsigned long tmp = va_arg(ap, unsigned long);
|
||||
uint8_t lenTmp = printFmtInt(pStr, size - len, tmp, 16, 1, 8u);
|
||||
pStr += lenTmp;
|
||||
len += lenTmp;
|
||||
break;
|
||||
}
|
||||
/* unsigned hexadecimal integer */
|
||||
case 'x':
|
||||
case 'X':
|
||||
{
|
||||
unsigned int tmp = va_arg(ap, unsigned int);
|
||||
uint8_t lenTmp = printFmtInt(pStr, size - len, tmp, 16, 0, width);
|
||||
pStr += lenTmp;
|
||||
len += lenTmp;
|
||||
break;
|
||||
}
|
||||
/* string */
|
||||
case 's':
|
||||
{
|
||||
char *tmp = va_arg(ap, char *);
|
||||
while ((tmp != NULL) && (*tmp != '\0') && (len < size))
|
||||
{
|
||||
*pStr++ = *tmp++;
|
||||
len++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pFmt++;
|
||||
}
|
||||
|
||||
/* Null-terminate output. */
|
||||
*pStr = 0;
|
||||
|
||||
if (len > size)
|
||||
{
|
||||
/* Compensate for -1 earlier. */
|
||||
return size + 2;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file print.h
|
||||
*
|
||||
* \brief Print functions.
|
||||
*
|
||||
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
|
||||
* $Revision: 10805 $
|
||||
*
|
||||
* Copyright (c) 2015-2017 ARM Ltd., all rights reserved.
|
||||
* ARM confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef PRINT_H
|
||||
#define PRINT_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wsf_types.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Print function attributes. */
|
||||
#if defined(__GNUC__) || defined(__CC_ARM)
|
||||
#define PRINT_ATTRIBUTE(a, b) __attribute__((format(printf, a, b)))
|
||||
#else
|
||||
#define PRINT_ATTRIBUTE(a, b)
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn UtilVsnPrintf
|
||||
*
|
||||
* \brief Print a trace message.
|
||||
*
|
||||
* \param pStr Storage for formatted string.
|
||||
* \param size Maximum number of characters to store.
|
||||
* \param pFmt Format string.
|
||||
* \param ap Arguments.
|
||||
*
|
||||
* \return Number of characters stored.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t PrintVsn(char *pStr, uint32_t size, const char *pFmt, va_list ap) PRINT_ATTRIBUTE(3, 0);
|
||||
|
||||
#endif /* PRINT_H */
|
||||
+532
@@ -0,0 +1,532 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file terminal.c
|
||||
*
|
||||
* \brief Terminal handler.
|
||||
*
|
||||
* $Date: 2016-03-29 14:55:12 -0700 (Tue, 29 Mar 2016) $
|
||||
* $Revision: 6524 $
|
||||
*
|
||||
* Copyright (c) 2015-2017 ARM Ltd., all rights reserved.
|
||||
* ARM confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "terminal.h"
|
||||
#include "print.h"
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "bstream.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
#define TERMINAL_IS_SPACE(c) ((c == '\n') || (c == '\t') || (c == '\r') || (c == ' ') || (c == '\v') || (c == '\f'))
|
||||
#define TERMINAL_IS_PRINT(c) ((c >= 0x20) && (c != 0x7F))
|
||||
|
||||
/*! \brief Terminal events. */
|
||||
enum
|
||||
{
|
||||
TERMINAL_EVENT_COMMAND_RX = (1 << 0)
|
||||
};
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Control block for terminal. */
|
||||
typedef struct
|
||||
{
|
||||
wsfHandlerId_t handlerId; /*!< Handler ID for TerminalHandler(). */
|
||||
terminalCommand_t *pFirstCommand; /*!< Pointer to first command. */
|
||||
char buf[TERMINAL_MAX_COMMAND_LEN + 1]; /*!< Command buffer. */
|
||||
bool_t isExecuting; /*!< TRUE if command in buffer is executing. */
|
||||
bool_t doEcho; /*!< TRUE if input should be echoed. */
|
||||
uint32_t bufOffset; /*!< Offset within buffer. */
|
||||
terminalUartTx_t terminalTx; /*!< Function to transmit via UART. */
|
||||
} terminalCtrlBlk_t;
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Function Prototypes
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Help Command Handler */
|
||||
static uint8_t terminalCommandHelpHandler(uint32_t argc, char **argv);
|
||||
|
||||
/*! \brief Echo Command Handler */
|
||||
static uint8_t terminalCommandEchoHandler(uint32_t argc, char **argv);
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Control block for terminal. */
|
||||
static terminalCtrlBlk_t terminalCb;
|
||||
|
||||
/*! \brief Help command. */
|
||||
static terminalCommand_t terminalCommandHelp = { NULL, "help", "help", terminalCommandHelpHandler };
|
||||
|
||||
/*! \brief Echo command. */
|
||||
static terminalCommand_t terminalCommandEcho = { NULL, "echo", "echo <on|off>", terminalCommandEchoHandler };
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalInit
|
||||
*
|
||||
* \brief Initialize terminal.
|
||||
*
|
||||
* \param handlerId Handler ID for TerminalHandler().
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalInit(wsfHandlerId_t handlerId)
|
||||
{
|
||||
APP_TRACE_INFO0("terminal: init");
|
||||
|
||||
terminalCb.handlerId = handlerId;
|
||||
terminalCb.pFirstCommand = NULL;
|
||||
terminalCb.isExecuting = FALSE;
|
||||
terminalCb.doEcho = TRUE;
|
||||
terminalCb.bufOffset = 0;
|
||||
|
||||
TerminalRegisterCommand(&terminalCommandHelp);
|
||||
TerminalRegisterCommand(&terminalCommandEcho);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalRegisterUartTxFunc
|
||||
*
|
||||
* \brief Register the UART Tx Function for the platform.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalRegisterUartTxFunc(terminalUartTx_t uartTxFunc)
|
||||
{
|
||||
terminalCb.terminalTx = uartTxFunc;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalRegisterCommand
|
||||
*
|
||||
* \brief Register command with terminal.
|
||||
*
|
||||
* \param pCommand Command.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalRegisterCommand(terminalCommand_t *pCommand)
|
||||
{
|
||||
terminalCommand_t *pCommandTemp = terminalCb.pFirstCommand;
|
||||
|
||||
if (pCommandTemp == NULL)
|
||||
{
|
||||
terminalCb.pFirstCommand = pCommand;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (pCommandTemp->pNext != NULL)
|
||||
{
|
||||
pCommandTemp = pCommandTemp->pNext;
|
||||
}
|
||||
|
||||
pCommandTemp->pNext = pCommand;
|
||||
}
|
||||
|
||||
pCommand->pNext = NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn terminalExecute
|
||||
*
|
||||
* \brief Execute a received command.
|
||||
*
|
||||
* \param pBuf Command string.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void terminalExecute(char *pBuf)
|
||||
{
|
||||
uint32_t argc = 0;
|
||||
char *argv[TERMINAL_MAX_ARGC + 1];
|
||||
uint32_t length;
|
||||
char *pBufCur;
|
||||
int state;
|
||||
|
||||
enum
|
||||
{
|
||||
STATE_OUTSIDE_OF_ARG,
|
||||
STATE_JUST_GOT_QUOTE,
|
||||
STATE_INSIDE_OF_ARG,
|
||||
STATE_INSIDE_OF_ARG_IN_QUOTES
|
||||
};
|
||||
|
||||
/* Parse arguments in command */
|
||||
state = STATE_OUTSIDE_OF_ARG;
|
||||
length = strlen(pBuf);
|
||||
for (pBufCur = pBuf; pBufCur < pBuf + length; pBufCur++)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case STATE_OUTSIDE_OF_ARG:
|
||||
{
|
||||
if (*pBufCur == '\"')
|
||||
{
|
||||
state = STATE_JUST_GOT_QUOTE;
|
||||
}
|
||||
else if (!TERMINAL_IS_SPACE(*pBufCur))
|
||||
{
|
||||
state = STATE_INSIDE_OF_ARG;
|
||||
if (argc < TERMINAL_MAX_ARGC)
|
||||
{
|
||||
argv[argc] = pBufCur;
|
||||
}
|
||||
argc++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STATE_JUST_GOT_QUOTE:
|
||||
{
|
||||
if (argc < TERMINAL_MAX_ARGC)
|
||||
{
|
||||
argv[state] = pBufCur;
|
||||
}
|
||||
argc++;
|
||||
if (*pBufCur == '\"')
|
||||
{
|
||||
state = STATE_OUTSIDE_OF_ARG;
|
||||
*pBufCur = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
state = STATE_INSIDE_OF_ARG_IN_QUOTES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STATE_INSIDE_OF_ARG:
|
||||
{
|
||||
if (TERMINAL_IS_SPACE(*pBufCur))
|
||||
{
|
||||
state = STATE_OUTSIDE_OF_ARG;
|
||||
*pBufCur = '\0';
|
||||
}
|
||||
else if (*pBufCur == '\"')
|
||||
{
|
||||
state = STATE_JUST_GOT_QUOTE;
|
||||
*pBufCur = '\0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STATE_INSIDE_OF_ARG_IN_QUOTES:
|
||||
{
|
||||
if (*pBufCur == '\"')
|
||||
{
|
||||
state = STATE_OUTSIDE_OF_ARG;
|
||||
*pBufCur = '\0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Find & invoke command. */
|
||||
if (argc > TERMINAL_MAX_ARGC)
|
||||
{
|
||||
TerminalTxStr(TERMINAL_STRING_ERROR "too many arguments" TERMINAL_STRING_NEW_LINE);
|
||||
}
|
||||
else if (argc > 0)
|
||||
{
|
||||
terminalCommand_t *pCommand = terminalCb.pFirstCommand;
|
||||
|
||||
while (pCommand != NULL)
|
||||
{
|
||||
if (strcmp(pCommand->pName, argv[0]) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pCommand = pCommand->pNext;
|
||||
}
|
||||
|
||||
if (pCommand == NULL)
|
||||
{
|
||||
TerminalTxStr(TERMINAL_STRING_ERROR "unrecognized command \"");
|
||||
TerminalTxStr(argv[0]);
|
||||
TerminalTxStr("\"" TERMINAL_STRING_NEW_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t r = pCommand->handler(argc, argv);
|
||||
switch (r)
|
||||
{
|
||||
case TERMINAL_ERROR_EXEC:
|
||||
case TERMINAL_ERROR_OK:
|
||||
break;
|
||||
case TERMINAL_ERROR_BAD_ARGUMENTS:
|
||||
TerminalTxStr(TERMINAL_STRING_ERROR "Invalid argument(s)" TERMINAL_STRING_NEW_LINE);
|
||||
break;
|
||||
case TERMINAL_ERROR_TOO_FEW_ARGUMENTS:
|
||||
TerminalTxStr(TERMINAL_STRING_ERROR "Too few arguments" TERMINAL_STRING_NEW_LINE);
|
||||
break;
|
||||
case TERMINAL_ERROR_TOO_MANY_ARGUMENTS:
|
||||
TerminalTxStr(TERMINAL_STRING_ERROR "Too many arguments" TERMINAL_STRING_NEW_LINE);
|
||||
break;
|
||||
default:
|
||||
TerminalTxStr(TERMINAL_STRING_ERROR "Unknown error" TERMINAL_STRING_NEW_LINE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalHandler
|
||||
*
|
||||
* \brief Handler for terminal messages.
|
||||
*
|
||||
* \param event WSF event mask.
|
||||
* \param pMsg WSF message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
|
||||
{
|
||||
if ((event & TERMINAL_EVENT_COMMAND_RX) != 0)
|
||||
{
|
||||
terminalExecute(terminalCb.buf);
|
||||
TerminalTxStr(TERMINAL_STRING_PROMPT);
|
||||
terminalCb.bufOffset = 0;
|
||||
terminalCb.isExecuting = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalRx
|
||||
*
|
||||
* \brief Called by application when a data byte is received.
|
||||
*
|
||||
* \param dataByte Received byte.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalRx(uint8_t dataByte)
|
||||
{
|
||||
/* Hands off buf if command is executing. */
|
||||
if (!terminalCb.isExecuting)
|
||||
{
|
||||
/* If this is the end of a line, signal task. */
|
||||
if ((dataByte == '\n') || (dataByte == '\r'))
|
||||
{
|
||||
TerminalTxStr(TERMINAL_STRING_NEW_LINE);
|
||||
terminalCb.buf[terminalCb.bufOffset] = '\0';
|
||||
WsfSetEvent(terminalCb.handlerId, TERMINAL_EVENT_COMMAND_RX);
|
||||
terminalCb.isExecuting = TRUE;
|
||||
}
|
||||
|
||||
/* Check for delete. */
|
||||
else if (dataByte == 0x7F)
|
||||
{
|
||||
if (terminalCb.bufOffset > 0)
|
||||
{
|
||||
terminalCb.bufOffset--;
|
||||
if (terminalCb.doEcho)
|
||||
{
|
||||
TerminalTxStr("\b \b");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we still have room in the buf, put it in buf. Othewise ignore it. */
|
||||
else if (terminalCb.bufOffset < TERMINAL_MAX_COMMAND_LEN)
|
||||
{
|
||||
/* Ignore non-printable characters. */
|
||||
if (TERMINAL_IS_PRINT(dataByte))
|
||||
{
|
||||
terminalCb.buf[terminalCb.bufOffset] = dataByte;
|
||||
terminalCb.bufOffset++;
|
||||
if (terminalCb.doEcho)
|
||||
{
|
||||
TerminalTxChar(dataByte);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalTxStr
|
||||
*
|
||||
* \brief Called by application to transmit string.
|
||||
*
|
||||
* \param pStr String.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalTxStr(const char *pStr)
|
||||
{
|
||||
TerminalTx((const uint8_t *)pStr, strlen(pStr));
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalTxChar
|
||||
*
|
||||
* \brief Called by application to transmit character.
|
||||
*
|
||||
* \param c Character.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalTxChar(char c)
|
||||
{
|
||||
TerminalTx((const uint8_t *)&c, 1);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalTxPrint
|
||||
*
|
||||
* \brief Called by application to print formatted data.
|
||||
*
|
||||
* \param pStr Message format string
|
||||
* \param ... Additional arguments, printf-style
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalTxPrint(const char *pStr, ...)
|
||||
{
|
||||
uint32_t len;
|
||||
char buf[TERMINAL_PRINTF_MAX_LEN];
|
||||
va_list args;
|
||||
|
||||
va_start(args, pStr);
|
||||
len = PrintVsn(buf, TERMINAL_PRINTF_MAX_LEN, pStr, args);
|
||||
va_end(args);
|
||||
|
||||
TerminalTx((uint8_t *)buf, len);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn terminalCommandHelpHandler
|
||||
*
|
||||
* \brief Handler for a terminal command.
|
||||
*
|
||||
* \param argc The number of arguments passed to the command.
|
||||
* \param argv The array of arguments; the 0th argument is the command.
|
||||
*
|
||||
* \return Error code.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t terminalCommandHelpHandler(uint32_t argc, char **argv)
|
||||
{
|
||||
terminalCommand_t *pCommand = terminalCb.pFirstCommand;
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
return TERMINAL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
}
|
||||
|
||||
while (pCommand != NULL)
|
||||
{
|
||||
TerminalTxStr(pCommand->pHelpStr);
|
||||
TerminalTxStr(TERMINAL_STRING_NEW_LINE);
|
||||
|
||||
pCommand = pCommand->pNext;
|
||||
}
|
||||
|
||||
TerminalTxStr(TERMINAL_STRING_NEW_LINE);
|
||||
return TERMINAL_ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalTx
|
||||
*
|
||||
* \brief Transmit buffer on platform UART.
|
||||
*
|
||||
* \param pBuf Buffer to transmit.
|
||||
* \param len Length of buffer in octets.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalTx(const uint8_t *pData, uint16_t len)
|
||||
{
|
||||
WSF_ASSERT(terminalCb.terminalTx);
|
||||
|
||||
(*terminalCb.terminalTx)(pData, len);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn terminalCommandEchoHandler
|
||||
*
|
||||
* \brief Handler for a terminal command.
|
||||
*
|
||||
* \param argc The number of arguments passed to the command.
|
||||
* \param argv The array of arguments; the 0th argument is the command.
|
||||
*
|
||||
* \return Error code.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t terminalCommandEchoHandler(uint32_t argc, char **argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
return TERMINAL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
if (strcmp(argv[1], "on") == 0)
|
||||
{
|
||||
terminalCb.doEcho = TRUE;
|
||||
TerminalTxStr("echo on" TERMINAL_STRING_NEW_LINE);
|
||||
}
|
||||
else if (strcmp(argv[1], "off") == 0)
|
||||
{
|
||||
terminalCb.doEcho = FALSE;
|
||||
TerminalTxStr("echo off" TERMINAL_STRING_NEW_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return TERMINAL_ERROR_BAD_ARGUMENTS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return TERMINAL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
}
|
||||
|
||||
return TERMINAL_ERROR_OK;
|
||||
}
|
||||
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file terminal.h
|
||||
*
|
||||
* \brief Terminal handler.
|
||||
*
|
||||
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
|
||||
* $Revision: 10805 $
|
||||
*
|
||||
* Copyright (c) 2015-2017 ARM Ltd., all rights reserved.
|
||||
* ARM confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef TERMINAL_H
|
||||
#define TERMINAL_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_os.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
#define TERMINAL_MAX_ARGC 8u /*!< Maximum number of arguments to any command. */
|
||||
#define TERMINAL_MAX_COMMAND_LEN 100u /*!< Maximum length of command line. */
|
||||
#define TERMINAL_PRINTF_MAX_LEN 128u /*!< Maximum length of any printed output. */
|
||||
#define TERMINAL_STRING_PROMPT "> " /*!< Prompt string. */
|
||||
#define TERMINAL_STRING_ERROR "ERROR: " /*!< Error prefix. */
|
||||
#define TERMINAL_STRING_USAGE "USAGE: " /*!< Usage prefix. */
|
||||
#define TERMINAL_STRING_NEW_LINE "\r\n" /*!< New line string. */
|
||||
|
||||
/*! \brief Terminal command error codes. */
|
||||
enum
|
||||
{
|
||||
TERMINAL_ERROR_OK = 0, /*!< Command completed. */
|
||||
TERMINAL_ERROR_BAD_ARGUMENTS = 1, /*!< ERROR: Invalid argument(s) */
|
||||
TERMINAL_ERROR_TOO_FEW_ARGUMENTS = 2, /*!< ERROR: Too few arguments */
|
||||
TERMINAL_ERROR_TOO_MANY_ARGUMENTS = 3, /*!< ERROR: Too many arguments */
|
||||
TERMINAL_ERROR_EXEC = 4 /*!< Command completed with execution error. */
|
||||
};
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handler for a terminal command.
|
||||
*
|
||||
* \param argc The number of arguments passed to the command.
|
||||
* \param argv The array of arguments; the 0th argument is the command.
|
||||
*
|
||||
* \return Error code.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
typedef uint8_t (*terminalHandler_t)(uint32_t argc, char **argv);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handler for transmit.
|
||||
*
|
||||
* \param pBuf Buffer to transmit.
|
||||
* \param len Number of bytes to transmit.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
typedef void (*terminalUartTx_t)(const uint8_t *pBuf, uint32_t len);
|
||||
|
||||
/*! \brief Terminal command. */
|
||||
typedef struct terminalCommand_tag
|
||||
{
|
||||
struct terminalCommand_tag *pNext; /*!< Pointer to next command in list. */
|
||||
const char *pName; /*!< Name of command. */
|
||||
const char *pHelpStr; /*!< Help String for command. */
|
||||
terminalHandler_t handler; /*!< Handler for command. */
|
||||
} terminalCommand_t;
|
||||
|
||||
/**************************************************************************************************
|
||||
Function Prototypes
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalInit
|
||||
*
|
||||
* \brief Initialize terminal.
|
||||
*
|
||||
* \param handlerId Handler ID for TerminalHandler().
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalInit(wsfHandlerId_t handlerId);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalRegisterUartTxFunc
|
||||
*
|
||||
* \brief Register the UART Tx Function for the platform.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalRegisterUartTxFunc(terminalUartTx_t uartTxFunc);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalRegisterCommand
|
||||
*
|
||||
* \brief Register command with terminal.
|
||||
*
|
||||
* \param pCommand Command.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalRegisterCommand(terminalCommand_t *pCommand);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalHandler
|
||||
*
|
||||
* \brief Handler for terminal messages.
|
||||
*
|
||||
* \param event WSF event mask.
|
||||
* \param pMsg WSF message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalRx
|
||||
*
|
||||
* \brief Called by application when a data byte is received.
|
||||
*
|
||||
* \param dataByte received byte
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalRx(uint8_t dataByte);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalTxStr
|
||||
*
|
||||
* \brief Called by application to transmit string.
|
||||
*
|
||||
* \param pStr String.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalTxStr(const char *pStr);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalTxChar
|
||||
*
|
||||
* \brief Called by application to transmit character.
|
||||
*
|
||||
* \param c Character.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalTxChar(char c);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalTxPrint
|
||||
*
|
||||
* \brief Called by application to print formatted data.
|
||||
*
|
||||
* \param pStr Message format string
|
||||
* \param ... Additional arguments, printf-style
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalTxPrint(const char *pStr, ...);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn TerminalTx
|
||||
*
|
||||
* \brief Application function to transmit data..
|
||||
*
|
||||
* \param pData Data.
|
||||
* \param len Length of data, in bytes.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TerminalTx(const uint8_t *pData, uint16_t len);
|
||||
|
||||
#endif /* TERMINAL_H */
|
||||
@@ -0,0 +1,98 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wstr.c
|
||||
*
|
||||
* \brief String manipulation functions.
|
||||
*
|
||||
* $Date: 2017-02-14 15:31:43 -0600 (Tue, 14 Feb 2017) $
|
||||
* $Revision: 11184 $
|
||||
*
|
||||
* Copyright (c) 2014-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "wsf_types.h"
|
||||
#include "wstr.h"
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WstrnCpy
|
||||
*
|
||||
* \brief Copy a string and zero out space after the string length.
|
||||
*
|
||||
* \return none.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WstrnCpy(char *pBuf, const char *pData, uint8_t n)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t zeroing = FALSE;
|
||||
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
if (!zeroing && pData[i] == '\0')
|
||||
zeroing = TRUE;
|
||||
|
||||
if (zeroing)
|
||||
*pBuf++ = 0;
|
||||
else
|
||||
*pBuf++ = pData[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WStrReverseCpy
|
||||
*
|
||||
* \brief Byte by byte reverse and copy a buffer.
|
||||
*
|
||||
* \param pBuf1 Buffer to hold reversed copy.
|
||||
* \param pBuf2 Buffer to copy.
|
||||
* \param len Size of pBuf1 and pBuf2 in bytes.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WStrReverseCpy(uint8_t *pBuf1, const uint8_t *pBuf2, uint16_t len)
|
||||
{
|
||||
int16_t i;
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
pBuf1[len-1-i] = pBuf2[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WStrReverse
|
||||
*
|
||||
* \brief Byte by byte reverse a buffer.
|
||||
*
|
||||
* \param pBuf Buffer to reverse.
|
||||
* \param len size of pBuf in bytes.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WStrReverse(uint8_t *pBuf, uint8_t len)
|
||||
{
|
||||
uint8_t i, temp;
|
||||
|
||||
for (i=0; i<len/2; i++)
|
||||
{
|
||||
temp = pBuf[len-i-1];
|
||||
pBuf[len-i-1] = pBuf[i];
|
||||
pBuf[i] = temp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file wstr.h
|
||||
*
|
||||
* \brief String manipulation functions.
|
||||
*
|
||||
* $Date: 2017-02-14 15:31:43 -0600 (Tue, 14 Feb 2017) $
|
||||
* $Revision: 11184 $
|
||||
*
|
||||
* Copyright (c) 2014-2017 ARM Ltd., all rights reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
*
|
||||
* IMPORTANT. Your use of this file is governed by a Software License Agreement
|
||||
* ("Agreement") that must be accepted in order to download or otherwise receive a
|
||||
* copy of this file. You may not use or copy this file for any purpose other than
|
||||
* as described in the Agreement. If you do not agree to all of the terms of the
|
||||
* Agreement do not use this file and delete all copies in your possession or control;
|
||||
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
|
||||
* to any use, copying or further distribution of this software.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef WSTR_H
|
||||
#define WSTR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WstrnCpy
|
||||
*
|
||||
* \brief Copies a string up to a given length.
|
||||
*
|
||||
* \param pBuf Pointer to buffer to copy to.
|
||||
* \param pData Pointer to the string to copy.
|
||||
* \param n Size of pBuf in bytes.
|
||||
*
|
||||
* \return none.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WstrnCpy(char *pBuf, const char *pData, uint8_t n);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WStrReverseCpy
|
||||
*
|
||||
* \brief Byte by byte reverse and copy a buffer.
|
||||
*
|
||||
* \param pBuf1 Buffer to hold reversed copy.
|
||||
* \param pBuf2 Buffer to copy.
|
||||
* \param len Size of pBuf1 and pBuf2 in bytes.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WStrReverseCpy(uint8_t *pBuf1, const uint8_t *pBuf2, uint16_t len);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn WStrReverse
|
||||
*
|
||||
* \brief Byte by byte reverse a buffer.
|
||||
*
|
||||
* \param pBuf Buffer to reverse.
|
||||
* \param len size of pBuf in bytes.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void WStrReverse(uint8_t *pBuf, uint8_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WSTR_H */
|
||||
Reference in New Issue
Block a user