mirror of https://github.com/ARMmbed/mbed-os.git
Using DCD line to invoke poll() HUP
POSIX poll() provides a mechanism to attach a POLL_HUP event if the modem or device hangs up on you. POLL_HUP and POLL_OUT are mutually exclusive. We poll in the PPP_input() routine if the modem hung up. If it did we stop the data consumption, close PPP and go back to the driver for reserruction of AT parser and subsequent retries or application specific actions. This is achieved by attaching an interrupt to the DCD line of the modem. When DCD line goes high (off), we have lost the carrier. So we record an POLLHUP event using _poll_change().pull/4119/head
parent
87a4580e5f
commit
93f436ebe0
|
@ -197,47 +197,22 @@ static void ppp_link_status(ppp_pcb *pcb, int err_code, void *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This should be in the switch case, this is put outside of the switch
|
||||
* case for example readability.
|
||||
*/
|
||||
|
||||
if (err_code == PPPERR_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* ppp_close() was previously called, don't reconnect */
|
||||
if (err_code == PPPERR_USER) {
|
||||
/* ppp_free(); -- can be called here */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to reconnect in 30 seconds, if you need a modem chatscript you have
|
||||
* to do a much better signaling here ;-)
|
||||
*/
|
||||
ppp_connect(pcb, 30);
|
||||
/* OR ppp_listen(pcb); */
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void flush(FileHandle *stream)
|
||||
{
|
||||
char buffer[8];
|
||||
for (;;) {
|
||||
ssize_t ret = stream->read(buffer, sizeof buffer);
|
||||
if (ret <= 0) {
|
||||
break;
|
||||
ppp_link_up = true;
|
||||
} else {
|
||||
if (ppp_link_up) {
|
||||
ppp_link_up = false;
|
||||
sys_sem_signal(&ppp_close_sem);
|
||||
}
|
||||
}
|
||||
|
||||
notify_ppp_link_status(err_code);
|
||||
}
|
||||
|
||||
#if !PPP_INPROC_IRQ_SAFE
|
||||
#error "PPP_INPROC_IRQ_SAFE must be enabled"
|
||||
#endif
|
||||
static void ppp_input(FileHandle *stream)
|
||||
static void ppp_input()
|
||||
{
|
||||
// Allow new events from now, avoiding potential races around the read
|
||||
event_queued = false;
|
||||
|
@ -259,7 +234,7 @@ static void ppp_input(FileHandle *stream)
|
|||
// serial, so we will fairly rapidly hit -EAGAIN.
|
||||
for (;;) {
|
||||
u8_t buffer[16];
|
||||
ssize_t len = stream->read(buffer, sizeof buffer);
|
||||
ssize_t len = my_stream->read(buffer, sizeof buffer);
|
||||
if (len == -EAGAIN) {
|
||||
break;
|
||||
} else if (len <= 0) {
|
||||
|
|
|
@ -26,12 +26,38 @@ namespace mbed {
|
|||
BufferedSerial::BufferedSerial(PinName tx, PinName rx, int baud) :
|
||||
SerialBase(tx, rx, baud),
|
||||
_blocking(true),
|
||||
_tx_irq_enabled(false)
|
||||
_tx_irq_enabled(false),
|
||||
_dcd(NULL)
|
||||
{
|
||||
/* Attatch IRQ routines to the serial device. */
|
||||
SerialBase::attach(callback(this, &BufferedSerial::rx_irq), RxIrq);
|
||||
}
|
||||
|
||||
BufferedSerial::~BufferedSerial()
|
||||
{
|
||||
delete _dcd;
|
||||
}
|
||||
|
||||
void BufferedSerial::DCD_IRQ()
|
||||
{
|
||||
_poll_change(this);
|
||||
}
|
||||
|
||||
void BufferedSerial::set_data_carrier_detect(PinName DCD_pin, bool active_high)
|
||||
{
|
||||
delete _dcd;
|
||||
_dcd = NULL;
|
||||
|
||||
if (DCD_pin != NC) {
|
||||
_dcd = new InterruptIn(DCD_pin);
|
||||
if (active_high) {
|
||||
_dcd->fall(callback(this, &BufferedSerial::DCD_IRQ));
|
||||
} else {
|
||||
_dcd->rise(callback(this, &BufferedSerial::DCD_IRQ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int BufferedSerial::close()
|
||||
{
|
||||
/* Does not let us pass a file descriptor. So how to close ?
|
||||
|
@ -133,18 +159,28 @@ ssize_t BufferedSerial::read(void* buffer, size_t length)
|
|||
return data_read;
|
||||
}
|
||||
|
||||
bool BufferedSerial::hup() const
|
||||
{
|
||||
return _dcd && _dcd->read() != 0;
|
||||
}
|
||||
|
||||
short BufferedSerial::poll(short events) const {
|
||||
|
||||
short revents = 0;
|
||||
/* Check the Circular Buffer if space available for writing out */
|
||||
if (!_txbuf.full()) {
|
||||
revents |= POLLOUT;
|
||||
}
|
||||
|
||||
|
||||
if (!_rxbuf.empty()) {
|
||||
revents |= POLLIN;
|
||||
}
|
||||
|
||||
/* POLLHUP and POLLOUT are mutually exclusive */
|
||||
if (hup()) {
|
||||
revents |= POLLHUP;
|
||||
} else if (!_txbuf.full()) {
|
||||
revents |= POLLOUT;
|
||||
}
|
||||
|
||||
/*TODO Handle other event types */
|
||||
|
||||
return revents;
|
||||
|
@ -200,12 +236,11 @@ void BufferedSerial::tx_irq(void)
|
|||
}
|
||||
|
||||
/* Report the File handler that data can be written to peripheral. */
|
||||
if (was_full && !_txbuf.full()) {
|
||||
if (was_full && !_txbuf.full() && !hup()) {
|
||||
_poll_change(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //namespace mbed
|
||||
|
||||
#endif //DEVICE_SERIAL
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "FileHandle.h"
|
||||
#include "SerialBase.h"
|
||||
#include "InterruptIn.h"
|
||||
#include "PlatformMutex.h"
|
||||
#include "serial_api.h"
|
||||
#include "CircularBuffer.h"
|
||||
|
@ -36,6 +37,7 @@ public:
|
|||
* @param baud The baud rate of the serial port (optional, defaults to MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
|
||||
*/
|
||||
BufferedSerial(PinName tx, PinName rx, int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
virtual ~BufferedSerial();
|
||||
|
||||
/** Equivalent to POSIX poll(). Derived from FileHandle.
|
||||
* Provides a mechanism to multiplex input/output over a set of file handles.
|
||||
|
@ -62,6 +64,8 @@ public:
|
|||
|
||||
virtual int set_blocking(bool blocking) { _blocking = blocking; return 0; }
|
||||
|
||||
void set_data_carrier_detect(PinName DCD_pin, bool active_high=false);
|
||||
|
||||
private:
|
||||
|
||||
/** Software serial buffers
|
||||
|
@ -74,8 +78,14 @@ private:
|
|||
|
||||
bool _blocking;
|
||||
bool _tx_irq_enabled;
|
||||
InterruptIn *_dcd;
|
||||
|
||||
|
||||
/** Device Hanged up
|
||||
* Determines if the device hanged up on us.
|
||||
*
|
||||
* @return True, if hanged up
|
||||
*/
|
||||
bool hup() const;
|
||||
|
||||
/** ISRs for serial
|
||||
* Routines to handle interrupts on serial pins.
|
||||
|
@ -85,7 +95,7 @@ private:
|
|||
void tx_irq(void);
|
||||
void rx_irq(void);
|
||||
|
||||
|
||||
void DCD_IRQ(void);
|
||||
};
|
||||
} //namespace mbed
|
||||
|
||||
|
|
Loading…
Reference in New Issue