ARM Cordio WSF(二)——API接口

本文开始介绍WSF相关API接口,了解其接口之后便于了解其具体的使用。

2、WSF框架API

2.1 Buffer

WSF缓冲管理服务,基于内存池的动态内存分配服务,相关文件见于:wsf_buf.c/h

c 复制代码
/*! \brief Buffer pool descriptor structure */
typedef struct
{
    uint16_t len; /*!< \brief Length of buffers in pool */
    uint8_t num;  /*!< \brief Number of buffers in pool */
} wsfBufPoolDesc_t;

uint32_t WsfBufInit(uint8_t numPools, wsfBufPoolDesc_t *pDesc);

缓冲池描述结构如上,通过WsfBufInit()进行初始化,确定了buffer的数量,以及每个buffer的长度。
初始化函数仅需要在系统初始化阶段调用一次

实现示例如下:

c 复制代码
//定义 WSF Buffer Pools
#define WSF_BUF_POOLS 5
// Default pool descriptor.
static wsfBufPoolDesc_t poolDescriptors[WSF_BUF_POOLS] = {
    {32, 8}, {64, 4}, {128, 4}, {256, 4}, {1024, 2},
};
//初始化
WsfBufInit(WSF_BUF_POOLS, poolDescriptors);

关于buffer的分配以及释放操作接口:

c 复制代码
/*************************************************************************************************/
/*!
 *  \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);

/*************************************************************************************************/
/*!
 *  \brief  Free a buffer.
 *
 *  \param  pBuf    Buffer to free.
 */
/*************************************************************************************************/
void WsfBufFree(void *pBuf);

2.2 队列

WSF队列服务是一个通用的队列服务,在整个软件系统中被广泛使用。队列服务接口在wsf_queue.h/c中定义与实现。

c 复制代码
/*! \brief Initialize a queue */
#define WSF_QUEUE_INIT(pQueue)  \
    {                           \
        (pQueue)->pHead = NULL; \
        (pQueue)->pTail = NULL; \
    }

/**************************************************************************************************
  Data Types
**************************************************************************************************/

/*! \brief Queue structure */
typedef struct
{
    void *pHead; /*!< \brief head of queue */
    void *pTail; /*!< \brief tail of queue */
} wsfQueue_t;

通过宏WSF_QUEUE_INIT初始化一个队列结构。

队列操作说明:

  • WsfQueueEnq,将一个元素入队到队列的结尾。
  • WsfQueueDeq,从队列的头部取出一个元素。
  • WsfQueuePeek,则仅仅是查看队列头部的元素(并不从队列中出列)。
  • WsfQueuePush,将一个元素入队到队列的头部。
  • WsfQueueInsert,在队列中插入一个元素;
  • WsfQueueRemove,从队列中移除一个元素;
c 复制代码
/*************************************************************************************************/
/*!
 *  \brief  Enqueue an element to the tail of a queue.
 *
 *  \param  pQueue    Pointer to queue.
 *  \param  pElem     Pointer to element.
 */
/*************************************************************************************************/
void WsfQueueEnq(wsfQueue_t *pQueue, void *pElem);

/*************************************************************************************************/
/*!
 *  \brief  Peek 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 *WsfQueuePeek(wsfQueue_t *pQueue);

/*************************************************************************************************/
/*!
 *  \brief  Dequeue an 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);

/*************************************************************************************************/
/*!
 *  \brief  Push an element to the head of a queue.
 *
 *  \param  pQueue    Pointer to queue.
 *  \param  pElem     Pointer to element.
 */
/*************************************************************************************************/
void WsfQueuePush(wsfQueue_t *pQueue, void *pElem);

/*************************************************************************************************/
/*!
 *  \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);

/*************************************************************************************************/
/*!
 *  \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.
 */
/*************************************************************************************************/
void WsfQueueRemove(wsfQueue_t *pQueue, void *pElem, void *pPrev);

2.3 消息

WSF消息服务用于在WSF事件处理中传递消息,定义:wsf_msg.h/c

消息缓存分配WsfMsgAlloc,发送通过:WsfMsgSend,发送到事件处理器。

数据消息缓存分配使用WsfMsgDataAlloc,发送依然使用:WsfMsgSend

c 复制代码
/*************************************************************************************************/
/*!
 *  \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);

/*************************************************************************************************/
/*!
 *  \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);

/*************************************************************************************************/
/*!
 *  \brief  Free a message buffer allocated with WsfMsgAlloc().
 *
 *  \param  pMsg  Pointer to message buffer.
 */
/*************************************************************************************************/
void WsfMsgFree(void *pMsg);

/*************************************************************************************************/
/*!
 *  \brief  Send a message to an event handler.
 *
 *  \param  handlerId   Event handler ID.
 *  \param  pMsg        Pointer to message buffer.
 */
/*************************************************************************************************/
void WsfMsgSend(wsfHandlerId_t handlerId, void *pMsg);

消息与队列的结合:

c 复制代码
/*************************************************************************************************/
/*!
 *  \brief  Enqueue a message.
 *
 *  \param  pQueue     Pointer to queue.
 *  \param  handlerId  Set message handler ID to this value.
 *  \param  pMsg       Pointer to message buffer.
 */
/*************************************************************************************************/
void WsfMsgEnq(wsfQueue_t *pQueue, wsfHandlerId_t handlerId, void *pMsg);

/*************************************************************************************************/
/*!
 *  \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);

/*************************************************************************************************/
/*!
 *  \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);

2.4 定时器

WSF定时器服务由WSF事件处理使用。

当定时器超时,相应关联的事件处理器将执行。

c 复制代码
/*! \brief Timer ticks data type */
typedef uint32_t wsfTimerTicks_t;

/*! \brief Timer structure */
typedef struct wsfTimer_tag
{
    struct wsfTimer_tag *pNext; /*!< \brief pointer to next timer in queue */
    wsfMsgHdr_t msg;            /*!< \brief application-defined timer event parameters */
    wsfTimerTicks_t ticks;      /*!< \brief number of ticks until expiration */
    uint32_t count;
    uint8_t mode;             /*!< \brief one shot or periodic */
    wsfHandlerId_t handlerId; /*!< \brief event handler for this timer */
    bool_t isStarted;         /*!< \brief TRUE if timer has been started */
} wsfTimer_t;

void WsfTimerInit(void);

void WsfTimerInit(void);初始化timer服务,仅在系统初始化阶段调用一次

Wsf支持秒级定时器与毫秒级的定时器,定时器启动与停止:

  • WsfTimerStartSec
  • WsfTimerStartMs
  • WsfTimerStop(wsfTimer_t *pTimer)

void WsfTimerUpdate(wsfTimerTicks_t ticks);用于更新定时器服务的tick,通常需要在定时器移植代码中调用。

c 复制代码
/*************************************************************************************************/
/*!
 *  \brief  Service expired timers for the given task.  This function is typically called only
 *          WSF OS porting code.
 *
 *  \param  taskId      OS Task ID of task servicing timers.
 *
 *  \return Pointer to next expired timer or NULL if there are no expired timers.
 */
/*************************************************************************************************/
wsfTimer_t *WsfTimerServiceExpired(wsfTaskId_t taskId);

特定任务定时器服务超期,参数为OS Task ID。返回下一超时定时器指针,或NULL(无超时定时器)。

c 复制代码
/*************************************************************************************************/
/*!
 *  \brief      Check if there is an active timer and if there is enough time to
 *              go to sleep.
 */
/*************************************************************************************************/
uint8_t WsfTimerSleepCheck(uint32_t *sleep_ms);

// 基于RTC ticks更新WSF定时器
void WsfTimerSleepUpdate(void);

检查是否有活跃定时器,以及是否有足够时间进行休眠。

2.5 事件处理程序

WSF事件处理程序从软件系统中接收WSF事件、消息、以及定时器超时通知。事件处理程序被协议栈的主要子系统使用。事件处理程序的接口在wsf_os.h文件中定义。

相关数据类型:

c 复制代码
/*! \brief Event handler ID data type */
typedef uint8_t wsfHandlerId_t;

/*! \brief Event handler event mask data type */
typedef uint16_t wsfEventMask_t;

/*! \brief Task ID data type */
typedef wsfHandlerId_t wsfTaskId_t;

/*! \brief Task event mask data type */
typedef uint8_t wsfTaskEvent_t;

/*! \brief      Idle check function. */
typedef bool_t (*WsfOsIdleCheckFunc_t)(void);

事件处理程序通用消息结构。

c 复制代码
/*! \brief Common message structure passed to event handler */
typedef struct
{
    uint16_t param; /*!< \brief General purpose parameter passed to event handler */
    uint8_t event;  /*!< \brief General purpose event value passed to event handler */
    uint8_t status; /*!< \brief General purpose status value passed to event handler */
} wsfMsgHdr_t;

事件处理回调函数:

c 复制代码
/*************************************************************************************************/
/*!
 *  \brief  Event handler callback function.
 *
 *  \param  event    Mask of events set for the event handler.
 *  \param  pMsg     Pointer to message for the event handler.
 */
/*************************************************************************************************/
typedef void (*wsfEventHandler_t)(wsfEventMask_t event, const void *pMsg);

为时间处理程序设置一个事件:void WsfSetEvent(wsfHandlerId_t handlerId, wsfEventMask_t event);

对于任务调度Locking,WSF提供了任务调度的锁定和解锁接口,这使得在抢占式多任务环境中可以进行操作:

c 复制代码
/*************************************************************************************************/
/*!
 *  \brief  Lock task scheduling.
 */
/*************************************************************************************************/
uint32_t WsfTaskLock(void);

/*************************************************************************************************/
/*!
 *  \brief  Unlock task scheduling.
 */
/*************************************************************************************************/
void WsfTaskUnlock(uint32_t lock);

2.6 关键区(Critical Section)

WSF提供了关键区域宏,用于在可能在中断上下文中执行的代码中保护全局数据。Critical Section的相关接口在wsf_cs.h中定义。

c 复制代码
#define WSF_CS_INIT(cs)

#define WSF_CS_ENTER(cs)       WsfCsEnter()
#define WSF_CS_EXIT(cs)        WsfCsExit()

其中,关于Critical Section的实现,需要结合使用平台处理器的特性进行修改,如进入CS,关闭全局中断等操作。

2.7 NVM

提供NVM操作接口。可用于在NVM中存储的数据,实现本地数据直接加载。需要使用pal_flash.c/h相关接口,进行平台适配。

c 复制代码
typedef void (*WsfNvmCompEvent_t)(bool_t status);

//初始化WSF NVM
void WsfNvmInit(void);

bool_t WsfNvmReadData(uint64_t id, uint8_t *pData, uint16_t len, WsfNvmCompEvent_t compCback);
bool_t WsfNvmWriteData(uint64_t id, const uint8_t *pData, uint16_t len, WsfNvmCompEvent_t compCback);
bool_t WsfNvmEraseData(uint64_t id, WsfNvmCompEvent_t compCback);
相关推荐
钡铼技术1 小时前
通过iFIX在ARMxy边缘计算网关上实现维护管理
人工智能·物联网·边缘计算·钡铼技术·armxy边缘计算网关
华清远见IT开放实验室4 小时前
【项目案例】物联网比较好的10+练手项目推荐,附项目文档/源码/视频
物联网·音视频
limingade4 小时前
手机实时提取SIM卡打电话的信令和声音-新的篇章(一、可行的方案探讨)
物联网·算法·智能手机·数据分析·信息与通信
傻傻虎虎10 小时前
【系统架构设计】信息系统基础知识
系统架构
有颜有货11 小时前
低代码开发平台系统架构概述
低代码·系统架构
z2014z11 小时前
系统架构设计师教程 第5章 5.3 系统分析与设计 笔记
笔记·系统架构
思为无线NiceRF11 小时前
全双工多路并发、低延时数传解决行业信号拥堵问题
物联网
h1771134720514 小时前
基于区块链的相亲交易系统源码解析
大数据·人工智能·安全·系统架构·交友
辣香牛肉面15 小时前
十三 系统架构设计(考点篇)
系统架构
东华果汁哥18 小时前
【嵌入式人工智能】嵌入式AI在物联网中如何应用
人工智能·物联网