From 6ee956d7b6cf775fd85c51347b75e39daa412d38 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 7 May 2012 18:43:52 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4171 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/io_block.h | 213 ++++++++++++++++++++++++++ os/hal/include/io_serial.h | 368 +++++++++++++++++++++++++++++++++++++++++++++ os/hal/include/sdc.h | 4 +- os/hal/src/sdc.c | 16 +- 4 files changed, 591 insertions(+), 10 deletions(-) create mode 100644 os/hal/include/io_block.h create mode 100644 os/hal/include/io_serial.h (limited to 'os/hal') diff --git a/os/hal/include/io_block.h b/os/hal/include/io_block.h new file mode 100644 index 000000000..20c2e991c --- /dev/null +++ b/os/hal/include/io_block.h @@ -0,0 +1,213 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file io_block.h + * @brief I/O block devices access. + * @details This header defines abstract interfaces useful to access generic + * I/O block devices in a standardized way. + * + * @addtogroup IO_BLOCK + * @details This module define an abstract interface for accessing generic + * block devices. + * Note that no code is present, just abstract interfaces-like + * structures, you should look at the system as to a set of + * abstract C++ classes (even if written in C). This system + * has then advantage to make the access to block devices + * independent from the implementation logic. + * @{ + */ + +#ifndef _IO_BLOCK_H_ +#define _IO_BLOCK_H_ + +/** + * @brief Block device info. + */ +typedef struct { + uint32_t blk_size; /**< @brief Block size in bytes. */ + uint32_t blk_num; /**< @brief Total number of blocks. */ +} BlockDeviceInfo; + +/** + * @brief @p BaseBlockDevice specific methods. + */ +#define _base_block_device_methods \ + /* Removable media detection.*/ \ + bool_t is_inserted(void *instance); \ + /* Removable write protection detection.*/ \ + bool_t is_protected(void *instance); \ + /* Connection to the block device.*/ \ + bool_t (*connect)(void *instance); \ + /* Disconnection from the block device.*/ \ + bool_t (*disconnect)(void *instance); \ + /* Reads one or more blocks.*/ \ + bool_t (*read)(void *instance, uint32_t startblk, \ + uint8_t *buffer, uint32_t n); \ + /* Writes one or more blocks.*/ \ + bool_t (*write)(void *instance, uint32_t startblk, \ + const uint8_t *buffer, uint32_t n); \ + /* Write operations synchronization.*/ \ + bool_t (*sync)(void *instance); \ + /* Obtains info about the media.*/ \ + bool_t (*get_info)(void *instance, BlockDeviceInfo *bdip); + +/** + * @brief @p BaseBlockDevice specific data. + * @note It is empty because @p BaseBlockDevice is only an interface + * without implementation. + */ +#define _base_block_device_data + +/** + * @brief @p BaseBlockDevice virtual methods table. + */ +struct BaseBlockDeviceVMT { + _base_block_device_methods +}; + +/** + * @brief Base block device class. + * @details This class represents a generic, block-accessible, device. + */ +typedef struct { + /** @brief Virtual Methods Table.*/ + const struct BaseBlockDeviceVMT *vmt; + _base_block_device_data +} BaseBlockDevice; + +/** + * @name Macro Functions (BaseBlockDevice) + * @{ + */ +/** + * @brief Returns the media insertion status. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The media state. + * @retval FALSE media not inserted. + * @retval TRUE media inserted. + * + * @api + */ +#define blkIsInserted(ip) ((ip)->vmt->is_inserted(ip)) + +/** + * @brief Returns the media write protection status. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The media state. + * @retval FALSE writable media. + * @retval TRUE non writable media. + * + * @api + */ +#define blkIsWriteProtected(ip) ((ip)->vmt->is_protected(ip)) + +/** + * @brief Performs the initialization procedure on the block device. + * @details This function should be performed before I/O operations can be + * attempted on the block device and after insertion has been + * confirmed using @p blkIsInserted(). + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The operation status. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. + * + * @api + */ +#define blkConnect(ip) ((ip)->vmt->connect(ip)) + +/** + * @brief Terminates operations on the block device. + * @details This operation safely terminates operations on the block device. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @return The operation status. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. + * + * @api + */ +#define blkDisconnect(ip) ((ip)->vmt-disconnect(ip)) + +/** + * @brief Reads one or more blocks. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * @param[in] startblk first block to read + * @param[out] buf pointer to the read buffer + * @param[in] n number of blocks to read + * + * @return The operation status. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. + * + * @api + */ +#define blkRead(ip, startblk, buffer, n) \ + ((ip)->vmt->read(ip, startblk, buffer, n)) + +/** + * @brief Writes one or more blocks. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * @param[in] startblk first block to write + * @param[out] buf pointer to the write buffer + * @param[in] n number of blocks to write + * + * @return The operation status. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. + * + * @api + */ +#define blkWrite(ip, startblk, buffer, n) \ + ((ip)->vmt->write(ip, startblk, buffer, n)) + +/** + * @brief Ensures write synchronization. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * + * @api + */ +#define blkSync(ip) ((ip)->vmt->sync(ip)) + +/** + * @brief Returns a media information structure. + * + * @param[in] ip pointer to a @p BaseBlockDevice or derived class + * @param[out] bdpi pointer to a @p BlockDeviceInfo structure + * + * @api + */ +#define blkGetInfo(ip, bdip) ((ip)->vmt->get_info(ip, bdip)) + +/** @} */ + +#endif /* _IO_BLOCK_H_ */ + +/** @} */ diff --git a/os/hal/include/io_serial.h b/os/hal/include/io_serial.h new file mode 100644 index 000000000..f6be5dad3 --- /dev/null +++ b/os/hal/include/io_serial.h @@ -0,0 +1,368 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file io_serial.h + * @brief I/O serial devices access. + * @details This header defines abstract interfaces useful to access generic + * I/O serial devices in a standardized way. + * + * @addtogroup IO_SERIAL + * @details This module defines an abstract interface for I/O channels by + * extending the @p BaseSequentialStream interface. Note that no code + * is present, I/O channels are just abstract interface like + * structures, you should look at the systems as to a set of abstract + * C++ classes (even if written in C). Specific device drivers can + * use/extend the interface and implement them.
+ * This system has the advantage to make the access to channels + * independent from the implementation logic. + * @{ + */ + +#ifndef _IO_SERIAL_H_ +#define _IO_SERIAL_H_ + +/** + * @brief @p BaseChannel specific methods. + */ +#define _base_channel_methods \ + _base_sequential_stream_methods \ + /* Channel output check.*/ \ + bool_t (*putwouldblock)(void *instance); \ + /* Channel input check.*/ \ + bool_t (*getwouldblock)(void *instance); \ + /* Channel put method with timeout specification.*/ \ + msg_t (*put)(void *instance, uint8_t b, systime_t time); \ + /* Channel get method with timeout specification.*/ \ + msg_t (*get)(void *instance, systime_t time); \ + /* Channel write method with timeout specification.*/ \ + 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); + +/** + * @brief @p BaseChannel specific data. + * @note It is empty because @p BaseChannel is only an interface without + * implementation. + */ +#define _base_channel_data \ + _base_sequential_stream_data + +/** + * @extends BaseSequentialStreamVMT + * + * @brief @p BaseChannel virtual methods table. + */ +struct BaseChannelVMT { + _base_channel_methods +}; + +/** + * @extends BaseSequentialStream + * + * @brief Base channel class. + * @details This class represents a generic, byte-wide, I/O channel. This class + * introduces generic I/O primitives with timeout specification. + */ +typedef struct { + /** @brief Virtual Methods Table.*/ + const struct BaseChannelVMT *vmt; + _base_channel_data +} BaseChannel; + +/** + * @name Macro Functions (BaseChannel) + * @{ + */ +/** + * @brief Channel output check. + * @details This function verifies if a subsequent put/write operation 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. + * + * @api + */ +#define srlPutWouldBlock(ip) ((ip)->vmt->putwouldblock(ip)) + +/** + * @brief Channel input check. + * @details This function verifies if a subsequent get/read operation 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. + * + * @api + */ +#define srlGetWouldBlock(ip) ((ip)->vmt->getwouldblock(ip)) + +/** + * @brief Channel blocking byte write. + * @details This function writes a byte value to a channel. If the channel + * is not ready to accept data then the calling thread is suspended. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @param[in] b the byte value to be written to the channel + * @return The operation status. + * @retval Q_OK if the operation succeeded. + * @retval Q_RESET if the channel associated queue (if any) was reset. + * + * @api + */ +#define srlPut(ip, b) ((ip)->vmt->put(ip, b, TIME_INFINITE)) + +/** + * @brief Channel blocking byte write with timeout. + * @details This function writes a byte value to a channel. If the channel + * is not ready to accept data then the calling thread is suspended. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @param[in] b the byte value to be written to the channel + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval Q_OK if the operation succeeded. + * @retval Q_TIMEOUT if the specified time expired. + * @retval Q_RESET if the channel associated queue (if any) was reset. + * + * @api + */ +#define srlPutTimeout(ip, b, time) ((ip)->vmt->put(ip, b, time)) + +/** + * @brief Channel blocking byte read. + * @details This function reads a byte value from a channel. If the data + * is not available then the calling thread is suspended. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @return A byte value from the queue. + * @retval Q_RESET if the channel associated queue (if any) has been + * reset. + * + * @api + */ +#define srlGet(ip) ((ip)->vmt->get(ip, TIME_INFINITE)) + +/** + * @brief Channel blocking byte read with timeout. + * @details This function reads a byte value from a channel. If the data + * is not available then the calling thread is suspended. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return A byte value from the queue. + * @retval Q_TIMEOUT if the specified time expired. + * @retval Q_RESET if the channel associated queue (if any) has been + * reset. + * + * @api + */ +#define srlGetTimeout(ip, time) ((ip)->vmt->get(ip, time)) + +/** + * @brief Channel blocking write with timeout. + * @details The function writes data from a buffer to a channel. If the channel + * is not ready to accept data then the calling thread is suspended. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @param[out] bp pointer to the data buffer + * @param[in] n the maximum amount of data to be transferred + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The number of bytes transferred. + * + * @api + */ +#define srlWriteTimeout(ip, bp, n, time) ((ip)->vmt->writet(ip, bp, n, time)) + +/** + * @brief Channel blocking read with timeout. + * @details The function reads data from a channel into a buffer. If the data + * is not available then the calling thread is suspended. + * + * @param[in] ip pointer to a @p BaseChannel or derived class + * @param[in] bp pointer to the data buffer + * @param[in] n the maximum amount of data to be transferred + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The number of bytes transferred. + * + * @api + */ +#define srlReadTimeout(ip, bp, n, time) ((ip)->vmt->readt(ip, bp, n, time)) +/** @} */ + +#if CH_USE_EVENTS || defined(__DOXYGEN__) +/** + * @name I/O status flags + * @{ + */ +/** @brief No pending conditions.*/ +#define IO_NO_ERROR 0 +/** @brief Connection happened.*/ +#define IO_CONNECTED 1 +/** @brief Disconnection happened.*/ +#define IO_DISCONNECTED 2 +/** @brief Data available in the input queue.*/ +#define IO_INPUT_AVAILABLE 4 +/** @brief Output queue empty.*/ +#define IO_OUTPUT_EMPTY 8 +/** @brief Transmission end.*/ +#define IO_TRANSMISSION_END 16 +/** @} */ + +/** + * @brief Type of an I/O condition flags mask. + */ +typedef uint_fast16_t ioflags_t; + +/** + * @brief @p BaseAsynchronousChannel specific methods. + */ +#define _base_asynchronous_channel_methods \ + _base_channel_methods \ + /* Channel read method with timeout specification.*/ \ + ioflags_t (*getflags)(void *instance); + +/** + * @brief @p BaseAsynchronousChannel specific data. + */ +#define _base_asynchronous_channel_data \ + _base_channel_data \ + /* I/O condition event source.*/ \ + EventSource event; \ + /* I/O condition flags.*/ \ + ioflags_t flags; + +/** + * @extends BaseChannelVMT + * + * @brief @p BaseAsynchronousChannel virtual methods table. + */ +struct BaseAsynchronousChannelVMT { + _base_asynchronous_channel_methods +}; + +/** + * @extends BaseChannel + * + * @brief Base asynchronous channel class. + * @details This class extends @p BaseChannel by adding event sources fields + * for asynchronous I/O for use in an event-driven environment. + */ +typedef struct { + /** @brief Virtual Methods Table.*/ + const struct BaseAsynchronousChannelVMT *vmt; + _base_asynchronous_channel_data +} BaseAsynchronousChannel; + +/** + * @name Macro Functions (BaseAsynchronousChannel) + * @{ + */ +/** + * @brief Returns the I/O condition event source. + * @details The event source is broadcasted when an I/O condition happens. + * + * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived + * class + * @return A pointer to an @p EventSource object. + * + * @api + */ +#define srlGetEventSource(ip) (&((ip)->event)) + +/** + * @brief Adds status flags to the channel's mask. + * @details This function is usually called from the I/O ISRs in order to + * notify I/O conditions such as data events, errors, signal + * changes etc. + * + * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived + * class + * @param[in] mask condition flags to be added to the mask + * + * @iclass + */ +#define srlAddFlagsI(ip, mask) { \ + (ip)->flags |= (mask); \ + chEvtBroadcastI(&(ip)->event); \ +} + +/** + * @brief Returns and clears the status flags associated to the channel. + * + * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived + * class + * @return The condition flags modified since last time this + * function was invoked. + * + * @api + */ +#define srlGetAndClearFlags(ip) ((ip)->vmt->getflags(ip)) +/** @} */ + +/** + * @brief Default implementation of the @p getflags virtual method. + * + * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived + * class + * @return The condition flags modified since last time this + * function was invoked. + * + * @notapi + */ +#define _ser_get_and_clear_flags_impl(ip) \ + ioflags_t mask; \ + chSysLock(); \ + mask = ((BaseAsynchronousChannel *)(ip))->flags; \ + ((BaseAsynchronousChannel *)(ip))->flags = IO_NO_ERROR; \ + chSysUnlock(); \ + return mask + +#endif /* CH_USE_EVENTS */ + +#endif /* _IO_SERIAL_H_ */ + +/** @} */ diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index f5051731e..82b083125 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -232,8 +232,8 @@ typedef enum { * * @param[in] sdcp pointer to the @p SDCDriver object * @return The card state. - * @retval FALSE card not inserted. - * @retval TRUE card inserted. + * @retval FALSE not write protected. + * @retval TRUE write protected. * * @api */ diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 3d0d495bb..6e9dcabd4 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -204,8 +204,8 @@ void sdcStop(SDCDriver *sdcp) { * @param[in] sdcp pointer to the @p SDCDriver object * * @return The operation status. - * @retval FALSE operation succeeded. - * @retval TRUE operation failed. + * @retval CH_FAILED operation succeeded. + * @retval CH_SUCCESS operation failed. * * @api */ @@ -365,8 +365,8 @@ failed: * @param[in] sdcp pointer to the @p SDCDriver object * * @return The operation status. - * @retval FALSE operation succeeded. - * @retval TRUE operation failed. + * @retval CH_FAILED operation succeeded. + * @retval CH_SUCCESS operation failed. * * @api */ @@ -406,8 +406,8 @@ bool_t sdcDisconnect(SDCDriver *sdcp) { * @param[in] n number of blocks to read * * @return The operation status. - * @retval FALSE operation succeeded. - * @retval TRUE operation failed. + * @retval CH_FAILED operation succeeded. + * @retval CH_SUCCESS operation failed. * * @api */ @@ -443,8 +443,8 @@ bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk, * @param[in] n number of blocks to write * * @return The operation status. - * @retval FALSE operation succeeded. - * @retval TRUE operation failed. + * @retval CH_FAILED operation succeeded. + * @retval CH_SUCCESS operation failed. * * @api */ -- cgit v1.2.3