|
发表于 2013-1-11 13:13:05
|
显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-1-12 18:34 编辑
顶啊~我也粘贴一个,捧个场
- /***************************************************************************
- * Copyright(C)2009-2012 by Gorgon Meducer<Embedded_zhuoran@hotmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2 of the *
- * License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
- #ifndef _USE_TEMPLATE_QUEUE_H_
- #define _USE_TEMPLATE_QUEUE_H_
- /*============================ INCLUDES ======================================*/
- /*============================ MACROS ========================================*/
- #define END_DEF_QUEUE
- #define END_DEF_QUEUE_U8
- #define END_DEF_QUEUE_U16
- #define END_DEF_QUEUE_U32
- #define END_DEF_SAFE_QUEUE
- #define END_DEF_SAFE_QUEUE_U8
- #define END_DEF_SAFE_QUEUE_U16
- #define END_DEF_SAFE_QUEUE_U32
- /*============================ MACROFIED FUNCTIONS ===========================*/
- #define NONE_ATOM_ACCESS(__CODE) {__CODE;}
- #define QUEUE_MUTEX(__NAME, __QUEUE) \
- __NAME##_queue_mutex(__QUEUE)
- #define QUEUE_INIT(__NAME, __QUEUE, __BUFFER, __SIZE) \
- __NAME##_queue_init((__QUEUE), (__BUFFER), (__SIZE))
- #define DEQUEUE(__NAME, __QUEUE, __ADDR) \
- __NAME##_dequeue((__QUEUE),(__ADDR))
- #define ENQUEUE(__NAME, __QUEUE, __VALUE) \
- __NAME##_enqueue((__QUEUE), (__VALUE))
- #define PEEK_QUEUE(__NAME, __QUEUE, __ADDR) \
- __NAME##_queue_peek((__QUEUE),(__ADDR))
- #define QUEUE(__NAME) __NAME##_queue_t
- #define DEF_QUEUE_EX(__NAME, __TYPE, __PTR_TYPE, __MUTEX_TYPE, __ATOM_ACCESS) \
- DEF_CLASS \
- __TYPE *ptBuffer; \
- __PTR_TYPE tSize; \
- __PTR_TYPE tHead; \
- __PTR_TYPE tTail; \
- __PTR_TYPE tCounter; \
- __MUTEX_TYPE tMutex; \
- END_DEF_CLASS(__NAME##_queue_t) \
- \
- __MUTEX_TYPE *__NAME##_queue_mutex(__NAME##_queue_t *ptQueue) \
- { \
- CLASS(__NAME##_queue_t) *ptQ = (CLASS(__NAME##_queue_t) *)ptQueue; \
- if ( NULL == ptQueue) { \
- return NULL; \
- } \
- return &(ptQ->tMutex); \
- } \
- \
- bool __NAME##_queue_init(__NAME##_queue_t *ptQueue, __TYPE *ptBuffer, __PTR_TYPE tSize) \
- { \
- CLASS(__NAME##_queue_t) *ptQ = (CLASS(__NAME##_queue_t) *)ptQueue; \
- if (NULL == ptQueue || NULL == ptBuffer || 0 == tSize) { \
- return false; \
- } \
- \
- ptQ->ptBuffer = ptBuffer; \
- ptQ->tSize = tSize; \
- ptQ->tHead = 0; \
- ptQ->tTail = 0; \
- ptQ->tCounter = 0; \
- \
- return true; \
- } \
- \
- bool __NAME##_enqueue(__NAME##_queue_t *ptQueue, __TYPE tObj) \
- { \
- bool bResult = false; \
- CLASS(__NAME##_queue_t) *ptQ = (CLASS(__NAME##_queue_t) *)ptQueue; \
- if (NULL == ptQ) { \
- return false; \
- } \
- \
- __ATOM_ACCESS( \
- do { \
- if ((ptQ->tHead == ptQ->tTail) && (0 != ptQ->tCounter)) { \
- break; \
- } \
- \
- ptQ->ptBuffer[ptQ->tTail++] = tObj; \
- if (ptQ->tTail >= ptQ->tSize) { \
- ptQ->tTail = 0; \
- } \
- ptQ->tCounter++; \
- bResult = true; \
- } while (false); \
- ) \
- \
- return bResult; \
- } \
- \
- bool __NAME##_queue_peek(__NAME##_queue_t *ptQueue, __TYPE *ptObj) \
- { \
- bool bResult = false; \
- CLASS(__NAME##_queue_t) *ptQ = (CLASS(__NAME##_queue_t) *)ptQueue; \
- if (NULL == ptQ) { \
- return false; \
- } \
- \
- __ATOM_ACCESS( \
- do { \
- if ((ptQ->tHead == ptQ->tTail) && (!ptQ->tCounter)) { \
- break; \
- } \
- if (NULL != ptObj) { \
- *ptObj = ptQ->ptBuffer[ptQ->tHead]; \
- } \
- bResult = true; \
- } while (false); \
- ) \
- \
- return bResult; \
- } \
- bool __NAME##_dequeue(__NAME##_queue_t *ptQueue, __TYPE *ptObj) \
- { \
- bool bResult = false; \
- CLASS(__NAME##_queue_t) *ptQ = (CLASS(__NAME##_queue_t) *)ptQueue; \
- if (NULL == ptQ) { \
- return false; \
- } \
- \
- __ATOM_ACCESS( \
- do { \
- if ((ptQ->tHead == ptQ->tTail) && (!ptQ->tCounter)) { \
- break; \
- } \
- if (NULL != ptObj) { \
- *ptObj = ptQ->ptBuffer[ptQ->tHead]; \
- } \
- ptQ->tHead++; \
- if (ptQ->tHead >= ptQ->tSize) { \
- ptQ->tHead = 0; \
- } \
- ptQ->tCounter--; \
- bResult = true; \
- } while (false); \
- ) \
- \
- return bResult; \
- } \
- #define DEF_SAFE_QUEUE(__NAME, __TYPE, __PTR_TYPE, __MUTEX_TYPE) \
- DEF_QUEUE_EX(__NAME, __TYPE, __PTR_TYPE, __MUTEX_TYPE, SAFE_ATOM_CODE)
- #define DEF_SAFE_QUEUE_U8(__NAME, __PTR_TYPE,__MUTEX_TYPE) \
- DEF_SAFE_QUEUE(__NAME, uint8_t, __PTR_TYPE, __MUTEX_TYPE)
- #define DEF_SAFE_QUEUE_U16(__NAME, __PTR_TYPE, __MUTEX_TYPE) \
- DEF_SAFE_QUEUE(__NAME, uint16_t, __PTR_TYPE, __MUTEX_TYPE)
- #define DEF_SAFE_QUEUE_U32(__NAME, __PTR_TYPE, __MUTEX_TYPE) \
- DEF_SAFE_QUEUE(__NAME, uint32_t __PTR_TYPE, __MUTEX_TYPE)
- #define DEF_QUEUE(__NAME, __TYPE, __PTR_TYPE, __MUTEX_TYPE) \
- DEF_QUEUE_EX(__NAME, __TYPE, __PTR_TYPE, __MUTEX_TYPE, NONE_ATOM_ACCESS)
- #define DEF_QUEUE_U8(__NAME, __PTR_TYPE,__MUTEX_TYPE) \
- DEF_QUEUE(__NAME, uint8_t, __PTR_TYPE, __MUTEX_TYPE)
- #define DEF_QUEUE_U16(__NAME, __PTR_TYPE, __MUTEX_TYPE) \
- DEF_QUEUE(__NAME, uint16_t, __PTR_TYPE, __MUTEX_TYPE)
- #define DEF_QUEUE_U32(__NAME, __PTR_TYPE, __MUTEX_TYPE) \
- DEF_QUEUE(__NAME, uint32_t __PTR_TYPE, __MUTEX_TYPE)
- /*============================ TYPES =========================================*/
- /*============================ GLOBAL VARIABLES ==============================*/
- /*============================ LOCAL VARIABLES ===============================*/
- /*============================ PROTOTYPES ====================================*/
- /*============================ IMPLEMENTATION ================================*/
- #endif
复制代码 支撑宏
- #define EXTERN_CLASS typedef struct {\
- uint8_t chMask[sizeof(struct {
- #define END_EXTERN_CLASS(__NAME) })];\
- }__NAME;
- #define DEF_CLASS typedef struct {
- #define END_DEF_CLASS(__NAME) }__##__NAME;\
- typedef struct {\
- uint8_t chMask[sizeof(__##__NAME)];\
- }__NAME;
- #define CLASS(__NAME) __##__NAME
- ...
- #define PRIVATE static
- //! 以IAR为例子
- #define NO_INIT __no_init
复制代码
使用范例:
- /*============================ TYPES =========================================*/
- //! 定义了一个专门的byte队列类型,这个队列用uint16_t作为计数器类型,所以,可以处理0~65535个元素, 用bool作为临界区变量类型
- DEF_SAFE_QUEUE_U8(byte_queue, uint16_t, bool)
- END_DEF_SAFE_QUEUE_U8
- /*============================ GLOBAL VARIABLES ==============================*/
- /*============================ LOCAL VARIABLES ===============================*/
- /*! 用刚刚定义的新类型byte_queue来定义一个队列s_tBLQIn, 这里s表示static,说明变量是静态的,_t表示这是自定义数据类
- 型, BL是Bootloader的缩写, Q是Queue的缩写 In表示这是一个输入队列
- */
- NO_INIT PRIVATE QUEUE(byte_queue) s_tBLQIn;
- //! 这是它的缓冲
- NO_INIT PRIVATE uint8_t s_chInBuffer[256];
- //! 用刚刚定义的新类型byte_queue来定义一个队列s_BLQOut;
- NO_INIT PRIVATE QUEUE(byte_queue) s_tBLQOut;
- //! 这是它的缓冲
- NO_INIT PRIVATE uint8_t s_chOutBuffer[64];
- //! 用两个队列,In和Out封装成一个管道pipe, 后面的两个函数是管道的一端,
- static bool pipe_out_write_byte(vsf_uint8_t chByte)
- {
- return ENQUEUE(byte_queue, &s_tBLQOut, chByte);
- }
- static bool pipe_in_read_byte(uint8_t *pchByte)
- {
- return DEQUEUE(byte_queue, &s_tBLQIn, pchByte);
- }
- /*! \note initialize application
- * \param none
- * \retval true hal initialization succeeded.
- * \retval false hal initialization failed
- */
- ROOT bool app_init(void)
- {
- ...
- //! 初始化两个队列,没啥好说的
- QUEUE_INIT(byte_queue, &s_tBLQIn, s_chInBuffer, sizeof(s_chInBuffer));
- QUEUE_INIT(byte_queue, &s_tBLQOut, s_chOutBuffer, sizeof(s_chOutBuffer));
- ...
- }
- /*! 这是一个不折不扣如何使用队列的例子,亮点是 ENAQUEUE, PEEK_QUEUE和DEQUEUE, SERIAL_IN
- 和SERIAL_OUT是串行输入输出设备的接口,你直接认为是串口就好了
- */
- ...
- PRIVATE STATE(BootLoader_Task) BEGIN
- do {
- uint8_t chByte;
- if (SERIAL_IN(&chByte)) {
- ENQUEUE(byte_queue, &s_tBLQIn, chByte);
- }
- } while (false);
- do {
- uint8_t chByte;
- if (PEEK_QUEUE(byte_queue, &s_tBLQOut, &chByte)) {
- if (SERIAL_OUT(chByte)) {
- DEQUEUE(byte_queue, &s_tBLQOut, &chByte);
- }
- }
- } while (false);
- ...
- REFLEXIVE_STATE;
- END
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|