ChibiOS/src/include/queues.h

185 lines
5.6 KiB
C

/*
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT 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 General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @addtogroup IOQueues
* @{
*/
#ifndef _QUEUES_H_
#define _QUEUES_H_
/** Queue notification callback type.*/
typedef void (*t_qnotify)(void);
/** Returned by the queue functions if the operation is successful.*/
#define Q_OK RDY_OK
/** Returned by the queue functions if a timeout occurs.*/
#define Q_TIMEOUT RDY_TIMEOUT
/** Returned by the queue functions if the queue is reset.*/
#define Q_RESET RDY_RESET
/** Returned by the queue functions if the queue is empty.*/
#define Q_EMPTY -3
/** Returned by the queue functions if the queue is full.*/
#define Q_FULL -4
#ifdef CH_USE_QUEUES
/**
* I/O queue structure, it is used by both Input and Output Queues,
* the difference is on how the semaphore is initialized.
*/
typedef struct {
/** Pointer to the queue buffer.*/
BYTE8 *q_buffer;
/** Pointer to the first location after the buffer.*/
BYTE8 *q_top;
/** Write pointer.*/
BYTE8 *q_wrptr;
/** Read pointer.*/
BYTE8 *q_rdptr;
/** Counter semaphore.*/
Semaphore q_sem;
/** Data notification callback.*/
t_qnotify q_notify;
} Queue;
/** Returns the queue's buffer size.*/
#define chQSize(q) \
((q)->q_top - (q)->q_buffer)
/** Returns the used space if used on an Input Queue and the empty space if
* used on an Output Queue.*/
#define chQSpace(q) \
((q)->q_sem.s_cnt)
/** Evaluates to TRUE if the specified Input Queue is empty.*/
#define chIQIsEmpty(q) \
(chQSpace(q) <= 0)
/** Evaluates to TRUE if the specified Input Queue is full.*/
#define chIQIsFull(q) \
(chQSpace(q) >= chQSize(q))
/** Evaluates to TRUE if the specified Output Queue is empty.*/
#define chOQIsEmpty(q) \
(chQSpace(q) >= chQSize(q))
/** Evaluates to TRUE if the specified Output Queue is full.*/
#define chOQIsFull(q) \
(chQSpace(q) <= 0)
#ifdef __cplusplus
extern "C" {
#endif
/*
* Input Queues functions. An Input Queue is usually written into by an
* interrupt handler and read from a thread.
*/
void chIQInit(Queue *qp, BYTE8 *buffer, t_size size, t_qnotify inotify);
void chIQReset(Queue *qp);
t_msg chIQPutI(Queue *qp, BYTE8 b);
t_msg chIQGet(Queue *qp);
t_size chIQRead(Queue *qp, BYTE8 *buffer, t_size n);
#ifdef CH_USE_QUEUES_TIMEOUT
t_msg chIQGetTimeout(Queue *qp, t_time time);
#endif
/*
* Output Queues functions. An Output Queue is usually written into by a
* thread and read from an interrupt handler.
*/
void chOQInit(Queue *queue, BYTE8 *buffer, t_size size, t_qnotify onotify);
void chOQReset(Queue *queue);
void chOQPut(Queue *queue, BYTE8 b);
t_msg chOQGetI(Queue *queue);
t_size chOQWrite(Queue *queue, BYTE8 *buffer, t_size n);
#ifdef __cplusplus
}
#endif
#endif /* CH_USE_QUEUES */
#ifdef CH_USE_QUEUES_HALFDUPLEX
/**
* Half duplex queue structure.
*/
typedef struct {
/** Pointer to the queue buffer.*/
BYTE8 *hdq_buffer;
/** Pointer to the first location after the buffer.*/
BYTE8 *hdq_top;
/** Write pointer.*/
BYTE8 *hdq_wrptr;
/** Read pointer.*/
BYTE8 *hdq_rdptr;
/** Input counter semaphore.*/
Semaphore hdq_isem;
/** Output counter semaphore.*/
Semaphore hdq_osem;
/** Input data notification callback.*/
t_qnotify hdq_inotify;
/** Output data notification callback.*/
t_qnotify hdq_onotify;
} HalfDuplexQueue;
/** Returns the queue's buffer size.*/
#define chHDQSize(q) \
((q)->hdq_top - (q)->hdq_buffer)
/** Returns the queue space when in transmission mode.*/
#define chHDQEmptySpace(q) \
((q)->hdq_osem.s_cnt)
/** Returns the number of the bytes in the queue when in receive mode.*/
#define chHDQFilledSpace(q) \
((q)->hdq_isem.s_cnt)
/** Evaluates to TRUE if the queue is in transmit mode.*/
#define chHDQIsTransmitting(q) \
(chHDQEmptySpace(q) < chHDQSize(q))
/** Evaluates to TRUE if the queue is in receive mode.*/
#define chHDQIsReceiving(q) \
(chHDQEmptySpaceQ(q) >= chHDQSize(q))
/** Evaluates to TRUE if the receive queue is full.*/
#define chHDQIsFullReceive(q) \
(chHDQFilledSpace(q) >= chHDQSize(q))
#ifdef __cplusplus
extern "C" {
#endif
void chHDQInit(HalfDuplexQueue *qp, BYTE8 *buffer, t_size size,
t_qnotify inotify, t_qnotify onotify);
t_msg chHDQGetReceive(HalfDuplexQueue *qp);
void chHDQPutTransmit(HalfDuplexQueue *qp, BYTE8 b);
t_msg chHDQGetTransmitI(HalfDuplexQueue *qp);
t_msg chHDQPutReceiveI(HalfDuplexQueue *qp, BYTE8 b);
#ifdef CH_USE_QUEUES_TIMEOUT
t_msg chHDQGetReceiveTimeout(HalfDuplexQueue *qp, t_time time);
#endif
#ifdef __cplusplus
}
#endif
#endif /* CH_USE_QUEUES_HALFDUPLEX */
#endif /* _QUEUES_H_ */
/** @} */