serial on linux tweaks

This commit is contained in:
Gordon Williams 2014-11-19 16:22:23 +00:00
parent f0d5bcf866
commit 47d809c7ff
2 changed files with 27 additions and 14 deletions

View File

@ -32,7 +32,7 @@ typedef struct {
unsigned char data; // data to transmit
} PACKED_FLAGS TxBufferItem;
TxBufferItem txBuffer[TXBUFFERMASK+1];
volatile TxBufferItem txBuffer[TXBUFFERMASK+1];
volatile unsigned char txHead=0, txTail=0;
typedef enum {
@ -154,7 +154,7 @@ bool jshHasTransmitData() {
// ----------------------------------------------------------------------------
// IO EVENT BUFFER
IOEvent ioBuffer[IOBUFFERMASK+1];
volatile IOEvent ioBuffer[IOBUFFERMASK+1];
volatile unsigned char ioHead=0, ioTail=0;
// ----------------------------------------------------------------------------
@ -175,6 +175,7 @@ void jshPushIOCharEvent(IOEventFlags channel, char charData) {
jshSetFlowControlXON(channel, false);
// Check for existing buffer (we must have at least 2 in the queue to avoid dropping chars though!)
unsigned char nextTail = (unsigned char)((ioTail+1) & IOBUFFERMASK);
#ifndef LINUX // no need for this on linux, and also potentially dodgy when multi-threading
if (ioHead!=ioTail && ioHead!=nextTail) {
// we can do this because we only read in main loop, and we're in an interrupt here
unsigned char lastHead = (unsigned char)((ioHead+IOBUFFERMASK) & IOBUFFERMASK); // one behind head
@ -187,6 +188,7 @@ void jshPushIOCharEvent(IOEventFlags channel, char charData) {
return;
}
}
#endif
// Make new buffer
unsigned char nextHead = (unsigned char)((ioHead+1) & IOBUFFERMASK);
if (ioTail == nextHead) {

View File

@ -190,6 +190,8 @@ bool isInitialised;
void jshInputThread() {
while (isInitialised) {
bool shortSleep = false;
/* Handle the delayed Ctrl-C -> interrupt behaviour (see description by EXEC_CTRL_C's definition) */
if (execInfo.execute & EXEC_CTRL_C_WAIT)
execInfo.execute = (execInfo.execute & ~EXEC_CTRL_C_WAIT) | EXEC_INTERRUPTED;
@ -201,31 +203,40 @@ void jshInputThread() {
if (ch<0) break;
jshPushIOCharEvent(EV_USBSERIAL, (char)ch);
}
// Read from any open devices
int i;
for (i=0;i<=EV_DEVICE_MAX;i++) {
if (ioDevices[i]) {
char buf[32];
// read can return -1 (EAGAIN) because O_NONBLOCK is set
int bytes = (int)read(ioDevices[i], buf, sizeof(buf));
if (bytes>0) jshPushIOCharEvents(i, buf, (unsigned int)bytes);
// Read from any open devices - if we have space
if (jshGetEventsUsed() < IOBUFFERMASK/2) {
int i;
for (i=0;i<=EV_DEVICE_MAX;i++) {
if (ioDevices[i]) {
char buf[32];
// read can return -1 (EAGAIN) because O_NONBLOCK is set
int bytes = (int)read(ioDevices[i], buf, sizeof(buf));
if (bytes>0) {
//int j; for (j=0;j<bytes;j++) printf("]] '%c'\r\n", buf[j]);
jshPushIOCharEvents(i, buf, (unsigned int)bytes);
shortSleep = true;
}
}
}
}
// Write any data we have
IOEventFlags device = jshGetDeviceToTransmit();
while (device != EV_NONE) {
char ch = (char)jshGetCharToTransmit(device);
if (ioDevices[device])
//printf("[[ '%c'\r\n", ch);
if (ioDevices[device]) {
write(ioDevices[device], &ch, 1);
shortSleep = true;
}
device = jshGetDeviceToTransmit();
}
bool hasWatches = false;
#ifdef SYSFS_GPIO_DIR
Pin pin;
for (pin=0;pin<JSH_PIN_COUNT;pin++)
if (gpioShouldWatch[pin]) {
hasWatches = true;
shortSleep = true;
bool state = jshPinGetValue(pin);
if (state != gpioLastState[pin]) {
jshPushIOEvent(pinToEVEXTI(pin) | (state?EV_EXTI_IS_HIGH:0), jshGetSystemTime());
@ -234,7 +245,7 @@ void jshInputThread() {
}
#endif
usleep(hasWatches ? 1000 : 50000);
usleep(shortSleep ? 1000 : 50000);
}
}