examples/modbus: Add Reg Coil support and use it to control USERLEDs
This commit is contained in:
parent
f7880bcca9
commit
0146e88001
@ -50,4 +50,15 @@ config EXAMPLES_MODBUS_REG_HOLDING_NREGS
|
||||
int "Number of holding registers"
|
||||
default 130
|
||||
|
||||
config EXAMPLES_MODBUS_REG_COILS_START
|
||||
int "Coils registers start address"
|
||||
default 3000
|
||||
|
||||
config EXAMPLES_MODBUS_REG_COILS_NREGS
|
||||
int "Number of coils registers"
|
||||
default 32
|
||||
|
||||
config EXAMPLES_MODBUS_REG_COILS_USERLEDS
|
||||
bool "Enable Reg Coils to control USERLEDs"
|
||||
depends on USERLED
|
||||
endif
|
||||
|
@ -71,6 +71,14 @@
|
||||
#include "modbus/mb.h"
|
||||
#include "modbus/mbport.h"
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_MODBUS_REG_COILS_USERLEDS
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <nuttx/leds/userled.h>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@ -108,6 +116,10 @@
|
||||
# define CONFIG_EXAMPLES_MODBUS_REG_HOLDING_NREGS 130
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_MODBUS_REG_COILS_USERLEDS
|
||||
# define CONFIG_USERLEDS_DEVPATH "/dev/userleds"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@ -124,6 +136,10 @@ struct modbus_state_s
|
||||
enum modbus_threadstate_e threadstate;
|
||||
uint16_t reginput[CONFIG_EXAMPLES_MODBUS_REG_INPUT_NREGS];
|
||||
uint16_t regholding[CONFIG_EXAMPLES_MODBUS_REG_HOLDING_NREGS];
|
||||
uint16_t regcoils[CONFIG_EXAMPLES_MODBUS_REG_COILS_NREGS];
|
||||
#ifdef CONFIG_EXAMPLES_MODBUS_REG_COILS_USERLEDS
|
||||
int fd_leds;
|
||||
#endif
|
||||
pthread_t threadid;
|
||||
pthread_mutex_t lock;
|
||||
volatile bool quit;
|
||||
@ -260,6 +276,12 @@ static void *modbus_pollthread(void *pvarg)
|
||||
{
|
||||
eMBErrorCode mberr;
|
||||
int ret;
|
||||
#ifdef CONFIG_EXAMPLES_MODBUS_REG_COILS_USERLEDS
|
||||
int i;
|
||||
userled_set_t ledbit;
|
||||
userled_set_t ledset = 0;
|
||||
userled_set_t supported;
|
||||
#endif
|
||||
|
||||
/* Initialize the modbus */
|
||||
|
||||
@ -273,6 +295,33 @@ static void *modbus_pollthread(void *pvarg)
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
/* Open the USERLED device */
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_MODBUS_REG_COILS_USERLEDS
|
||||
printf("Opening %s\n", CONFIG_USERLEDS_DEVPATH);
|
||||
g_modbus.fd_leds = open(CONFIG_USERLEDS_DEVPATH, O_WRONLY);
|
||||
if (g_modbus.fd_leds < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("ERROR: Failed to open %s: %d\n",
|
||||
CONFIG_USERLEDS_DEVPATH, errcode);
|
||||
goto stop_modbus_exit;
|
||||
}
|
||||
|
||||
/* Get the set of LEDs supported */
|
||||
|
||||
ret = ioctl(g_modbus.fd_leds, ULEDIOC_SUPPORTED,
|
||||
(unsigned long)((uintptr_t)&supported));
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("ERROR: ioctl(ULEDIOC_SUPPORTED) failed: %d\n",
|
||||
errcode);
|
||||
close(g_modbus.fd_leds);
|
||||
goto stop_modbus_exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Then loop until we are commanded to shutdown */
|
||||
|
||||
do
|
||||
@ -288,9 +337,35 @@ static void *modbus_pollthread(void *pvarg)
|
||||
/* Generate some random input */
|
||||
|
||||
g_modbus.reginput[0] = (uint16_t)rand();
|
||||
|
||||
/* If Reg Coils controls USERLEDs, update it! */
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_MODBUS_REG_COILS_USERLEDS
|
||||
ledset = 0;
|
||||
|
||||
for (i = 0; i < CONFIG_EXAMPLES_MODBUS_REG_COILS_NREGS && i < 32; i++)
|
||||
{
|
||||
ledbit = g_modbus.regcoils[i] << i;
|
||||
ledset |= ledbit & supported;
|
||||
}
|
||||
|
||||
ret = ioctl(g_modbus.fd_leds, ULEDIOC_SETALL, ledset);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("ERROR: ioctl(ULEDIOC_SUPPORTED) failed: %d\n",
|
||||
errcode);
|
||||
close(g_modbus.fd_leds);
|
||||
goto stop_modbus_exit;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
while (g_modbus.threadstate != SHUTDOWN);
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_MODBUS_REG_COILS_USERLEDS
|
||||
stop_modbus_exit:
|
||||
#endif
|
||||
|
||||
/* Disable */
|
||||
|
||||
eMBDisable();
|
||||
@ -539,7 +614,50 @@ eMBErrorCode eMBRegHoldingCB(uint8_t *buffer, uint16_t address, uint16_t nregs,
|
||||
eMBErrorCode eMBRegCoilsCB(uint8_t *buffer, uint16_t address, uint16_t ncoils,
|
||||
eMBRegisterMode mode)
|
||||
{
|
||||
return MB_ENOREG;
|
||||
eMBErrorCode mberr = MB_ENOERR;
|
||||
int index;
|
||||
|
||||
if ((address >= CONFIG_EXAMPLES_MODBUS_REG_COILS_START) &&
|
||||
(address + ncoils <=
|
||||
CONFIG_EXAMPLES_MODBUS_REG_COILS_START +
|
||||
CONFIG_EXAMPLES_MODBUS_REG_COILS_NREGS))
|
||||
{
|
||||
index = (int)(address - CONFIG_EXAMPLES_MODBUS_REG_COILS_START);
|
||||
switch (mode)
|
||||
{
|
||||
/* Pass current register values to the protocol stack. */
|
||||
|
||||
case MB_REG_READ:
|
||||
while (ncoils > 0)
|
||||
{
|
||||
*buffer++ = (uint8_t)(g_modbus.regcoils[index] & 0xff);
|
||||
*buffer++ = (uint8_t)(g_modbus.regcoils[index] >> 8);
|
||||
index++;
|
||||
ncoils--;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Update current register values with new values from the
|
||||
* protocol stack.
|
||||
*/
|
||||
|
||||
case MB_REG_WRITE:
|
||||
while (ncoils > 0)
|
||||
{
|
||||
g_modbus.regcoils[index] = *buffer++;
|
||||
g_modbus.regcoils[index] |= *buffer++ << 8;
|
||||
index++;
|
||||
ncoils--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mberr = MB_ENOREG;
|
||||
}
|
||||
|
||||
return mberr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user