aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-05-20 12:46:24 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-05-20 12:46:24 +0000
commitf4ec81ae144ef2ae7ddd9a0e56082970420c0464 (patch)
treeace4834692e336cf436901b6a2eaf58b8b7a48f7 /os
parent3cfb4077fb27e9ab51bc33d67def962ae68f26c7 (diff)
downloadChibiOS-f4ec81ae144ef2ae7ddd9a0e56082970420c0464.tar.gz
ChibiOS-f4ec81ae144ef2ae7ddd9a0e56082970420c0464.tar.bz2
ChibiOS-f4ec81ae144ef2ae7ddd9a0e56082970420c0464.zip
USB CDC functionality restored, more improvements to the I/O queues.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2983 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/src/serial_usb.c14
-rw-r--r--os/kernel/src/chqueues.c41
2 files changed, 29 insertions, 26 deletions
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index 7fecd5f30..3f53d7df0 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -126,9 +126,8 @@ static void inotify(GenericQueue *qp) {
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
sdup->iqueue.q_counter = n;
- if (notempty(&sdup->iqueue.q_waiting))
+ while (notempty(&sdup->iqueue.q_waiting))
chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
- chSchRescheduleS();
}
}
}
@@ -148,10 +147,9 @@ static void onotify(GenericQueue *qp) {
if (w != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- sdup->oqueue.q_counter = n;
- if (notempty(&sdup->oqueue.q_waiting))
+ sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
+ while (notempty(&sdup->oqueue.q_waiting))
chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK;
- chSchRescheduleS();
}
}
@@ -294,8 +292,8 @@ void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
if (w != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- sdup->oqueue.q_counter = n;
- if (notempty(&sdup->oqueue.q_waiting))
+ sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
+ while (notempty(&sdup->oqueue.q_waiting))
chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
@@ -325,7 +323,7 @@ void sduDataReceived(USBDriver *usbp, usbep_t ep) {
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
sdup->iqueue.q_counter = n;
- if (notempty(&sdup->iqueue.q_waiting))
+ while (notempty(&sdup->iqueue.q_waiting))
chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c
index 767a36e63..8532f8307 100644
--- a/os/kernel/src/chqueues.c
+++ b/os/kernel/src/chqueues.c
@@ -136,8 +136,10 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
*iqp->q_wrptr++ = b;
if (iqp->q_wrptr >= iqp->q_top)
iqp->q_wrptr = iqp->q_buffer;
+
if (notempty(&iqp->q_waiting))
chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK;
+
return Q_OK;
}
@@ -146,6 +148,9 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
* @details This function reads a byte value from an input queue. If the queue
* is empty then the calling thread is suspended until a byte arrives
* in the queue or a timeout occurs.
+ * @note The callback is invoked if the queue is empty before entering the
+ * @p THD_STATE_WTQUEUE state in order to solicit the low level to
+ * start queue filling.
*
* @param[in] iqp pointer to an @p InputQueue structure
* @param[in] time the number of ticks before the operation timeouts,
@@ -192,8 +197,9 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) {
* been reset.
* @note The function is not atomic, if you need atomicity it is suggested
* to use a semaphore or a mutex for mutual exclusion.
- * @note The queue callback is invoked before entering a sleep state and at
- * the end of the transfer.
+ * @note The callback is invoked if the queue is empty before entering the
+ * @p THD_STATE_WTQUEUE state in order to solicit the low level to
+ * start queue filling.
*
* @param[in] iqp pointer to an @p InputQueue structure
* @param[out] bp pointer to the data buffer
@@ -220,6 +226,7 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
while (chIQIsEmptyI(iqp)) {
if (nfy)
nfy(iqp);
+
if (qwait((GenericQueue *)iqp, time) != Q_OK) {
chSysUnlock();
return r;
@@ -230,15 +237,12 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
*bp++ = *iqp->q_rdptr++;
if (iqp->q_rdptr >= iqp->q_top)
iqp->q_rdptr = iqp->q_buffer;
+
chSysUnlock(); /* Gives a preemption chance in a controlled point.*/
r++;
- if (--n == 0) {
- chSysLock();
- if (nfy)
- nfy(iqp);
- chSysUnlock();
+ if (--n == 0)
return r;
- }
+
chSysLock();
}
}
@@ -291,6 +295,8 @@ void chOQResetI(OutputQueue *oqp) {
* @details This function writes a byte value to an output queue. If the queue
* is full then the calling thread is suspended until there is space
* in the queue or a timeout occurs.
+ * @note The callback is invoked after writing the character into the
+ * buffer.
*
* @param[in] oqp pointer to an @p OutputQueue structure
* @param[in] b the byte value to be written in the queue
@@ -350,8 +356,10 @@ msg_t chOQGetI(OutputQueue *oqp) {
b = *oqp->q_rdptr++;
if (oqp->q_rdptr >= oqp->q_top)
oqp->q_rdptr = oqp->q_buffer;
+
if (notempty(&oqp->q_waiting))
chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK;
+
return b;
}
@@ -363,8 +371,8 @@ msg_t chOQGetI(OutputQueue *oqp) {
* been reset.
* @note The function is not atomic, if you need atomicity it is suggested
* to use a semaphore or a mutex for mutual exclusion.
- * @note The queue callback is invoked before entering a sleep state and at
- * the end of the transfer.
+ * @note The callback is invoked after writing each character into the
+ * buffer.
*
* @param[in] oqp pointer to an @p OutputQueue structure
* @param[out] bp pointer to the data buffer
@@ -389,8 +397,6 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp,
chSysLock();
while (TRUE) {
while (chOQIsFullI(oqp)) {
- if (nfy)
- nfy(oqp);
if (qwait((GenericQueue *)oqp, time) != Q_OK) {
chSysUnlock();
return w;
@@ -400,15 +406,14 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp,
*oqp->q_wrptr++ = *bp++;
if (oqp->q_wrptr >= oqp->q_top)
oqp->q_wrptr = oqp->q_buffer;
+
+ if (nfy)
+ nfy(oqp);
+
chSysUnlock(); /* Gives a preemption chance in a controlled point.*/
w++;
- if (--n == 0) {
- chSysLock();
- if (nfy)
- nfy(oqp);
- chSysUnlock();
+ if (--n == 0)
return w;
- }
chSysLock();
}
}