removed Reader_Mutex, IOMutex, rs485_read_task and placed select inside of getting characters call to reduce CPU usage.

This commit is contained in:
skarg
2011-08-19 16:33:07 +00:00
parent bcd1c2c101
commit 0fe647a678
+21 -51
View File
@@ -60,7 +60,6 @@
#include "rs485.h" #include "rs485.h"
#include "fifo.h" #include "fifo.h"
#include <pthread.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/time.h> #include <sys/time.h>
@@ -89,46 +88,10 @@ static struct termios RS485_oldtio;
/* Ring buffer for incoming bytes, in order to speed up the receiving. */ /* Ring buffer for incoming bytes, in order to speed up the receiving. */
static FIFO_BUFFER Rx_FIFO; static FIFO_BUFFER Rx_FIFO;
/* buffer size needs to be a power of 2 */ /* buffer size needs to be a power of 2 */
static uint8_t Rx_Buffer[1 << 12]; static uint8_t Rx_Buffer[4096];
static pthread_mutex_t Reader_Mutex, IOMutex;
#define _POSIX_SOURCE 1 /* POSIX compliant source */ #define _POSIX_SOURCE 1 /* POSIX compliant source */
static void *rs485_read_task(
void *arg)
{
uint8_t buf[1 << 11];
int count, n;
fd_set input;
struct timeval cekalica;
FD_ZERO(&input);
FD_SET(RS485_Handle, &input);
cekalica.tv_sec = 1;
cekalica.tv_usec = 0;
for (;;) {
n = select(RS485_Handle + 1, &input, NULL, NULL, &cekalica);
if (n < 0) {
continue;
}
if (FD_ISSET(RS485_Handle, &input)) {
pthread_mutex_lock(&IOMutex);
count = read(RS485_Handle, buf, sizeof(buf));
pthread_mutex_unlock(&IOMutex);
if (count > 0) {
pthread_mutex_lock(&Reader_Mutex);
FIFO_Add(&Rx_FIFO, &buf[0], count);
pthread_mutex_unlock(&Reader_Mutex);
}
usleep(5000);
}
FD_SET(RS485_Handle, &input);
cekalica.tv_sec = 1;
cekalica.tv_usec = 0;
}
return NULL;
}
/********************************************************************* /*********************************************************************
* DESCRIPTION: Configures the interface name * DESCRIPTION: Configures the interface name
* RETURN: none * RETURN: none
@@ -234,12 +197,11 @@ void RS485_Send_Frame(
regular file, 0 will be returned without causing any other effect. For regular file, 0 will be returned without causing any other effect. For
a special file, the results are not portable. a special file, the results are not portable.
*/ */
pthread_mutex_lock(&IOMutex);
written = write(RS485_Handle, buffer, nbytes); written = write(RS485_Handle, buffer, nbytes);
pthread_mutex_unlock(&IOMutex);
greska = errno; greska = errno;
if (written <= 0) if (written <= 0) {
printf("write error: %s\n", strerror(greska)); printf("write error: %s\n", strerror(greska));
}
/* tcdrain(RS485_Handle); */ /* tcdrain(RS485_Handle); */
/* per MSTP spec, sort of */ /* per MSTP spec, sort of */
if (mstp_port) { if (mstp_port) {
@@ -253,21 +215,35 @@ void RS485_Send_Frame(
void RS485_Check_UART_Data( void RS485_Check_UART_Data(
volatile struct mstp_port_struct_t *mstp_port) volatile struct mstp_port_struct_t *mstp_port)
{ {
fd_set input;
struct timeval waiter;
uint8_t buf[2048];
int n;
if (mstp_port->ReceiveError == true) { if (mstp_port->ReceiveError == true) {
/* wait for state machine to clear this */ /* wait for state machine to clear this */
/*mstp_port->ReceiveError=false; */ /*mstp_port->ReceiveError=false; */
return; return;
} }
/* wait for state machine to read from the DataRegister */ /* wait for state machine to read from the DataRegister */
/*else */
if (mstp_port->DataAvailable == false) { if (mstp_port->DataAvailable == false) {
/* check for data */ /* check for data */
pthread_mutex_lock(&Reader_Mutex);
if (FIFO_Count(&Rx_FIFO) > 0) { if (FIFO_Count(&Rx_FIFO) > 0) {
mstp_port->DataRegister = FIFO_Get(&Rx_FIFO); mstp_port->DataRegister = FIFO_Get(&Rx_FIFO);
mstp_port->DataAvailable = true; mstp_port->DataAvailable = true;
} } else {
pthread_mutex_unlock(&Reader_Mutex); FD_ZERO (&input);
FD_SET (RS485_Handle, &input);
waiter.tv_sec = 0;
waiter.tv_usec = 5000;
n = select (RS485_Handle + 1, &input, NULL, NULL, &waiter);
if (n < 0) {
return;
}
if (FD_ISSET(RS485_Handle, &input)) {
count = read(RS485_Handle, buf, sizeof(buf));
FIFO_Add(&Rx_FIFO, &buf[0], count);
}
} }
} }
@@ -277,8 +253,6 @@ void RS485_Cleanup(
/* restore the old port settings */ /* restore the old port settings */
tcsetattr(RS485_Handle, TCSANOW, &RS485_oldtio); tcsetattr(RS485_Handle, TCSANOW, &RS485_oldtio);
close(RS485_Handle); close(RS485_Handle);
pthread_mutex_destroy(&Reader_Mutex);
pthread_mutex_destroy(&IOMutex);
} }
@@ -286,7 +260,6 @@ void RS485_Initialize(
void) void)
{ {
struct termios newtio; struct termios newtio;
unsigned long hThread = 0;
printf("RS485: Initializing %s", RS485_Port_Name); printf("RS485: Initializing %s", RS485_Port_Name);
/* /*
Open device for reading and writing. Open device for reading and writing.
@@ -332,9 +305,6 @@ void RS485_Initialize(
tcflush(RS485_Handle, TCIOFLUSH); tcflush(RS485_Handle, TCIOFLUSH);
/* ringbuffer */ /* ringbuffer */
FIFO_Init(&Rx_FIFO, Rx_Buffer, sizeof(Rx_Buffer)); FIFO_Init(&Rx_FIFO, Rx_Buffer, sizeof(Rx_Buffer));
pthread_mutex_init(&Reader_Mutex, NULL);
pthread_mutex_init(&IOMutex, NULL);
pthread_create(&hThread, NULL, rs485_read_task, NULL);
printf("=success!\n"); printf("=success!\n");
} }