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
This commit is contained in:
gdisirio 2011-05-20 12:46:24 +00:00
parent 3cfb4077fb
commit f4ec81ae14
3 changed files with 31 additions and 26 deletions

View File

@ -126,9 +126,8 @@ static void inotify(GenericQueue *qp) {
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE); chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer; sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
sdup->iqueue.q_counter = n; 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; 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) { if (w != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY); chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer; sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
sdup->oqueue.q_counter = n; sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
if (notempty(&sdup->oqueue.q_waiting)) while (notempty(&sdup->oqueue.q_waiting))
chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK; 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) { if (w != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY); chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer; sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
sdup->oqueue.q_counter = n; sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
if (notempty(&sdup->oqueue.q_waiting)) while (notempty(&sdup->oqueue.q_waiting))
chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK; 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); chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer; sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
sdup->iqueue.q_counter = n; 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; chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
} }
} }

View File

@ -136,8 +136,10 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
*iqp->q_wrptr++ = b; *iqp->q_wrptr++ = b;
if (iqp->q_wrptr >= iqp->q_top) if (iqp->q_wrptr >= iqp->q_top)
iqp->q_wrptr = iqp->q_buffer; iqp->q_wrptr = iqp->q_buffer;
if (notempty(&iqp->q_waiting)) if (notempty(&iqp->q_waiting))
chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK; chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK;
return 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 * @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 * is empty then the calling thread is suspended until a byte arrives
* in the queue or a timeout occurs. * 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] iqp pointer to an @p InputQueue structure
* @param[in] time the number of ticks before the operation timeouts, * @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. * been reset.
* @note The function is not atomic, if you need atomicity it is suggested * @note The function is not atomic, if you need atomicity it is suggested
* to use a semaphore or a mutex for mutual exclusion. * to use a semaphore or a mutex for mutual exclusion.
* @note The queue callback is invoked before entering a sleep state and at * @note The callback is invoked if the queue is empty before entering the
* the end of the transfer. * @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] iqp pointer to an @p InputQueue structure
* @param[out] bp pointer to the data buffer * @param[out] bp pointer to the data buffer
@ -220,6 +226,7 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
while (chIQIsEmptyI(iqp)) { while (chIQIsEmptyI(iqp)) {
if (nfy) if (nfy)
nfy(iqp); nfy(iqp);
if (qwait((GenericQueue *)iqp, time) != Q_OK) { if (qwait((GenericQueue *)iqp, time) != Q_OK) {
chSysUnlock(); chSysUnlock();
return r; return r;
@ -230,15 +237,12 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
*bp++ = *iqp->q_rdptr++; *bp++ = *iqp->q_rdptr++;
if (iqp->q_rdptr >= iqp->q_top) if (iqp->q_rdptr >= iqp->q_top)
iqp->q_rdptr = iqp->q_buffer; iqp->q_rdptr = iqp->q_buffer;
chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ chSysUnlock(); /* Gives a preemption chance in a controlled point.*/
r++; r++;
if (--n == 0) { if (--n == 0)
chSysLock();
if (nfy)
nfy(iqp);
chSysUnlock();
return r; return r;
}
chSysLock(); chSysLock();
} }
} }
@ -291,6 +295,8 @@ void chOQResetI(OutputQueue *oqp) {
* @details This function writes a byte value to an output queue. If the queue * @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 * is full then the calling thread is suspended until there is space
* in the queue or a timeout occurs. * 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] oqp pointer to an @p OutputQueue structure
* @param[in] b the byte value to be written in the queue * @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++; b = *oqp->q_rdptr++;
if (oqp->q_rdptr >= oqp->q_top) if (oqp->q_rdptr >= oqp->q_top)
oqp->q_rdptr = oqp->q_buffer; oqp->q_rdptr = oqp->q_buffer;
if (notempty(&oqp->q_waiting)) if (notempty(&oqp->q_waiting))
chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK; chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK;
return b; return b;
} }
@ -363,8 +371,8 @@ msg_t chOQGetI(OutputQueue *oqp) {
* been reset. * been reset.
* @note The function is not atomic, if you need atomicity it is suggested * @note The function is not atomic, if you need atomicity it is suggested
* to use a semaphore or a mutex for mutual exclusion. * to use a semaphore or a mutex for mutual exclusion.
* @note The queue callback is invoked before entering a sleep state and at * @note The callback is invoked after writing each character into the
* the end of the transfer. * buffer.
* *
* @param[in] oqp pointer to an @p OutputQueue structure * @param[in] oqp pointer to an @p OutputQueue structure
* @param[out] bp pointer to the data buffer * @param[out] bp pointer to the data buffer
@ -389,8 +397,6 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp,
chSysLock(); chSysLock();
while (TRUE) { while (TRUE) {
while (chOQIsFullI(oqp)) { while (chOQIsFullI(oqp)) {
if (nfy)
nfy(oqp);
if (qwait((GenericQueue *)oqp, time) != Q_OK) { if (qwait((GenericQueue *)oqp, time) != Q_OK) {
chSysUnlock(); chSysUnlock();
return w; return w;
@ -400,15 +406,14 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp,
*oqp->q_wrptr++ = *bp++; *oqp->q_wrptr++ = *bp++;
if (oqp->q_wrptr >= oqp->q_top) if (oqp->q_wrptr >= oqp->q_top)
oqp->q_wrptr = oqp->q_buffer; oqp->q_wrptr = oqp->q_buffer;
chSysUnlock(); /* Gives a preemption chance in a controlled point.*/
w++;
if (--n == 0) {
chSysLock();
if (nfy) if (nfy)
nfy(oqp); nfy(oqp);
chSysUnlock();
chSysUnlock(); /* Gives a preemption chance in a controlled point.*/
w++;
if (--n == 0)
return w; return w;
}
chSysLock(); chSysLock();
} }
} }

View File

@ -95,6 +95,8 @@
reimplemented as a port-specific option. reimplemented as a port-specific option.
- CHANGE: chiQGetFullI() and chOQGetFullI() become macros. The queues - CHANGE: chiQGetFullI() and chOQGetFullI() become macros. The queues
subsystem has been optimized and is no more dependent on semaphores. subsystem has been optimized and is no more dependent on semaphores.
Note that the queues callbacks invocation policy has been slightly
changed, see the documentation.
*** 2.3.2 *** *** 2.3.2 ***
- FIX: Fixed invalid BRR() macro in AVR serial driver (bug 3299306)(backported - FIX: Fixed invalid BRR() macro in AVR serial driver (bug 3299306)(backported