From dd5d6d0affd6ee564836aba9e1429925d7a39d63 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 29 Aug 2017 11:30:45 +0000 Subject: Added an ioctl()-like function to the serial driver. No specific codes implemented yet. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10505 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/hal_channels.h | 29 ++++++++++++++++++++++++++++- os/hal/include/hal_serial.h | 1 + os/hal/src/hal_serial.c | 43 ++++++++++++++++++++++++++++++++++++++++++- readme.txt | 4 ++++ 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/os/hal/include/hal_channels.h b/os/hal/include/hal_channels.h index ab1ac314a..748dbe04a 100644 --- a/os/hal/include/hal_channels.h +++ b/os/hal/include/hal_channels.h @@ -36,6 +36,15 @@ #ifndef HAL_CHANNELS_H #define HAL_CHANNELS_H +/** + * @name Default control operation codes. + * @{ + */ +#define CHN_CTL_INVALID 0 /** @brief Invalid operation code. */ +#define CHN_CTL_NOP 1 /** @brief Does nothing. */ +#define CHN_CTL_TX_WAIT 2 /** @brief Wait for TX completion. */ +/** @} */ + /** * @brief @p BaseChannel specific methods. */ @@ -49,7 +58,9 @@ size_t (*writet)(void *instance, const uint8_t *bp, \ size_t n, systime_t time); \ /* Channel read method with timeout specification.*/ \ - size_t (*readt)(void *instance, uint8_t *bp, size_t n, systime_t time); + size_t (*readt)(void *instance, uint8_t *bp, size_t n, systime_t time); \ + /* Channel put method with timeout specification.*/ \ + msg_t (*ctl)(void *instance, unsigned int operation, void *arg); /** * @brief @p BaseChannel specific data. @@ -193,6 +204,22 @@ typedef struct { * @api */ #define chnReadTimeout(ip, bp, n, time) ((ip)->vmt->readt(ip, bp, n, time)) + +/** + * @brief Control operation on a channel. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @param[in] operation control operation code + * @param[in,out] arg operation argument + * + * @return The control operation status. + * @retval MSG_OK in case of success. + * @retval MSG_TIMEOUT in case of operation timeout. + * @retval MSG_RESET in case of operation reset. + * + * @api + */ +#define chnControl(sdp, operation, arg) ((ip)->vmt->ctl(ip, operation, arg) /** @} */ /** diff --git a/os/hal/include/hal_serial.h b/os/hal/include/hal_serial.h index 5d4de04e0..2a0925658 100644 --- a/os/hal/include/hal_serial.h +++ b/os/hal/include/hal_serial.h @@ -283,6 +283,7 @@ extern "C" { msg_t sdRequestDataI(SerialDriver *sdp); bool sdPutWouldBlock(SerialDriver *sdp); bool sdGetWouldBlock(SerialDriver *sdp); + msg_t sdControl(SerialDriver *sdp, unsigned int operation, void *arg); #ifdef __cplusplus } #endif diff --git a/os/hal/src/hal_serial.c b/os/hal/src/hal_serial.c index 22723e3e6..573b139be 100644 --- a/os/hal/src/hal_serial.c +++ b/os/hal/src/hal_serial.c @@ -89,9 +89,31 @@ static size_t _readt(void *ip, uint8_t *bp, size_t n, systime_t timeout) { return iqReadTimeout(&((SerialDriver *)ip)->iqueue, bp, n, timeout); } +static msg_t _ctl(void *ip, unsigned int operation, void *arg) { + SerialDriver *sdp = (SerialDriver *)ip; + + osalDbgCheck(sdp != NULL); + + switch (operation) { + case CHN_CTL_NOP: + osalDbgCheck(arg == NULL); + break; + default: +#if defined(SD_LLD_IMPLEMENTS_CTL) + return sd_lld_control(sdp, operation, arg); +#else + case CHN_CTL_INVALID: + osalDbgAssert(false, "invalid CTL operation"); + break; +#endif + } + return MSG_OK; +} + static const struct SerialDriverVMT vmt = { _write, _read, _put, _get, - _putt, _gett, _writet, _readt + _putt, _gett, _writet, _readt, + _ctl }; /*===========================================================================*/ @@ -298,6 +320,25 @@ bool sdGetWouldBlock(SerialDriver *sdp) { return b; } +/** + * @brief Control operation on a serial port. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] operation control operation code + * @param[in,out] arg operation argument + * + * @return The control operation status. + * @retval MSG_OK in case of success. + * @retval MSG_TIMEOUT in case of operation timeout. + * @retval MSG_RESET in case of operation reset. + * + * @api + */ +msg_t sdControl(SerialDriver *sdp, unsigned int operation, void *arg) { + + return _ctl((void *)sdp, operation, arg); +} + #endif /* HAL_USE_SERIAL == TRUE */ /** @} */ diff --git a/readme.txt b/readme.txt index 95eb196b1..665927b6e 100644 --- a/readme.txt +++ b/readme.txt @@ -89,6 +89,10 @@ ***************************************************************************** *** Next *** +- NEW: Added to the serial driver and channels interface a new "control" + function that allows to implement extensions in the LLD without + touching the high level interface. Conceptually it is similar + to Posix ioctl(). - NEW: Added an argument to PAL events callback. API changed thus this causes a major number change in HAL. - NEW: Added shared Eclipse debug configurations for OpenOCD under -- cgit v1.2.3