Concept code which launches two threads, one of which implements a Modbus Tunnel protocol to talk with an ISEM, the other which launches a Modbus RTU protocol to talk to a CPUM (most of the Modbus code has been removed prior to publishing.) A canned AC and DC spectra is provided to display wave forms on start-up however the project normally polls for spectra from the ISEM and then plots is (that functionality has been removed prior to publishing.)
Dependencies: LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI mbed-os BSP_DISCO_F429ZI

Plot of the initial start-up canned AC and DC spectra.
NextGen-Exerciser-Tunnel.cpp
- Committer:
- Damotclese
- Date:
- 2019-05-31
- Revision:
- 2:346119b3db6c
- Parent:
- 0:387684ec9d92
File content as of revision 2:346119b3db6c:
// ----------------------------------------------------------------------
// NextGen-Exerciser-Tunnel.cpp
//
// Fredric L. Rice, May 2019
//
// o A digital output for an LED is instantiated
// o A Serial object is instantiated on Serial-2
// o A thread's mailbox object is instantiated
// o A Thread object is instantiated
// o The serial interface is configured
// o The module's thread is start()ed
//
// The LED is toggled according to timing established by a periodic
// wait() and according to messages pending in the thread's mailbox
//
// The mailbox is checked for any messages that need to go out the
// serial interface, and if there are any, the message is extracted
// from the mailbox and gets sent out the serial interface. If there
// are no messages waiting to go out, a Modbus polling message is
// sent out the serial interface instead.
//
// If there is serial data waiting to be read, the data is collected
// in to a Modbus frame and it gets handled by examining the content
// of the inbound frame.
//
// ----------------------------------------------------------------------
#include "mbed.h" // The mbed operating system
#include "NextGen-Exerciser-Tunnel.h" // Always include ourself
#include "NextGen-Exerciser-Defines.h" // For defined constants and MACROs
// ----------------------------------------------------------------------
// Allocate local data storage
//
// ----------------------------------------------------------------------
static DigitalOut st_digitalOutTunnelLED(LED2);
static Serial st_TunnelSerial(SERIAL_TX, SERIAL_RX); // TX, RX, Serial 2 (Don't see anything)
static Mail<st_pendingMessage, 16> st_TunnelMailbox;
static Thread st_threadTunnel;
static bool b_TunnelInitialized = false;
static char c_flipFlop = 0;
static unsigned char uch_tunnelPollFrame[] =
{
0xF7, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xDE
} ;
// ----------------------------------------------------------------------
// TunnelCheckInbound()
//
// This function will:
// o Check to see if the serial interface is readable
// o If there are bytes waiting, the bytes are read and get
// assembled in to a full Modbus frame.
// o The inbound message is handled by passing it to a function
// which examines the content of the inbound message
//
// ----------------------------------------------------------------------
static void TunnelCheckInbound(void)
{
// See if there is inbound serial data
if (st_TunnelSerial.readable())
{
}
}
// ----------------------------------------------------------------------
// TunnelCheckOutbound()
//
// This function will:
// o Get a message from the thread's mailbox, waiting for up to
// 2 milliseconds for a message
// o If a message is pending, the message is extracted and then
// gets formatted in to an output Modbus message frame
// o The newly-formatted Modbus frame gets transmitted out the
// serial interface
// o The mailbox message gets released back in to the memory pool
// o If there was no output message waiting in the mailbox, a
// Modbus polling message is sent out the serial interface
//
// ----------------------------------------------------------------------
static void TunnelCheckOutbound(void)
{
// Is there an outbound message waiting? Wait for up to 2 milliseconds
osEvent st_eventResult = st_TunnelMailbox.get(2);
if (st_eventResult.status == osEventMail)
{
// Get a pointer to the message
st_pendingMessage * pst_outFrame = (st_pendingMessage *)st_eventResult.value.p;
// Format and send the Modbus Tunnel frame
// Finished with the message so release it even if it was not sent
st_TunnelMailbox.free(pst_outFrame);
}
else
{
// Send a poll frame
st_TunnelSerial.write((uint8_t *)uch_tunnelPollFrame, sizeof(uch_tunnelPollFrame), NULL);
}
}
// ----------------------------------------------------------------------
// TunnelThread()
//
// This function will:
// o Get invoked as a thread under the mbed operating system
// o Turn ON the lED associated with this module and protocol
// o Enter in to a forever loop which wakes up ten times a second
// o Drives the module's LED so that it flashes frim time to time
// to indicate that the thread is running
// o Check to ensure that the module has been initialized
// o If the module is initialized (and it should be) checks to
// see if there are inbound serial Modbus messages
// o Checks to see if there are any outbound serial Modbus messages
//
// ----------------------------------------------------------------------
static void TunnelThread(void)
{
char ch_halfSecond = 5;
// Set the Modbus Tunnel LED to ON to indicate that the thread has started
st_digitalOutTunnelLED = 1;
// Enter in to a forever loop
while (true)
{
// Sleep for one tenth of a second
wait(0.1);
// Count down the half second timer and see if it expired
if (0 == --ch_halfSecond)
{
// It has expired so restart the half second time
ch_halfSecond = 5;
// See if we turn on or turn off the LED
if (0 == c_flipFlop)
{
c_flipFlop = 1;
}
else
{
c_flipFlop = 0;
}
st_digitalOutTunnelLED = c_flipFlop;
}
// We check to see if there is inbound or outbound serial traffic 10 times a second
if (TRUE == b_TunnelInitialized)
{
// Check for inbound Modbus Tunnel frames
TunnelCheckInbound();
// See if we need to send outbound Tunnel frames
TunnelCheckOutbound();
}
}
}
// ----------------------------------------------------------------------
// TunnelInit()
//
// This function will:
// o Initialize the module protocol's serial interface
// o Flag the fact that things are initialized
// o Launch the module's thread
//
// ----------------------------------------------------------------------
void TunnelInit(void)
{
// We configure the Modbus Tunnel serial interface
st_TunnelSerial.baud(115200);
st_TunnelSerial.format(8, SerialBase::None, 1);
// Flag the fact that the module has been initialized
b_TunnelInitialized = true;
// Launch the Modbus Tunnel thread
st_threadTunnel.start(TunnelThread);
}
// End of file