mirror of
https://github.com/thiagoralves/OpenPLC.git
synced 2025-05-09 00:21:52 +08:00
Added persistent storage to the OpenPLC! :)
This commit is contained in:
parent
5dbfec2d80
commit
b67eea7c13
@ -56,10 +56,10 @@ extern pthread_mutex_t bufferLock;
|
||||
|
||||
//hardware_layer.cpp
|
||||
void initializeHardware();
|
||||
void sendOutput(unsigned char *sendBytes, unsigned char *recvBytes);
|
||||
void updateBuffers();
|
||||
|
||||
//openplc.cpp
|
||||
void sleep_thread(int milliseconds);
|
||||
void *modbusThread();
|
||||
void PlcCycle(void); //read inputs, process them according to the ladder software and set outputs
|
||||
|
||||
@ -71,6 +71,10 @@ void processMessage(unsigned char *buffer, int bufferSize);
|
||||
void *handleConnections(void *arguments);
|
||||
void startServer(int port);
|
||||
|
||||
//persistent_storage.cpp
|
||||
void *persistentStorage(void *args);
|
||||
int readPersistentStorage();
|
||||
|
||||
//modbus.cpp
|
||||
//Declaration of the supported modbus functions and the respective function code
|
||||
enum MB_FC
|
||||
|
@ -34,6 +34,18 @@ using namespace std;
|
||||
pthread_mutex_t bufferLock; //mutex for the internal buffers
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper function - Makes the running thread sleep for the ammount of time
|
||||
// in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
void sleep_thread(int milliseconds)
|
||||
{
|
||||
struct timespec ts;
|
||||
ts.tv_sec = milliseconds / 1000;
|
||||
ts.tv_nsec = (milliseconds % 1000) * 1000000;
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
void *modbusThread(void *arg)
|
||||
{
|
||||
startServer(502);
|
||||
@ -70,14 +82,20 @@ int main(void)
|
||||
//======================================================
|
||||
initializeHardware();
|
||||
updateBuffers();
|
||||
|
||||
struct timespec timer_start;
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, modbusThread, NULL);
|
||||
|
||||
//======================================================
|
||||
// PERSISTENT STORAGE INITIALIZATION
|
||||
//======================================================
|
||||
readPersistentStorage();
|
||||
pthread_t persistentThread;
|
||||
pthread_create(&persistentThread, NULL, persistentStorage, NULL);
|
||||
|
||||
//======================================================
|
||||
// MAIN LOOP
|
||||
//======================================================
|
||||
struct timespec timer_start;
|
||||
for(;;)
|
||||
{
|
||||
clock_gettime(CLOCK_MONOTONIC, &timer_start);
|
||||
@ -85,6 +103,7 @@ int main(void)
|
||||
while (measureTime(&timer_start) < OPLC_CYCLE)
|
||||
{
|
||||
updateBuffers();
|
||||
sleep_thread(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
107
core/persistent_storage.cpp
Normal file
107
core/persistent_storage.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2015 Thiago Alves
|
||||
// This file is part of the OpenPLC Software Stack.
|
||||
//
|
||||
// OpenPLC is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// OpenPLC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with OpenPLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
//------
|
||||
//
|
||||
// This file is responsible for the persistent storage on the OpenPLC
|
||||
// Thiago Alves, Mar 2016
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "ladder.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main function for the thread. Should create a buffer for the persistent
|
||||
// data, compare it with the actual data and write back to the persistent
|
||||
// file if the data has changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void *persistentStorage(void *args)
|
||||
{
|
||||
SWORD persistentBuffer[BUFFER_SIZE];
|
||||
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
for (int i = 0; i < BUFFER_SIZE; i++)
|
||||
{
|
||||
persistentBuffer[i] = AnalogOutputBuffer0[i];
|
||||
}
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
|
||||
while (1)
|
||||
{
|
||||
//printf("checking data...\n");
|
||||
bool bufferOutdated = false;
|
||||
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
for (int i = 0; i < BUFFER_SIZE; i++)
|
||||
{
|
||||
if (persistentBuffer[i] != AnalogOutputBuffer0[i])
|
||||
{
|
||||
persistentBuffer[i] = AnalogOutputBuffer0[i];
|
||||
bufferOutdated = true;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
|
||||
if (bufferOutdated)
|
||||
{
|
||||
//printf("writing data to disk...\n");
|
||||
FILE *fd = fopen("persistent.file", "w"); //if file already exists, it will be overwritten
|
||||
if (fd == NULL)
|
||||
{
|
||||
printf("Error creating persistent memory file!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fwrite(persistentBuffer, sizeof(SWORD), BUFFER_SIZE, fd) < BUFFER_SIZE)
|
||||
{
|
||||
printf("Error writing to persistent memory file!\n");
|
||||
return 0;
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
sleep_thread(1000);
|
||||
}
|
||||
}
|
||||
|
||||
int readPersistentStorage()
|
||||
{
|
||||
FILE *fd = fopen("persistent.file", "r");
|
||||
if (fd == NULL)
|
||||
{
|
||||
printf("Error openning persistent memory file, or file doesn't exists!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SWORD persistentBuffer[BUFFER_SIZE];
|
||||
|
||||
if (fread(persistentBuffer, sizeof(SWORD), BUFFER_SIZE, fd) < BUFFER_SIZE)
|
||||
{
|
||||
printf("Error while trying to read the persistent memory file!\n");
|
||||
return 0;
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
for (int i = 0; i < BUFFER_SIZE; i++)
|
||||
{
|
||||
AnalogOutputBuffer0[i] = persistentBuffer[i];
|
||||
}
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user