--- a/modbus/mb_runtime.c Thu Aug 13 18:42:02 2020 +0100
+++ b/modbus/mb_runtime.c Thu Aug 13 19:00:38 2020 +0100
@@ -436,46 +436,6 @@
-/* Function to activate a client node's thread */
-/* returns -1 if it could not send the signal */
-static int __signal_client_thread(int client_node_id) {
- /* We TRY to signal the client thread.
- * We do this because this function can be called at the end of the PLC scan cycle
- * and we don't want it to block at that time.
- if (pthread_mutex_trylock(&(client_nodes[client_node_id].mutex)) != 0)
- client_nodes[client_node_id].execute_req = 1; // tell the thread to execute
- pthread_cond_signal (&(client_nodes[client_node_id].condv));
- pthread_mutex_unlock(&(client_nodes[client_node_id].mutex));
-/* Function that will be called whenever a client node's periodic timer expires. */
-/* The client node's thread will be waiting on a condition variable, so this function simply signals that
- * The same callback function is called by the timers of all client nodes. The id of the client node
- * in question will be passed as a parameter to the call back function.
-void __client_node_timer_callback_function(int client_node_id) {
- /* signal the client node's condition variable on which the client node's thread should be waiting... */
- /* Since the communication cycle is run with the mutex locked, we use trylock() instead of lock() */
- if (pthread_mutex_trylock (&(client_nodes[client_node_id].mutex)) != 0)
- /* we never get to signal the thread for activation. But that is OK.
- * If it still in the communication cycle (during which the mutex is kept locked)
- * then that means that the communication cycle is falling behing in the periodic
- * communication cycle, and we therefore need to skip a period.
- client_nodes[client_node_id].execute_req = 1; // tell the thread to execute
- client_nodes[client_node_id].periodic_act = 1; // tell the thread the activation was done by periodic timer
- pthread_cond_signal (&(client_nodes[client_node_id].condv));
- pthread_mutex_unlock(&(client_nodes[client_node_id].mutex));
/* Thread that simply implements a periodic 'timer',
@@ -528,10 +488,24 @@
while (0 != clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_cycle, NULL));
- __client_node_timer_callback_function(client_node_id);
+ /* signal the client node's condition variable on which the client node's thread should be waiting... */ + /* Since the communication cycle is run with the mutex locked, we use trylock() instead of lock() */ + if (pthread_mutex_trylock (&(client_nodes[client_node_id].mutex)) == 0) { + client_nodes[client_node_id].execute_req = 1; // tell the thread to execute + client_nodes[client_node_id].periodic_act = 1; // tell the thread the activation was done by periodic timer + pthread_cond_signal (&(client_nodes[client_node_id].condv)); + pthread_mutex_unlock(&(client_nodes[client_node_id].mutex)); + /* We never get to signal the thread for activation. But that is OK. + * If it still in the communication cycle (during which the mutex is kept locked) + * then that means that the communication cycle is falling behing in the periodic + * communication cycle, and we therefore need to skip a period.
+ return NULL; // humour the compiler -> will never be executed! @@ -743,13 +717,26 @@
if ((client_requests[index].flag_exec_req != 0) && (0 == client_requests[index].flag_exec_started)) {
int client_node_id = client_requests[index].client_node_id;
- if (__signal_client_thread(client_node_id) >= 0) {
- /* - upon success, set flag_exec_started
- * - both flags (flag_exec_req and flag_exec_started) will be reset
- * once the transaction has completed.
- client_requests[index].flag_exec_started = 1;
+ /* We TRY to signal the client thread. + * We do this because this function can be called at the end of the PLC scan cycle + * and we don't want it to block at that time. + if (pthread_mutex_trylock(&(client_nodes[client_node_id].mutex)) == 0) { + client_nodes[client_node_id].execute_req = 1; // tell the thread to execute + pthread_cond_signal (&(client_nodes[client_node_id].condv)); + pthread_mutex_unlock(&(client_nodes[client_node_id].mutex)); + /* - upon success, set flag_exec_started + * - both flags (flag_exec_req and flag_exec_started) will be reset + * once the transaction has completed. + client_requests[index].flag_exec_started = 1; + /* The mutex is locked => the client thread is currently executing MB transactions. + * We will try to activate it in the next PLC cycle...