大家好,欢迎来到IT知识分享网。
本文开始介绍WSF相关API接口,了解其接口之后便于了解其具体的使用。
2、WSF框架API
2.1 Buffer
WSF缓冲管理服务,基于内存池的动态内存分配服务,相关文件见于:wsf_buf.c/h
。
/*! \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的长度。
初始化函数仅需要在系统初始化阶段调用一次。
实现示例如下:
//定义 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的分配以及释放操作接口:
/*/ /*! * \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
中定义与实现。
/*! \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
,从队列中移除一个元素;
/*/ /*! * \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
。
/*/ /*! * \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);
消息与队列的结合:
/*/ /*! * \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 定时器
/*! \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,通常需要在定时器移植代码中调用。
/*/ /*! * \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(无超时定时器)。
/*/ /*! * \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
文件中定义。
相关数据类型:
/*! \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);
事件处理程序通用消息结构。
/*! \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;
事件处理回调函数:
/*/ /*! * \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提供了任务调度的锁定和解锁接口,这使得在抢占式多任务环境中可以进行操作:
/*/ /*! * \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
中定义。
#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
相关接口,进行平台适配。
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);
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/141206.html