aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
Diffstat (limited to 'os')
-rw-r--r--os/hal/src/serial_usb.c39
-rw-r--r--os/kernel/include/chsem.h2
-rw-r--r--os/kernel/src/chsem.c25
3 files changed, 32 insertions, 34 deletions
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index b6ad10c13..bc2c39426 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -59,44 +59,44 @@ static cdc_linecoding_t linecoding = {
static size_t writes(void *ip, const uint8_t *bp, size_t n) {
- return chOQWriteTimeout(&((SerialDriver *)ip)->oqueue, bp,
+ return chOQWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp,
n, TIME_INFINITE);
}
static size_t reads(void *ip, uint8_t *bp, size_t n) {
- return chIQReadTimeout(&((SerialDriver *)ip)->iqueue, bp,
+ return chIQReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp,
n, TIME_INFINITE);
}
static bool_t putwouldblock(void *ip) {
- return chOQIsFullI(&((SerialDriver *)ip)->oqueue);
+ return chOQIsFullI(&((SerialUSBDriver *)ip)->oqueue);
}
static bool_t getwouldblock(void *ip) {
- return chIQIsEmptyI(&((SerialDriver *)ip)->iqueue);
+ return chIQIsEmptyI(&((SerialUSBDriver *)ip)->iqueue);
}
static msg_t putt(void *ip, uint8_t b, systime_t timeout) {
- return chOQPutTimeout(&((SerialDriver *)ip)->oqueue, b, timeout);
+ return chOQPutTimeout(&((SerialUSBDriver *)ip)->oqueue, b, timeout);
}
static msg_t gett(void *ip, systime_t timeout) {
- return chIQGetTimeout(&((SerialDriver *)ip)->iqueue, timeout);
+ return chIQGetTimeout(&((SerialUSBDriver *)ip)->iqueue, timeout);
}
static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) {
- return chOQWriteTimeout(&((SerialDriver *)ip)->oqueue, bp, n, time);
+ return chOQWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp, n, time);
}
static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) {
- return chIQReadTimeout(&((SerialDriver *)ip)->iqueue, bp, n, time);
+ return chIQReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp, n, time);
}
static ioflags_t getflags(void *ip) {
@@ -124,7 +124,7 @@ static void inotify(GenericQueue *qp) {
sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
if (n != USB_ENDPOINT_BUSY) {
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
- chSemSetCounterI(&sdup->iqueue.q_sem, n);
+ chSemAddCounterI(&sdup->iqueue.q_sem, n);
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
}
}
@@ -135,15 +135,16 @@ static void inotify(GenericQueue *qp) {
*/
static void onotify(GenericQueue *qp) {
SerialUSBDriver *sdup = (SerialUSBDriver *)qp->q_rdptr;
- size_t n;
+ size_t w, n;
/* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/
- n = usbWritePacketI(sdup->config->usbp, DATA_REQUEST_EP,
- sdup->oqueue.q_buffer, chOQGetFullI(&sdup->oqueue));
- if (n != USB_ENDPOINT_BUSY) {
+ n = chOQGetFullI(&sdup->oqueue);
+ w = usbWritePacketI(sdup->config->usbp, DATA_REQUEST_EP,
+ sdup->oqueue.q_buffer, n);
+ if (w != USB_ENDPOINT_BUSY) {
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- chSemSetCounterI(&sdup->oqueue.q_sem, SERIAL_USB_BUFFERS_SIZE);
+ chSemAddCounterI(&sdup->oqueue.q_sem, n);
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
}
}
@@ -276,17 +277,17 @@ bool_t sduRequestsHook(USBDriver *usbp) {
*/
void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
SerialUSBDriver *sdup = usbp->param;
- size_t n;
+ size_t n, w;
chSysLockFromIsr();
/* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/
n = chOQGetFullI(&sdup->oqueue);
if (n > 0) {
- n = usbWritePacketI(usbp, ep, sdup->oqueue.q_buffer, n);
- if (n != USB_ENDPOINT_BUSY) {
+ w = usbWritePacketI(usbp, ep, sdup->oqueue.q_buffer, n);
+ if (w != USB_ENDPOINT_BUSY) {
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- chSemSetCounterI(&sdup->oqueue.q_sem, SERIAL_USB_BUFFERS_SIZE);
+ chSemAddCounterI(&sdup->oqueue.q_sem, n);
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
}
}
@@ -314,7 +315,7 @@ void sduDataReceived(USBDriver *usbp, usbep_t ep) {
SERIAL_USB_BUFFERS_SIZE);
if (n != USB_ENDPOINT_BUSY) {
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
- chSemSetCounterI(&sdup->iqueue.q_sem, n);
+ chSemAddCounterI(&sdup->iqueue.q_sem, n);
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
}
}
diff --git a/os/kernel/include/chsem.h b/os/kernel/include/chsem.h
index f33b294fa..04e079466 100644
--- a/os/kernel/include/chsem.h
+++ b/os/kernel/include/chsem.h
@@ -52,7 +52,7 @@ extern "C" {
msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time);
void chSemSignal(Semaphore *sp);
void chSemSignalI(Semaphore *sp);
- void chSemSetCounterI(Semaphore *sp, cnt_t n);
+ void chSemAddCounterI(Semaphore *sp, cnt_t n);
#if CH_USE_SEMSW
msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw);
#endif
diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c
index 3e0fcd0e8..c22a568ea 100644
--- a/os/kernel/src/chsem.c
+++ b/os/kernel/src/chsem.c
@@ -313,35 +313,32 @@ void chSemSignalI(Semaphore *sp) {
}
/**
- * @brief Sets the semaphore counter to the specified value.
- * @post After invoking this function all the threads waiting on the
- * semaphore, if any, are released and the semaphore counter is set
- * to the specified, non negative, value.
+ * @brief Adds the specified value to the semaphore counter.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] sp pointer to a @p Semaphore structure
- * @param[in] n the new value of the semaphore counter. The value must
- * be non-negative.
+ * @param[in] n value to be added to the semaphore counter. The value
+ * must be positive.
*
* @iclass
*/
-void chSemSetCounterI(Semaphore *sp, cnt_t n) {
- cnt_t cnt;
+void chSemAddCounterI(Semaphore *sp, cnt_t n) {
- chDbgCheck((sp != NULL) && (n >= 0), "chSemSetCounterI");
+ chDbgCheck((sp != NULL) && (n > 0), "chSemAddCounterI");
chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) ||
((sp->s_cnt < 0) && notempty(&sp->s_queue)),
- "chSemSetCounterI(), #1",
+ "chSemAddCounterI(), #1",
"inconsistent semaphore");
- cnt = sp->s_cnt;
- sp->s_cnt = n;
- while (++cnt <= 0)
- chSchReadyI(lifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_OK;
+ while (n > 0) {
+ if (++sp->s_cnt <= 0)
+ chSchReadyI(fifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_OK;
+ n--;
+ }
}
#if CH_USE_SEMSW