mirror of
https://github.com/thiagoralves/OpenPLC_v2.git
synced 2025-05-09 00:21:11 +08:00
Merge pull request #4 from 0ussama/scancycle
Separates the input and output updates in two functions. This improves OpenPLC scan cycle as it starts processing with an accurate representation of the inputs.
This commit is contained in:
commit
d9bad37a94
@ -560,10 +560,10 @@ void initializeHardware()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual I/O state. The mutex bufferLock
|
||||
// must be updated to reflect the actual Input state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffers()
|
||||
void updateBuffersIn()
|
||||
{
|
||||
//Lock mutexes
|
||||
pthread_mutex_lock(&bufferLock);
|
||||
@ -581,6 +581,21 @@ void updateBuffers()
|
||||
if (int_input[i] != NULL) *int_input[i] = input_data.analog[i];
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&ioLock);
|
||||
pthread_mutex_unlock(&bufferLock);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual Output state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersOut()
|
||||
{
|
||||
//Lock mutexes
|
||||
pthread_mutex_lock(&bufferLock);
|
||||
pthread_mutex_lock(&ioLock);
|
||||
|
||||
//Digital Output
|
||||
for (int i = 0; i < (sizeof(output_data.digital)*8); i++)
|
||||
{
|
||||
@ -595,4 +610,4 @@ void updateBuffers()
|
||||
|
||||
pthread_mutex_unlock(&ioLock);
|
||||
pthread_mutex_unlock(&bufferLock);
|
||||
}
|
||||
}
|
@ -42,10 +42,32 @@ void initializeHardware()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual I/O state. The mutex bufferLock
|
||||
// must be updated to reflect the actual Input state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffers()
|
||||
void updateBuffersIn()
|
||||
{
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
|
||||
/*********READING AND WRITING TO I/O**************
|
||||
|
||||
*bool_input[0][0] = read_digital_input(0);
|
||||
write_digital_output(0, *bool_output[0][0]);
|
||||
|
||||
*int_input[0] = read_analog_input(0);
|
||||
write_analog_output(0, *int_output[0]);
|
||||
|
||||
**************************************************/
|
||||
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual Output state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersOut()
|
||||
{
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
|
||||
|
@ -244,12 +244,22 @@ void initializeHardware()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual I/O state. The mutex bufferLock
|
||||
// must be updated to reflect the actual Input state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffers()
|
||||
void updateBuffersIn()
|
||||
{
|
||||
//The thread created in initializeHardware is already updating
|
||||
//OpenPLC's buffers. So this function should do nothing.
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual Output state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersOut()
|
||||
{
|
||||
//The thread created in initializeHardware is already updating
|
||||
//OpenPLC's buffers. So this function should do nothing.
|
||||
}
|
@ -138,10 +138,53 @@ void sendOutput(unsigned char *sendBytes, unsigned char *recvBytes)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual I/O state. The mutex buffer_lock
|
||||
// must be updated to reflect the actual Input state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffers()
|
||||
void updateBuffersIn()
|
||||
{
|
||||
unsigned char sendBytes[3], recvBytes[6], i;
|
||||
sendBytes[0] = 0xC2; //read and write IO for both modules
|
||||
sendBytes[1] = 0; //make sure output is off
|
||||
sendBytes[2] = 0; //make sure output is off
|
||||
|
||||
pthread_mutex_lock(&bufferLock);
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
if (bool_output[0][i] != NULL) sendBytes[1] = sendBytes[1] | (*bool_output[0][i] << i); //write each bit
|
||||
}
|
||||
for (i=8; i<16; i++)
|
||||
{
|
||||
if (bool_output[1][i%8] != NULL) sendBytes[2] = sendBytes[2] | (*bool_output[1][i%8] << (i-8)); //write each bit
|
||||
}
|
||||
pthread_mutex_unlock(&bufferLock);
|
||||
|
||||
sendOutput(sendBytes, recvBytes);
|
||||
|
||||
pthread_mutex_lock(&bufferLock);
|
||||
//if (int_input[0] != NULL) *int_input[0] = (int)(recvBytes[2] << 8) | (int)recvBytes[3]; //EX
|
||||
//if (int_input[1] != NULL) *int_input[1] = (int)(recvBytes[4] << 8) | (int)recvBytes[5]; //EY
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
if (bool_input[0][i] != NULL) *bool_input[0][i] = (recvBytes[0] >> i) & 0x01;
|
||||
//printf("%d\t", DiscreteInputBuffer0[i]);
|
||||
}
|
||||
for (i=8; i<16; i++)
|
||||
{
|
||||
if (bool_input[1][i%8] != NULL) *bool_input[1][i%8] = (recvBytes[1] >> (i-8)) & 0x01;
|
||||
//printf("%d\t", DiscreteInputBuffer0[i]);
|
||||
}
|
||||
//printf("\n");
|
||||
pthread_mutex_unlock(&bufferLock);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual Output state. The mutex buffer_lock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersOut()
|
||||
{
|
||||
unsigned char sendBytes[3], recvBytes[6], i;
|
||||
sendBytes[0] = 0xC2; //read and write IO for both modules
|
||||
|
@ -486,10 +486,10 @@ void initializeHardware()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual I/O state. The mutex bufferLock
|
||||
// must be updated to reflect the actual Input state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffers()
|
||||
void updateBuffersIn()
|
||||
{
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
pthread_mutex_lock(&ioLock);
|
||||
@ -498,6 +498,25 @@ void updateBuffers()
|
||||
{
|
||||
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bool_input_buf[i];
|
||||
if (int_input[i] != NULL) *int_input[i] = int_input_buf[i];
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&ioLock);
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual Output state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersOut()
|
||||
{
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
pthread_mutex_lock(&ioLock);
|
||||
|
||||
for (int i = 0; i < MAX_MB_IO; i++)
|
||||
{
|
||||
if (bool_output[i/8][i%8] != NULL) bool_output_buf[i] = *bool_output[i/8][i%8];
|
||||
if (int_output[i] != NULL) int_output_buf[i] = *int_output[i];
|
||||
}
|
||||
|
@ -819,10 +819,10 @@ void initializeHardware()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual I/O state. The mutex buffer_lock
|
||||
// must be updated to reflect the actual Input state. The mutex buffer_lock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffers()
|
||||
void updateBuffersIn()
|
||||
{
|
||||
//lock mutexes
|
||||
pthread_mutex_lock(&bufferLock);
|
||||
@ -834,6 +834,30 @@ void updateBuffers()
|
||||
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byDigIn, i);
|
||||
}
|
||||
|
||||
//ANALOG IN
|
||||
uint16_t *analogInputs;
|
||||
analogInputs = &InputData.wAi0;
|
||||
for (int i = 0; i < MAX_ANALOG_IN; i++)
|
||||
{
|
||||
if (int_input[i] != NULL) *int_input[i] = analogInputs[i];
|
||||
}
|
||||
|
||||
//unlock mutexes
|
||||
pthread_mutex_unlock(&localBufferLock);
|
||||
pthread_mutex_unlock(&bufferLock);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual Output state. The mutex buffer_lock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersOut()
|
||||
{
|
||||
//lock mutexes
|
||||
pthread_mutex_lock(&bufferLock);
|
||||
pthread_mutex_lock(&localBufferLock);
|
||||
|
||||
//DIGITAL OUTPUT
|
||||
for (int i = 0; i < MAX_DIG_OUT; i++)
|
||||
{
|
||||
@ -847,14 +871,6 @@ void updateBuffers()
|
||||
}
|
||||
}
|
||||
|
||||
//ANALOG IN
|
||||
uint16_t *analogInputs;
|
||||
analogInputs = &InputData.wAi0;
|
||||
for (int i = 0; i < MAX_ANALOG_IN; i++)
|
||||
{
|
||||
if (int_input[i] != NULL) *int_input[i] = analogInputs[i];
|
||||
}
|
||||
|
||||
//ANALOG OUT
|
||||
uint16_t *analogOutputs;
|
||||
uint16_t *pwmOutputs;
|
||||
@ -875,4 +891,4 @@ void updateBuffers()
|
||||
//unlock mutexes
|
||||
pthread_mutex_unlock(&localBufferLock);
|
||||
pthread_mutex_unlock(&bufferLock);
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@
|
||||
|
||||
#define MAX_INPUT 14
|
||||
#define MAX_OUTPUT 11
|
||||
#define MAX_ANALOG_OUT 1
|
||||
#define MAX_ANALOG_OUT 1
|
||||
|
||||
/********************I/O PINS CONFIGURATION*********************
|
||||
* A good source for RaspberryPi I/O pins information is:
|
||||
@ -91,10 +91,10 @@ void initializeHardware()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual I/O state. The mutex buffer_lock
|
||||
// must be updated to reflect the actual state of the input pins. The mutex buffer_lock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffers()
|
||||
void updateBuffersIn()
|
||||
{
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
|
||||
@ -104,6 +104,18 @@ void updateBuffers()
|
||||
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = digitalRead(inBufferPinMask[i]);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual state of the output pins. The mutex buffer_lock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersOut()
|
||||
{
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
|
||||
//OUTPUT
|
||||
for (int i = 0; i < MAX_OUTPUT; i++)
|
||||
{
|
||||
@ -118,4 +130,3 @@ void updateBuffers()
|
||||
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
}
|
||||
|
||||
|
@ -159,10 +159,22 @@ void initializeHardware()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual I/O state. The mutex bufferLock
|
||||
// must be updated to reflect the actual Input state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffers()
|
||||
void updateBuffersIn()
|
||||
{
|
||||
// This function here is blank because the thread that connects to the
|
||||
// Interface program is already filling the OpenPLC buffers with the
|
||||
// data that is being received.
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual Output state. The mutex bufferLock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersOut()
|
||||
{
|
||||
// This function here is blank because the thread that connects to the
|
||||
// Interface program is already filling the OpenPLC buffers with the
|
||||
|
@ -173,10 +173,10 @@ void initializeHardware()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual I/O state. The mutex buffer_lock
|
||||
// must be updated to reflect the actual Input state. The mutex buffer_lock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffers()
|
||||
void updateBuffersIn()
|
||||
{
|
||||
//printf("Digital Inputs:\n");
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
@ -185,12 +185,6 @@ void updateBuffers()
|
||||
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = !digitalRead(inputPinMask[i]); //printf("[IO%d]: %d | ", i, !digitalRead(inputPinMask[i]));
|
||||
}
|
||||
|
||||
//printf("\nDigital Outputs:\n");
|
||||
for (int i = 0; i < MAX_OUTPUT; i++)
|
||||
{
|
||||
if (bool_output[i/8][i%8] != NULL) digitalWrite(DOUT_PINBASE + i, *bool_output[i/8][i%8]); //printf("[IO%d]: %d | ", i, digitalRead(DOUT_PINBASE + i));
|
||||
}
|
||||
|
||||
//printf("\nAnalog Inputs:");
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
@ -198,7 +192,24 @@ void updateBuffers()
|
||||
}
|
||||
//printf("\n");
|
||||
|
||||
if(int_output[0] != NULL) pwmWrite(ANALOG_OUT_PIN, *int_output[0]);
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual Output state. The mutex buffer_lock
|
||||
// must be used to protect access to the buffers on a threaded environment.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersOut()
|
||||
{
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
|
||||
//printf("\nDigital Outputs:\n");
|
||||
for (int i = 0; i < MAX_OUTPUT; i++)
|
||||
{
|
||||
if (bool_output[i/8][i%8] != NULL) digitalWrite(DOUT_PINBASE + i, *bool_output[i/8][i%8]); //printf("[IO%d]: %d | ", i, digitalRead(DOUT_PINBASE + i));
|
||||
}
|
||||
if(int_output[0] != NULL) pwmWrite(ANALOG_OUT_PIN, *int_output[0]);
|
||||
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
}
|
@ -202,27 +202,31 @@ int main(int argc,char **argv)
|
||||
printf("WARNING: Failed to lock memory\n");
|
||||
}
|
||||
#endif
|
||||
//gets the starting point for the clock
|
||||
printf("Getting current time\n");
|
||||
struct timespec timer_start;
|
||||
clock_gettime(CLOCK_MONOTONIC, &timer_start);
|
||||
|
||||
//======================================================
|
||||
// MAIN LOOP
|
||||
//======================================================
|
||||
for(;;)
|
||||
{
|
||||
//make sure the buffer pointers are correct and
|
||||
//attached to the user variables
|
||||
glueVars();
|
||||
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
config_run__(tick++);
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
//gets the starting point for the clock
|
||||
printf("Getting current time\n");
|
||||
struct timespec timer_start;
|
||||
clock_gettime(CLOCK_MONOTONIC, &timer_start);
|
||||
|
||||
updateBuffers();
|
||||
updateTime();
|
||||
//======================================================
|
||||
// MAIN LOOP
|
||||
//======================================================
|
||||
for(;;)
|
||||
{
|
||||
//make sure the buffer pointers are correct and
|
||||
//attached to the user variables
|
||||
glueVars();
|
||||
|
||||
updateBuffersIn(); //read input image
|
||||
|
||||
sleep_until(&timer_start, common_ticktime__);
|
||||
}
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
config_run__(tick++); // execute plc program logic
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
|
||||
updateBuffersOut(); //write output image
|
||||
|
||||
updateTime();
|
||||
|
||||
sleep_until(&timer_start, common_ticktime__);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user