diff --git a/os/kernel/include/chevents.h b/os/kernel/include/chevents.h index 6a1cd6106..d934340ab 100644 --- a/os/kernel/include/chevents.h +++ b/os/kernel/include/chevents.h @@ -55,6 +55,11 @@ typedef struct EventSource { Source. */ } EventSource; +/** + * @brief Event Handler callback function. + */ +typedef void (*evhandler_t)(eventid_t); + /** * @brief Data part of a static event source initializer. * @details This macro should be used when statically initializing an event @@ -119,9 +124,28 @@ typedef struct EventSource { ((void *)(esp) != (void *)(esp)->es_next) /** - * @brief Event Handler callback function. + * @brief Signals all the Event Listeners registered on the specified Event + * Source. + * + * @param[in] esp pointer to the @p EventSource structure + * + * @api */ -typedef void (*evhandler_t)(eventid_t); +#define chEvtBroadcast(esp) chEvtBroadcastFlags(esp, 0) + +/** + * @brief Signals all the Event Listeners registered on the specified Event + * Source. + * @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] esp pointer to the @p EventSource structure + * + * @iclass + */ +#define chEvtBroadcastI(esp) chEvtBroadcastFlagsI(esp, 0) #ifdef __cplusplus extern "C" { @@ -132,10 +156,10 @@ extern "C" { void chEvtUnregister(EventSource *esp, EventListener *elp); eventmask_t chEvtClearFlags(eventmask_t mask); eventmask_t chEvtAddFlags(eventmask_t mask); - void chEvtSignal(Thread *tp, eventmask_t mask); - void chEvtSignalI(Thread *tp, eventmask_t mask); - void chEvtBroadcast(EventSource *esp); - void chEvtBroadcastI(EventSource *esp); + void chEvtSignalFlags(Thread *tp, eventmask_t mask); + void chEvtSignalFlagsI(Thread *tp, eventmask_t mask); + void chEvtBroadcastFlags(EventSource *esp, eventmask_t mask); + void chEvtBroadcastFlagsI(EventSource *esp, eventmask_t mask); void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask); #if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT eventmask_t chEvtWaitOne(eventmask_t mask); diff --git a/os/kernel/include/chmboxes.h b/os/kernel/include/chmboxes.h index ce3f238be..fcd26597d 100644 --- a/os/kernel/include/chmboxes.h +++ b/os/kernel/include/chmboxes.h @@ -60,10 +60,13 @@ extern "C" { void chMBReset(Mailbox *mbp); msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout); msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t timeout); + msg_t chMBPostI(Mailbox *mbp, msg_t msg); msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout); msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t timeout); + msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg); msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t timeout); msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t timeout); + msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp); #ifdef __cplusplus } #endif diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index a0ef2d1bb..a64f59bdc 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -160,12 +160,12 @@ eventmask_t chEvtAddFlags(eventmask_t mask) { * * @api */ -void chEvtSignal(Thread *tp, eventmask_t mask) { +void chEvtSignalFlags(Thread *tp, eventmask_t mask) { chDbgCheck(tp != NULL, "chEvtSignal"); chSysLock(); - chEvtSignalI(tp, mask); + chEvtSignalFlagsI(tp, mask); chSchRescheduleS(); chSysUnlock(); } @@ -182,7 +182,7 @@ void chEvtSignal(Thread *tp, eventmask_t mask) { * * @iclass */ -void chEvtSignalI(Thread *tp, eventmask_t mask) { +void chEvtSignalFlagsI(Thread *tp, eventmask_t mask) { chDbgCheck(tp != NULL, "chEvtSignalI"); @@ -198,15 +198,20 @@ void chEvtSignalI(Thread *tp, eventmask_t mask) { /** * @brief Signals all the Event Listeners registered on the specified Event * Source. + * @details This function variants ORs the specified event flags to all the + * threads registered on the @p EventSource in addition to the event + * flags specified by the threads themselves in the + * @p EventListener objects. * * @param[in] esp pointer to the @p EventSource structure + * @param[in] mask the event flags set to be ORed * * @api */ -void chEvtBroadcast(EventSource *esp) { +void chEvtBroadcastFlags(EventSource *esp, eventmask_t mask) { chSysLock(); - chEvtBroadcastI(esp); + chEvtBroadcastFlagsI(esp, mask); chSchRescheduleS(); chSysUnlock(); } @@ -214,23 +219,28 @@ void chEvtBroadcast(EventSource *esp) { /** * @brief Signals all the Event Listeners registered on the specified Event * Source. + * @details This function variants ORs the specified event flags to all the + * threads registered on the @p EventSource in addition to the event + * flags specified by the threads themselves in the + * @p EventListener objects. * @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] esp pointer to the @p EventSource structure + * @param[in] mask the event flags set to be ORed * * @iclass */ -void chEvtBroadcastI(EventSource *esp) { +void chEvtBroadcastFlagsI(EventSource *esp, eventmask_t mask) { EventListener *elp; - chDbgCheck(esp != NULL, "chEvtBroadcastI"); + chDbgCheck(esp != NULL, "chEvtBroadcastMaskI"); elp = esp->es_next; while (elp != (EventListener *)esp) { - chEvtSignalI(elp->el_listener, elp->el_mask); + chEvtSignalFlagsI(elp->el_listener, elp->el_mask | mask); elp = elp->el_next; } } diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index b2cef2470..e0b6ca014 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -155,6 +155,34 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { return rdymsg; } +/** + * @brief Posts a message into a mailbox. + * @details This variant is non-blocking, the function returns a timeout + * condition if the queue is full. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @return The operation status. + * @retval RDY_OK if a message has been correctly posted. + * @retval RDY_TIMEOUT if the mailbox is full and the message cannot be + * posted. + * + * @iclass + */ +msg_t chMBPostI(Mailbox *mbp, msg_t msg) { + + chDbgCheck(mbp != NULL, "chMBPostI"); + + if (chSemGetCounterI(&mbp->mb_emptysem) <= 0) + return RDY_TIMEOUT; + chSemFastWaitI(&mbp->mb_emptysem); + *mbp->mb_wrptr++ = msg; + if (mbp->mb_wrptr >= mbp->mb_top) + mbp->mb_wrptr = mbp->mb_buffer; + chSemSignalI(&mbp->mb_fullsem); + return RDY_OK; +} + /** * @brief Posts an high priority message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes @@ -218,6 +246,34 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { return rdymsg; } +/** + * @brief Posts an high priority message into a mailbox. + * @details This variant is non-blocking, the function returns a timeout + * condition if the queue is full. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @return The operation status. + * @retval RDY_OK if a message has been correctly posted. + * @retval RDY_TIMEOUT if the mailbox is full and the message cannot be + * posted. + * + * @iclass + */ +msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg) { + + chDbgCheck(mbp != NULL, "chMBPostAheadI"); + + if (chSemGetCounterI(&mbp->mb_emptysem) <= 0) + return RDY_TIMEOUT; + chSemFastWaitI(&mbp->mb_emptysem); + if (--mbp->mb_rdptr < mbp->mb_buffer) + mbp->mb_rdptr = mbp->mb_top - 1; + *mbp->mb_rdptr = msg; + chSemSignalI(&mbp->mb_fullsem); + return RDY_OK; +} + /** * @brief Retrieves a message from a mailbox. * @details The invoking thread waits until a message is posted in the mailbox @@ -280,6 +336,33 @@ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { } return rdymsg; } + +/** + * @brief Retrieves a message from a mailbox. + * @details This variant is non-blocking, the function returns a timeout + * condition if the queue is full. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[out] msgp pointer to a message variable for the received message + * @return The operation status. + * @retval RDY_OK if a message has been correctly fetched. + * @retval RDY_TIMEOUT if the mailbox is empty and a message cannot be + * fetched. + * + * @iclass + */ +msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp) { + + chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchI"); + + if (chSemGetCounterI(&mbp->mb_fullsem) <= 0) + return RDY_TIMEOUT; + *msgp = *mbp->mb_rdptr++; + if (mbp->mb_rdptr >= mbp->mb_top) + mbp->mb_rdptr = mbp->mb_buffer; + chSemSignalI(&mbp->mb_emptysem); + return RDY_OK; +} #endif /* CH_USE_MAILBOXES */ /** @} */ diff --git a/readme.txt b/readme.txt index a9a8e15bd..0ef32b5b7 100644 --- a/readme.txt +++ b/readme.txt @@ -75,6 +75,14 @@ 2.2.1). - FIX: Error in MAC driver (bug 3179783)(backported to 2.2.1). - FIX: Fixed wrong serial driver macros (bug 3173336)(backported to 2.2.1). +- NEW: Added two new functions to the events subsystem: chEvtBroadcastFlags() + and chEvtBroadcastFlagsI(). The old chEvtBroadcast() and chEvtBroadcastI() + become macros. The new functions allow to add the same flags to all the + registered listener threads. +- CHANGE: The functions chEvtSignal() and chEvtSignalI() have been renamed + to chEvtSignalFlags() and chEvtSignalFlagsI() for consistency. +- NEW: Added I-Class functions to the MailBoxes subsystem, now it is + possible to use them as a transport layer between ISRs and Threads. - NEW: Added experimental generic USB driver, it will evolve in next releases. - NEW: Added an experimental USB driver implementation for STM32. diff --git a/test/testevt.c b/test/testevt.c index 656a8430d..ccf0ed576 100644 --- a/test/testevt.c +++ b/test/testevt.c @@ -136,7 +136,7 @@ static void evt2_setup(void) { static msg_t thread1(void *p) { chThdSleepMilliseconds(50); - chEvtSignal((Thread *)p, 1); + chEvtSignalFlags((Thread *)p, 1); return 0; } diff --git a/todo.txt b/todo.txt index 7c92ddac3..92e357ae4 100644 --- a/todo.txt +++ b/todo.txt @@ -6,49 +6,61 @@ X = In progress, some work done. N = Decided against. Within 2.3.x (hopefully) -- Improvements to the message passing mechanism in order to allow "delayed, - out of order, responses". -- Add a switch to enable/disable the priority inheritance algorithm in mutexes. -- Introduce a "THREAD" function prefix in order to hide compiler-specific - optimizations for thread functions. -? Make thread functions return void. -- Introduce compiler-info macros to the port layer, improve the test reports - with the info. +* Add an USB abstract device driver class. +* USB driver implementation for STM32F102/STM32F103. +* Add a Serial over USB generic device driver implementing a USB Communication + Device Class and offering a Serial-like interface to the applications. +* Add I-class APIs for mailboxes. +* Modify chEvtBroadcast() to accept a flags mask as parameter. * Add a "transmission end" event to the serial device driver model. X Implement the "transmission end" serial driver event on those platforms supporting the feature. -X Add an USB abstract device driver class. -X USB driver implementation for STM32F103/STM32F102. -- USB driver implementation for STM32F105/STM32F107. -X Add a Serial over USB generic device driver implementing a USB Communication - Device Class and offering a Serial-like interface to the applications. +- Swap TIME_IMMEDIATE and TIME_INFINITE values. +- Improvements to the message passing mechanism in order to allow "delayed, + out of order, responses". +? Make thread functions return void and add a CH_THREAD macro for threads + declaration in order to hide compiler-specific optimizations for thread + functions. +- Introduce compiler-info macros to the port layer, improve the test reports + with the compiler info. +- Test suite overhaul, the API should be more generic in order to be used + with different subsystems and not just the kernel. +- Long duration "IRQ storm" stress test applications for all supported + architectures. +- Device drivers for STM8/STM8L (ADC, PWM, bring them on par with STM32). +- Device drivers for LPC1xxx (ADC, PWM, bring them on par with STM32). - Implement USB Mass Storage Class support and demo using the MMC_SPI driver as back-end. X File System infrastructure. - Official FatFs wrapper using the new infrastructure, dedicated test suite. X Transactional flash file system implementation. X I2C device driver class support and at least one implementation. -- Serial over UART complex driver driver, evaluate from the performance - results if to make obsolete the current dedicated Serial driver. X Shared DMA channels support in the STM32/STM8L HALs. +X RAM ISR vectors support in the STM32 HAL. X New device driver models: Clock, Systick, RTC, WDG, DAC, Power Monitor. -- MAC driver for STM32F107 (hardware missing). -- Device drivers for STM8/STM8L (ADC, PWM, bring them on par with STM32). + +Later but within 2.x.x - Batch testing of the ARM7/ARMCMx port using OpenOCD, with reports. - Debug-related features and tools. ? Add a *very simple* ADC API for single one shot sampling (implement it as an injected conversion on the STM32). +- Improved Makefile system. +- Serial over UART complex driver driver, evaluate from the performance + results if to make obsolete the current dedicated Serial driver. +- LPC17xx family support. +- Official segmented interrupts support and abstraction in CMx port. +- USB driver implementation for STM32F105/STM32F107. +- MAC driver revision in order to support copy-less operations, this will + require changes to lwIP or a new TCP/IP stack however. +- MAC driver for STM32F107 (hardware missing). - Update C++ wrapper (Heap, Pools, Mailboxes and any new feature). - Threads Pools manager in the library. - -Later but within 2.x.x +- Add a switch to enable/disable the priority inheritance algorithm in mutexes. - Dedicated TCP/IP stack. ? ISO7816 driver over UART driver, both reader and card side (hardware missing). - Merge the Coldfire branch in mainline (hardware missing). - Merge the H8S branch in mainline (hardware missing). -- MAC driver revision in order to support copy-less operations, this will - require changes to lwIP or a new TCP/IP stack however. Ideas for 3.x.x: - MMU/MPU support. @@ -58,5 +70,4 @@ Ideas for 3.x.x: Side projects: X ChibiOS Wizard, UML modeling and ChibiOS applications code and documentation generator. -? File System - Visual debugger/monitor interfaced through OpenOCD.