- Move CRC polynomial enum into HAL layer, so it's accessible from platform
implementations
- Add enum to CRC class to indicate which mode the CRC class should use:
HARDWARE, TABLE, or BITWISE
- Add calls to HAL Hardware CRC API to each of the compute functions when the
class is in HARDWARE mode.
- Add missing constructor call to template constructor, and remove const from
delegating constructor.
There was no way to check current blocking state, so no way to modify
and restore status.
Also have default FileHandle::set_blocking() used by real files return a
correct error code when asked for non-blocking, and success when asked
for blocking.
These were minor omissions that are required to implement POSIX fcntl
properly.
fixup! Add `is_blocking()` method to FileHandle
Appears when complied with -O3 optimization level
Compile: UARTSerial.cpp
../drivers/UARTSerial.cpp: In member function 'void mbed::UARTSerial::tx_irq()':
../drivers/UARTSerial.cpp:314:31: warning: 'data' may be used uninitialized in this function [-Wmaybe-uninitialized]
SerialBase::_base_putc(data);
Ticker constructor calls directly target specific ticker init function. Currently there is no problem, since ticker interface initialization functions are protected against multi-calls and simply returns if not called for the first time (interface initialization can be performed only once). According to the new Thicker HAL API requirements:
The function ticker_init allows the ticker to keep counting and disables the ticker interrupt.
Disabling interrupts while some Ticker interrupts are already scheduled for sure will destroy the schedule. Ticker interface should be initialized only once and it is already done by: static void initialize(const ticker_data_t *ticker) function in /m-bed/hal/mbed_ticker_api.c file.
CRC class `MbedCRC.h` is templated class created to support hardware/software
CRCs. Default CRC will be hardware CRC when support for HAL is available.
Polynomial tables are available for 8/16 bit CCITT, 7/16 bit for SD card and
32-bit ANSI. Polynomial table implementation will be used if Hardware CRC is
not available.
In case device does not have hardware CRC and polynomial table is not supported,
CRC is still available and is computed runtime bit by bit for all data input.
- Add flag to SPI class to track if the SPI instance has locked deep sleep mode.
- Wrap call to sleep_manager_lock_deep_sleep to only be called if SPI instance
hasn't already locked deep sleep.
- Wrap call to sleep_manager_unlock_deep_sleep to only be called if SPI has
currently locked deep sleep mode.
- Add flag to I2C class to track if the I2C instance has locked deep sleep mode.
- Wrap call to sleep_manager_lock_deep_sleep to only be called if I2C instance
hasn't already locked deep sleep.
- Wrap call to sleep_manager_unlock_deep_sleep to only be called if I2C has
currently locked deep sleep mode.
Previously, write() was somewhat soft - it only ever made one attempt to
wait for buffer space, so it would take as much data as would fit in the
buffer in one call.
This is not the intent of a POSIX filehandle write. It should try to
send everything if blocking, and only send less if interrupted by a
signal:
- If the O_NONBLOCK flag is clear, write() shall block the calling
thread until the data can be accepted.
- If the O_NONBLOCK flag is set, write() shall not block the thread.
If some data can be written without blocking the thread, write()
shall write what it can and return the number of bytes written.
Otherwise, it shall return -1 and set errno to [EAGAIN].
This "send all" behaviour is of slightly limited usefulness in POSIX, as
you still usually have to worry about the interruption possibility:
- If write() is interrupted by a signal before it writes any data, it
shall return -1 with errno set to [EINTR].
- If write() is interrupted by a signal after it successfully writes
some data, it shall return the number of bytes written.
But as mbed OS does not have the possibility of signal interruption, if we
strengthen write to write everything, we can make applications' lives
easier - they can just do "write(large amount)" confident that it will
all go in one call (if no errors).
So, rework to make multiple writes to the buffer, blocking as necessary,
until all data is written.
This change does not apply to read(), which is correct in only blocking until
some data is available:
- If O_NONBLOCK is set, read() shall return -1 and set errno to [EAGAIN].
- If O_NONBLOCK is clear, read() shall block the calling thread until some
data becomes available.
- The use of the O_NONBLOCK flag has no effect if there is some data
available.
If a LowPowerTimer is started and then goes out of scope then a
deep sleep lock underflow can occur. This is because the
the variable '_lock_deepsleep' is checked when starting the timer
but is not checked in the destructor, which unconditionally releases
the deep sleep lock.
Release the deep sleep lock when running instances of the Timer class
are deleted. This ensures that deep sleep locks are properly released
by the Timer class.
Add passthrough APIs to enable the flow control and format methods from
SerialBase to be accessed.
Modify the RX data pump so it stops reading data and disables the IRQ
when the buffer is full, to allow UART automatic flow control to work.
In principle it would also be possible as a future enhancement to
provide XON/XOFF flow control, or manual RTS/CTS control using GPIO, but
this commit at least restores the functionality present in Serial,
SerialBase and RawSerial that was missing in UARTSerial.
UARTSerial inherits both FileHandle::readable() [public] and
SerialBase::readable() [private], so calling readable() on a UARTSerial
object produces an ambiguous member error.
Add using declarations to direct towards the FileHandle versions of
readable and writable.
There's currently no ambiguity for writable, as SerialBase uses the
spelling 'writeable', but add a using directive for that anyway, in case
SerialBase gains 'writable' later.
attach/detach can be multiple invoked. Therefore lock/unlock deep sleep
only for the very first time it is invoked (when callbacks
are actually changed).
Any driver with attach or async API should be considered for deep sleep.
Add locking to those that require in most cases
high-frequency clocks:
- CAN
- I2C
- SPI
- Serial
- Ticker/Timeout/Timer
On some platforms, the in-application memory is not memory mapped
and therefore cannot be accessed using memcpy.
The flash_read function added to flash_api.h (with a weak
implementation using memcpy in mbed_flash_api.c) can be used for
reading data from areas that are not memory mapped.
1. Private _acquire() function is added to avoid multiple locking/unlocking
2. format and frequency functions updated to use appropriate function calls
instead of a aquire()
Fixes issue #4537. SerialBase and UARTSerial happened to have same names
for the mutex locking that confused the system of holding a mutex in interrupt context.
UARTSerial has to change so as to provide empty implementations for lock() and unlock()
becuase it uses SerialBase from interrupt context only or from its own critical section,
so no extra locks required.
Private locks for UARTSerial itself are renamed to api_lock() and api_unlock().
For keep supporting external APIs with the same name (supposedly there are a larger
number of users of those APIs), BufferedSerial and ATParser are being renamed.
BufferedSerial becomes UARTSerial, will complement a future USBSerial etc.
ATParser becomes ATCmdParser.
* UARTSerial moves to /drivers
* APN_db.h is moved from platform to cellular/util/.
* Original CellularInterface is restored for backward compatability (again, supposedly there
are users of that).
* A new file, CellularBase is added which will now servce as the base class for all
upcoming drivers.
* Special restructuring for the driver has been undertaken. This makes a clear cut distinction
between an on-board or an off-board implementation.
- PPPCellularInterface is a generic network interface that works with a generic FileHandle
and PPP. A derived class is needed to pass that FileHandle.
- PPPCellularInterface provides some base functionality like network registration, AT setup,
PPP connection etc. Lower level job is delegated to the derived classes and various modem
specific APIs are provided which are supposed to be overridden.
- UARTCellularInterface is derived from PPPCellularInterface. It constructs a FileHandle and
passes it back to PPPCellularInterface as well as provides modem hangupf functionality.
In future we could proive a USBInterface that would derive from PPPCellularInterface and could
pass the FileHandle back.
- OnboardCellularInterface is derived from UARTCellularInterfae and provides hooks to
the target provided implementation of onbard_modem_api.h. An off-board modem, i.e, a modem on
a shield has to override the modem_init(), modem_power_up() etc as it cannot use
onboard_modem_api.h.
mbed::fdopen() is provided in mbed_retarget.cpp which will attach a stream to the
given FileHandle. Removing mbed_set_unbuffered_stream() from stream class as it
is defined in mbed_retarget.cpp. Stream class should not decide whether it wants
to detach buffers from c library or not. mbed::fdopen() will do that based upon
isatty() call. So if a FileHandle is not a tty, i.e., is not a device type, c library
buffering will not be turned off. For device type FileHandles, c library buffering
is turned off.
This has been an attempt to extend existing FileHandle to behave like POSIX
file descriptor for input/output resources/devices too.
This will now provide an abstract indicator/handle any arbitrary file or device
type resource. May be in future, sockets too.
In order to correctly detect availability of read/write a FileHandle, we needed
a select or poll mechanisms. We opted for poll as POSIX defines in
http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html Currently,
mbed::poll() just spins and scans filehandles looking for any events we are
interested in. In future, his spinning behaviour will be replaced with
condition variables.
In retarget.cpp we have introduced an mbed::fdopen() function which is
equivalent to C fdopen(). It attaches a std stream to our FileHandle stream.
newlib-nano somehow does not seem to call isatty() so retarget doesn't work for
device type file handles. We handle this by checking ourselves in
mbed::fdopen() if we wish to attach our stream to std stream. We also turn off
buffering by C library as our stuff will be buffered already.
sigio() is also provided, matching the API of the Socket class, with a view to
future unification. As well as unblocking poll(), _poll_change calls the user
sigio callback if an event happens, i.e., when FileHandle becomes
readable/writable.
virtual int write(const char *tx_buffer, int tx_length,
char *rx_buffer, int rx_length);
The main benefit of block-level SPI writes is the performance
improvement from not acquiring a mutex lock between each byte sent on
the SPI bus. The block write may also be poked through the hal level for
additional speed improvements.