diff --git a/docs/src/concepts.dox b/docs/src/concepts.dox index 725be9b52..ed37ed349 100644 --- a/docs/src/concepts.dox +++ b/docs/src/concepts.dox @@ -35,8 +35,8 @@ * ChibiOS/RT APIs are all named following this convention: * @a ch\\\(). * The possible groups are: @a Sys, @a Sch, @a Time, @a VT, @a Thd, @a Sem, - * @a Mtx, @a Cond, @a Evt, @a Msg, @a IQ, @a OQ, @a HQ, @a FDD, @a HDD, - * @a Dbg, @a Heap, @a Pool. + * @a Mtx, @a Cond, @a Evt, @a Msg, @a IQ, @a OQ, @a IO, @a FDD, @a Dbg, + * @a Heap, @a Pool. * * @section api_suffixes API Names Suffixes * The suffix can be one of the following: diff --git a/docs/src/main.dox b/docs/src/main.dox index ea30d420f..2e76e0a75 100644 --- a/docs/src/main.dox +++ b/docs/src/main.dox @@ -313,7 +313,7 @@ * you should look at the systems as to a set of abstract C++ classes (even if * implemented in C). Specific device drivers can use/extend the interfaces * and implement them.
- * This system has the advantage to make the access to the device drivers + * This system has the advantage to make the access to channels * independent from the implementation logic. As example, an I/O channel * interface can hide the access to a serial driver, to a networking socket * and so on. diff --git a/readme.txt b/readme.txt index 78db7352e..6d8c1c9c2 100644 --- a/readme.txt +++ b/readme.txt @@ -75,6 +75,15 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process, - FIX: Found new instances of the obsolete function chSysGetTime() in the C++ wrapper and in the WEB demo (bug 2772237)(backported in stable branch). - FIX: Fixed macro in test.h (bug 2781176)(backported in stable branch). +- NEW: Abstract I/O Channels mechanism introduced. This mechanism allows to + access I/O resources through a standard interface and hides implementation + details. The existing FullDuplexDrivers were modified to offer a standard + channel interface to the applications. +- NEW: The I/O queues code was improved, now there are 2 separate structures: + InputQueue and OutputQueue. There are some changes in the queue APIs + in order to make them more symmetrical and functional. Improved the queues + documentation. Some of the changes were needed in order to support the new + channels mechanism as a backend for queued serial drivers. - NEW: Added a code coverage analysis application under ./tests/coverage. - NEW: Added more test cases in order to improve the test suite code coverage (it was 74% in version 1.2.0). @@ -82,10 +91,6 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process, real context switch time, previous benchmarks introduced too much overhead to the measurement. The STM32 performs the context switch in under 1.48uS. - NEW: Added architecture name strings to the port code. -- NEW: The I/O queues code was improved, now there are 2 separate structures: - InputQueue and Output queues. There are some changes int the queue APIs - in order to make them more symmetrical and functional. Improved the queues - documentation. - CHANGE: Removed the half duplex queues and half duplex serial drivers because it was never extensively tested. The code is still available but not as part of the kernel. diff --git a/src/chserial.c b/src/chserial.c index 4dac892f8..65179689d 100644 --- a/src/chserial.c +++ b/src/chserial.c @@ -28,6 +28,20 @@ #if CH_USE_SERIAL_FULLDUPLEX +/* + * Interface implementation, the following functions just invoke the equivalent + * queue-level function or macro. + */ +static bool_t putwouldblock(void *instance) { + + return chOQIsFull(&((FullDuplexDriver *)instance)->d2.oqueue); +} + +static bool_t getwouldblock(void *instance) { + + return chIQIsEmpty(&((FullDuplexDriver *)instance)->d2.iqueue); +} + static msg_t put(void *instance, uint8_t b, systime_t timeout) { return chOQPutTimeout(&((FullDuplexDriver *)instance)->d2.oqueue, b, timeout); @@ -49,7 +63,7 @@ static size_t read(void *instance, uint8_t *buffer, size_t n) { } static const struct FullDuplexDriverVMT vmt = { - {put, get}, + {putwouldblock, getwouldblock, put, get}, {write, read}, {} }; diff --git a/src/include/channels.h b/src/include/channels.h index d3d1f5d47..2ff20b1ad 100644 --- a/src/include/channels.h +++ b/src/include/channels.h @@ -31,6 +31,16 @@ * @brief @p BaseChannel specific methods. */ struct _base_channel_methods { + /** + * @brief Channel output check. + * @see chIOPutWouldBlock() + */ + bool_t (*putwouldblock)(void *instance); + /** + * @brief Channel input check. + * @see chIOGetWouldBlock() + */ + bool_t (*getwouldblock)(void *instance); /** * @brief Channel put method with timeout specification. * @see chIOPut() @@ -76,6 +86,30 @@ typedef struct { struct _base_channel_data d0; } BaseChannel; +/** + * @brief Channel output check. + * @details This function verifies if a subsequent @p chIOPut() would block. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @return The output queue status: + * @retval FALSE if the output queue has space and would not block a write + * operation. + * @retval TRUE if the output queue is full and would block a write operation. + */ +#define chIOPutWouldBlock(ip) ((ip)->vmt->m0.putwouldblock(ip)) + +/** + * @brief Channel input check. + * @details This function verifies if a subsequent @p chIOGett() would block. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @return The input queue status: + * @retval FALSE if the input queue contains data and would not block a read + * operation. + * @retval TRUE if the input queue is empty and would block a read operation. + */ +#define chIOGetWouldBlock(ip) ((ip)->vmt->m0.getwouldblock(ip)) + /** * @brief Channel blocking byte write. * @details This function writes a byte value to a channel. If the channel diff --git a/src/include/serial.h b/src/include/serial.h index 9bb6c4f92..08ddf61fe 100644 --- a/src/include/serial.h +++ b/src/include/serial.h @@ -136,6 +136,24 @@ extern "C" { } #endif +/** + * @brief Direct output check on a @p FullDuplexDriver. + * @details This function bypasses the indirect access to the channel and + * checks directly the output queue. This is faster but cannot + * be used to check different channels implementations. + * @see chIOPutWouldBlock() + */ +#define chFDDPutWouldBlock(sd) chOQIsFull(&(sd)->d2.oqueue) + +/** + * @brief Direct input check on a @p FullDuplexDriver. + * @details This function bypasses the indirect access to the channel and + * checks directly the input queue. This is faster but cannot + * be used to check different channels implementations. + * @see chIOGetWouldBlock() + */ +#define chFDDGetWouldBlock(sd) chIQIsEmpty(&(sd)->d2.iqueue) + /** * @brief Direct blocking write to a @p FullDuplexDriver. * @details This function bypasses the indirect access to the channel and