diff --git a/Makefile.in b/Makefile.in
index fe1d3a1ff672d5ab5084e74d97cd292eb7fbef76..8a460ae0ed51c85f3cb93b62d40f09b23bbe1c4b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -46,6 +46,7 @@ DEVFLAGS=@DEVFLAGS@
 	@/bin/mkdir -p build/$@epics
 	@/bin/mv -f build/$@epics-medm build/$@epics/medm
 	@/bin/mv -f build/$@epics-config build/$@epics/config
+ifndef RCG_BUILD_NO_KOBJ
 	@echo Building front-end Linux kernel module $@...
 	@make -sC src/fe/$@ clean
 # copy IOP symbol file to build area if found
@@ -60,10 +61,13 @@ DEVFLAGS=@DEVFLAGS@
 	@make -C src/fe/$@ >> $@.log 2>>$@_error.log || (tail $@.log; cat $@_error.log && /bin/false)
 	@$(srcdir)/src/epics/util/checkUndefined.pl $@_error.log >> $@.log 2>>$@_error.log || (tail $@.log; cat $@_error.log && /bin/false)
 	@echo Done
-#	@echo Building front-end user space object $@...
-#	@/bin/rm -rf src/fe/$@_usp/*.o ;
-#	@make -C src/fe/$@_usp >> $@.log 2>>$@_error.log || (tail $@.log; cat $@_error.log && /bin/false)
-#	@echo Done
+endif
+ifdef RCG_BUILD_USP
+	@echo Building front-end user space object $@...
+	@/bin/rm -rf src/fe/$@_usp/*.o ;
+	@make -C src/fe/$@_usp >> $@.log 2>>$@_error.log || (tail $@.log; cat $@_error.log && /bin/false)
+	@echo Done
+endif
 	@/bin/mkdir -p target/$@epics/src
 	@echo $(srcdir) > target/$@epics/src/rcg_location.txt
 	@echo Build date `date` > target/$@epics/src/build.txt
diff --git a/NEWS b/NEWS
index c2ff98d1fa0cdc7968bb8dae0ebfeee90ccc223a..25c3212c1a95e793e0826bf4a434eda2654b0f62 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,13 @@
 ==================================================================================================
+Changes for 4.0.2
+==================================================================================================
+- RCG I/O module mapping modified to allow DAC models to appear in any order on the bus. (issue #150)
+- Fix for ANU new 'N' site setting (Issue #117)
+- Fix to rtcds stop --all to stop IOP model last
+- Various changes to clear all RCG code gcc compile warnings (Issue #147)
+- Modified Parameters.pm to perform proper checking for Parameter block entreis. (Issue #155)
+- Enabled user space code compile with RCG_BUILD_USP compile argument
+==================================================================================================
 Changes for 4.0.1
 ==================================================================================================
 - Minor fix to the daq_wiper.py script, so that it does not crash when a free size is specified.
diff --git a/src/drv/fmReadCoeff.c b/src/drv/fmReadCoeff.c
index c5f1bcde896c5e4c1876e8e5d5b4891499245643..bfbfe7ed022e7d3ae5b3bbd9cc7a1dfdec65855f 100644
--- a/src/drv/fmReadCoeff.c
+++ b/src/drv/fmReadCoeff.c
@@ -31,6 +31,9 @@
 #include "fmReadCoeff.h"
 #include "crc.h"
 
+int getwords(char *, char *[], int );
+extern int checkFileCrc(char *);
+
 /* Cat string and make upper case */
 static char *strcat_upper(char *dest, char *src) {
   char *d = dest;
diff --git a/src/drv/mbuf/mbuf.c b/src/drv/mbuf/mbuf.c
index 0a45ce097c17c1a750aee2531854f4e687bb12cc..37414251b65244c695777e91ea3ccfd26b7a7792 100644
--- a/src/drv/mbuf/mbuf.c
+++ b/src/drv/mbuf/mbuf.c
@@ -42,6 +42,11 @@ static struct class* mbuf_class = NULL;
 static struct device* mbuf_device = NULL;
 static struct cdev mbuf_cdev;
 
+#define CDS_LOCAL_MBUF_SETTINGS_BUFFER_SIZE 10
+
+atomic_t mbuf_verbosity = ATOMIC_INIT(0);
+
+
 /* methods of the character device */
 static int mbuf_open(struct inode *inode, struct file *filp);
 static int mbuf_release(struct inode *inode, struct file *filp);
@@ -99,7 +104,10 @@ static DEFINE_SPINLOCK(lock);
 int mbuf_release_area(char *name, struct file *file) {
 	int i;
 
-    printk(KERN_INFO " mbuf_release_area %s\n", name);
+	if ((int)atomic_read(&mbuf_verbosity) > 0) {
+        printk(KERN_INFO
+        " mbuf_release_area %s\n", name);
+    }
 	spin_lock(&lock);
 	// See if allocated
 	for (i = 0; i < MAX_AREAS; i++) {
@@ -230,8 +238,8 @@ int mbuf_allocate_area(char *name, int size, struct file *file) {
 	//rkfree(kmalloc_area[i], s);
 	//kmalloc_area[i] = 0;
 	if (kmalloc_area[i] == 0) {
-		printk("malloc() failed\n");
-		spin_unlock(&lock);
+        spin_unlock(&lock);
+        printk("malloc() failed\n");
 	       	return -1;
 	}
 
@@ -309,14 +317,20 @@ static int mbuf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 {
 	int res;
     int mod = 0;
-	struct mbuf_request_struct req;
+	int verbose = 0;
+    struct mbuf_request_struct req;
         void __user *argp = (void __user *)arg;
 
-	printk(KERN_INFO "mbuf_ioctl: command=%d\n", cmd);
-        switch(cmd){
-        case IOCTL_MBUF_ALLOCATE:
+    verbose = (int)atomic_read(&mbuf_verbosity);
+
+    if (verbose > 0) {
+        printk(KERN_INFO
+        "mbuf_ioctl: command=%d\n", cmd);
+    }
+    switch(cmd){
+    case IOCTL_MBUF_ALLOCATE:
 		{
-        	  if (copy_from_user (&req, (void *) argp, sizeof (req))) {
+          if (copy_from_user (&req, (void *) argp, sizeof (req))) {
 			return -EFAULT;
 		  }
           // the size should be a multiple of page size
@@ -324,7 +338,10 @@ static int mbuf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
           if (mod != 0) {
               req.size += PAGE_SIZE - mod;
           }
-        	  printk(KERN_INFO "mbuf_ioctl: name:%.32s, size:%d, cmd:%d, file:%p\n", req.name, (int)req.size, cmd, file);
+          if (verbose > 0) {
+              printk(KERN_INFO
+              "mbuf_ioctl: name:%.32s, size:%d, cmd:%d, file:%p\n", req.name, (int) req.size, cmd, file);
+          }
 		  res = mbuf_allocate_area(req.name, req.size, file);
 		  if (res >= 0) {
 			return kmalloc_area_size[res];
@@ -333,12 +350,12 @@ static int mbuf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 		  }
 		}
 		break;
-        case IOCTL_MBUF_DEALLOCATE:
+    case IOCTL_MBUF_DEALLOCATE:
 		{
         	  if (copy_from_user (&req, (void *) argp, sizeof (req))) {
 			return -EFAULT;
 		  }
-        	  //printk("mbuf_ioctl: name:%.32s, size:%d, cmd:%d, file:%p\n", req.name, req.size, cmd, file);
+          //printk("mbuf_ioctl: name:%.32s, size:%d, cmd:%d, file:%p\n", req.name, req.size, cmd, file);
 		  res = mbuf_release_area(req.name, file);
 		  if (res >= 0) {
 			return  0;
@@ -348,7 +365,7 @@ static int mbuf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 		} 
                 break;
 
-        case IOCTL_MBUF_INFO:
+    case IOCTL_MBUF_INFO:
 #if 0
 		for (i = 0; i < MAX_AREAS; i++) {
 			if (kmalloc_area[i]) {
@@ -361,8 +378,8 @@ static int mbuf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 		break;
         default:		
                 return -EINVAL;
-        }
-        return -EINVAL;
+    }
+    return -EINVAL;
 }
 
 static ssize_t mbuf_sysfs_status(struct kobject *kobj, struct kobj_attribute *attr, char *buf) {
@@ -389,15 +406,44 @@ static ssize_t mbuf_sysfs_status(struct kobject *kobj, struct kobj_attribute *at
 	return count;
 }
 
+static ssize_t mbuf_sysfs_verbosity_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) {
+    int new_verbosity = 0;
+    char localbuf[CDS_LOCAL_MBUF_SETTINGS_BUFFER_SIZE+1];
+    int conv_ret = 0;
+
+    memset(localbuf, 0, CDS_LOCAL_MBUF_SETTINGS_BUFFER_SIZE+1);
+    if (count >= CDS_LOCAL_MBUF_SETTINGS_BUFFER_SIZE) {
+        printk("mbuf_sysfs_verbosity_store called with too much input, ignoring the value");
+        return -EFAULT;
+    }
+    memcpy(localbuf, buf, count);
+    localbuf[count] ='\0';
+
+
+    if ((conv_ret = kstrtoint(localbuf, 10, &new_verbosity)) != 0) {
+        printk("mbuf_sysfs_verbosity_store error converting verbosity into an integer - %s %d", (conv_ret == -ERANGE ? "range" : "overflow"), conv_ret);
+        return -EFAULT;
+    }
+    atomic_set(&mbuf_verbosity, new_verbosity);
+    return (ssize_t) count;
+}
+
+static ssize_t mbuf_sysfs_verbosity_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) {
+    return sprintf(buf, "%d\n", (int)atomic_read(&mbuf_verbosity));
+}
+
+
 /* sysfs related structures */
 static struct kobject *mbuf_sysfs_dir = NULL;
 
 /* individual sysfs debug attributes */
 static struct kobj_attribute sysfs_mbuf_status_attr = __ATTR(status, 0444, mbuf_sysfs_status, NULL);
+static struct kobj_attribute sysfs_mbuf_verbosity_attr = __ATTR(verbosity, 0644, mbuf_sysfs_verbosity_show, mbuf_sysfs_verbosity_store);
 
 /* group attributes together for bulk operations */
 static struct attribute *mbuf_fields[] = {
 		&sysfs_mbuf_status_attr.attr,
+		&sysfs_mbuf_verbosity_attr.attr,
 		NULL,
 };
 
diff --git a/src/drv/mbuf/mbuf_probe/CMakeLists.txt b/src/drv/mbuf/mbuf_probe/CMakeLists.txt
index b27b0321b46bfe1187071c6743cb21c176bff0f5..715c84526de9b13845521d82de3b363b3743c6b5 100644
--- a/src/drv/mbuf/mbuf_probe/CMakeLists.txt
+++ b/src/drv/mbuf/mbuf_probe/CMakeLists.txt
@@ -4,12 +4,13 @@ add_executable(mbuf_probe
         mbuf_probe.cc
         mbuf_decoders.cc
         analyze_daq_multi_dc.cc
-        analyze_rmipc.cc)
+        analyze_rmipc.cc
+        check_size.cc)
 target_include_directories(mbuf_probe PRIVATE
         ${CMAKE_CURRENT_SOURCE_DIR}/..
         ${CMAKE_CURRENT_SOURCE_DIR}/../../include
         )
-target_link_libraries(mbuf_probe PUBLIC driver::shmem)
+target_link_libraries(mbuf_probe PUBLIC driver::shmem driver::ini_parsing)
 target_requires_cpp11(mbuf_probe PRIVATE)
 
 install(TARGETS mbuf_probe DESTINATION bin)
\ No newline at end of file
diff --git a/src/drv/mbuf/mbuf_probe/check_size.cc b/src/drv/mbuf/mbuf_probe/check_size.cc
new file mode 100644
index 0000000000000000000000000000000000000000..01301fed08d6eeefba7323d16060571f25b94c6d
--- /dev/null
+++ b/src/drv/mbuf/mbuf_probe/check_size.cc
@@ -0,0 +1,320 @@
+//
+// Created by jonathan.hanks on 8/13/20.
+//
+
+#include "check_size.hh"
+
+#include <algorithm>
+#include <array>
+#include <fstream>
+#include <iostream>
+
+#include "daq_core.h"
+#include "daq_core_defs.h"
+#include "daq_data_types.h"
+
+#include "daqmap.h"
+extern "C" {
+#include "param.h"
+}
+
+namespace check_mbuf_sizes
+{
+    typedef struct ini_file_info
+    {
+        ini_file_info( )
+            : dcu_sizes( ), dcu_config_crc( ), last_dcuid( 0 ), valid( true )
+        {
+            std::fill( dcu_sizes.begin( ), dcu_sizes.end( ), 0 );
+            std::fill( dcu_config_crc.begin( ), dcu_config_crc.end( ), 0 );
+        }
+        ini_file_info( const ini_file_info& ) noexcept = default;
+        ini_file_info& operator=( const ini_file_info& ) noexcept = default;
+
+        std::array< unsigned int, DAQ_TRANSIT_MAX_DCU >  dcu_sizes;
+        std::array< unsigned long, DAQ_TRANSIT_MAX_DCU > dcu_config_crc;
+        int                                              last_dcuid;
+        bool                                             valid;
+    } size_info;
+
+    int
+    channel_callback( char*              channel_name,
+                      struct CHAN_PARAM* params,
+                      void*              user )
+    {
+        auto* info = reinterpret_cast< ini_file_info* >( user );
+        int   chan_size = data_type_size( params->datatype ) *
+            ( params->datarate / DAQ_NUM_DATA_BLOCKS_PER_SECOND );
+        if ( chan_size == 0 )
+        {
+            info->valid = false;
+        }
+        else
+        {
+            info->dcu_sizes[ params->dcuid ] += chan_size;
+        }
+        info->last_dcuid = params->dcuid;
+        return 1;
+    }
+
+    ini_file_info
+    load_master( const std::string& fname )
+    {
+        ini_file_info sysinfo;
+        // File names are specified in `master_config' file
+        std::ifstream mcf( fname );
+
+        for ( std::string line; std::getline( mcf, line ); )
+        {
+            std::string trimmed_line;
+            trimmed_line.reserve( line.size( ) );
+            std::copy_if( line.begin( ),
+                          line.end( ),
+                          std::back_inserter( trimmed_line ),
+                          []( const char ch ) -> bool { return ch != ' '; } );
+            if ( line.front( ) == '#' )
+            {
+                continue;
+            }
+            if ( trimmed_line.empty( ) || trimmed_line.front( ) == '#' )
+            {
+                continue;
+            }
+
+            std::string ext =
+                ( trimmed_line.size( ) > 4
+                      ? trimmed_line.substr( trimmed_line.size( ) - 4 )
+                      : "" );
+            auto testpoint = ( ext == ".par" );
+
+            unsigned long file_crc = 0;
+            sysinfo.valid = true;
+            sysinfo.last_dcuid = -1;
+            int parse_status =
+                ::parseConfigFile( const_cast< char* >( trimmed_line.c_str( ) ),
+                                   &file_crc,
+                                   channel_callback,
+                                   testpoint,
+                                   0,
+                                   reinterpret_cast< void* >( &sysinfo ) );
+            if ( parse_status == 0 || !sysinfo.valid || sysinfo.last_dcuid < 0 )
+            {
+                std::cerr << "Unable to process " << trimmed_line
+                          << " either the file is invalid, bad data types, or "
+                             "other error ("
+                          << sysinfo.valid << ", " << sysinfo.last_dcuid
+                          << ")\n";
+                if ( sysinfo.last_dcuid >= 0 )
+                {
+                    sysinfo.dcu_sizes[ sysinfo.last_dcuid ] = 0;
+                }
+            }
+            else
+            {
+                sysinfo.dcu_config_crc[ sysinfo.last_dcuid ] = file_crc;
+            }
+        }
+        return sysinfo;
+    }
+
+    int
+    check_size_rmipc( volatile void*      buffer,
+                      std::size_t         buffer_size,
+                      const ::ConfigOpts& options )
+    {
+        if ( options.analysis_type != MBUF_RMIPC ||
+             buffer_size != 64 * 1024 * 1024 )
+        {
+            return 0;
+        }
+
+        load_master( options.ini_file_fname );
+
+        unsigned int prev_config_crc{ 0 };
+        unsigned int prev_data_size{ 0 };
+
+        auto header = reinterpret_cast< const volatile rmIpcStr* >( buffer );
+
+        ini_file_info dcu_reference;
+        bool          noted_crc_change{ false };
+
+        bool have_inis = false;
+        if ( !options.ini_file_fname.empty( ) )
+        {
+            dcu_reference = load_master( options.ini_file_fname );
+            have_inis = true;
+        }
+
+        bool first_iteration = true;
+        while ( true )
+        {
+            wait_until_changed< const unsigned int, 5000 >( &header->cycle,
+                                                            header->cycle );
+
+            auto cur_cycle = header->cycle;
+            auto dcuid = header->dcuId;
+
+            if ( !first_iteration )
+            {
+                if ( have_inis )
+                {
+                    if ( header->crc != dcu_reference.dcu_config_crc[ dcuid ] &&
+                         !noted_crc_change )
+                    {
+                        std::cout
+                            << "config change on dcu " << dcuid << " from "
+                            << dcu_reference.dcu_config_crc[ dcuid ] << " to "
+                            << header->crc << "\n";
+                        noted_crc_change = true;
+                    }
+                    if ( dcu_reference.dcu_sizes[ dcuid ] !=
+                         header->dataBlockSize )
+                    {
+                        std::cout << "wrong data size on " << dcuid
+                                  << " expected "
+                                  << dcu_reference.dcu_sizes[ dcuid ] << " got "
+                                  << header->dataBlockSize << "\n";
+                    }
+                }
+                else
+                {
+                    if ( prev_config_crc != header->crc && !noted_crc_change )
+                    {
+                        std::cout << "config change on dcu " << dcuid
+                                  << " from " << prev_config_crc << " to "
+                                  << header->crc << "\n";
+                        noted_crc_change;
+                    }
+                    if ( prev_data_size != header->dataBlockSize )
+                    {
+                        std::cout << "data size change on dcu " << dcuid
+                                  << " from " << prev_data_size << " to "
+                                  << header->dataBlockSize << "\n";
+                    }
+                }
+            }
+            prev_config_crc = header->crc;
+            prev_data_size = header->dataBlockSize;
+
+            if ( first_iteration )
+            {
+                std::cout
+                    << "Completed the first iteration of the check_size test"
+                    << std::endl;
+                first_iteration = false;
+            }
+        }
+        return 0;
+    }
+
+    int
+    check_size_multi( volatile void*      buffer,
+                      std::size_t         buffer_size,
+                      const ::ConfigOpts& options )
+    {
+        if ( !buffer || buffer_size < DAQD_MIN_SHMEM_BUFFER_SIZE ||
+             buffer_size > DAQD_MAX_SHMEM_BUFFER_SIZE ||
+             options.analysis_type != MBUF_DAQ_MULTI_DC )
+        {
+            return 0;
+        }
+
+        load_master( options.ini_file_fname );
+
+        std::array< unsigned int, DAQ_TRANSIT_MAX_DCU > prev_config_crc{};
+        std::array< unsigned int, DAQ_TRANSIT_MAX_DCU > prev_data_size{};
+
+        std::fill( prev_config_crc.begin( ), prev_config_crc.end( ), 0 );
+        std::fill( prev_data_size.begin( ), prev_data_size.end( ), 0 );
+
+        auto multi_header =
+            reinterpret_cast< const volatile daq_multi_cycle_data_t* >(
+                buffer );
+
+        ini_file_info                           dcu_reference;
+        std::array< bool, DAQ_TRANSIT_MAX_DCU > noted_crc_change{};
+        std::fill( noted_crc_change.begin( ), noted_crc_change.end( ), false );
+        bool have_inis = false;
+        if ( !options.ini_file_fname.empty( ) )
+        {
+            dcu_reference = load_master( options.ini_file_fname );
+            have_inis = true;
+        }
+
+        bool first_iteration = true;
+        while ( true )
+        {
+            wait_for_time_change< 5000 >( multi_header->header );
+
+            auto cur_cycle = multi_header->header.curCycle;
+            auto cycle_data_size = multi_header->header.cycleDataSize;
+
+            auto cur_cylce_block =
+                reinterpret_cast< const volatile daq_multi_dcu_data_t* >(
+                    &multi_header->dataBlock[ 0 ] +
+                    (cycle_data_size)*cur_cycle );
+            auto total_models = cur_cylce_block->header.dcuTotalModels;
+
+            for ( auto i = 0; i < total_models; ++i )
+            {
+                auto& cur_header = cur_cylce_block->header.dcuheader[ i ];
+                auto  dcuid = cur_header.dcuId;
+
+                if ( !first_iteration )
+                {
+                    if ( have_inis )
+                    {
+                        if ( cur_header.fileCrc !=
+                                 dcu_reference.dcu_config_crc[ dcuid ] &&
+                             !noted_crc_change[ dcuid ] )
+                        {
+                            std::cout << "config change on dcu " << dcuid
+                                      << " from "
+                                      << dcu_reference.dcu_config_crc[ dcuid ]
+                                      << " to " << cur_header.fileCrc << "\n";
+                            noted_crc_change[ dcuid ] = true;
+                        }
+                        if ( dcu_reference.dcu_sizes[ dcuid ] !=
+                             cur_header.dataBlockSize )
+                        {
+                            std::cout << "wrong data size on " << dcuid
+                                      << " expected "
+                                      << dcu_reference.dcu_sizes[ dcuid ]
+                                      << " got " << cur_header.dataBlockSize
+                                      << "\n";
+                        }
+                    }
+                    else
+                    {
+                        if ( prev_config_crc[ dcuid ] != cur_header.fileCrc &&
+                             !noted_crc_change[ dcuid ] )
+                        {
+                            std::cout << "config change on dcu " << dcuid
+                                      << " from " << prev_config_crc[ dcuid ]
+                                      << " to " << cur_header.fileCrc << "\n";
+                            noted_crc_change[ dcuid ];
+                        }
+                        if ( prev_data_size[ dcuid ] !=
+                             cur_header.dataBlockSize )
+                        {
+                            std::cout << "data size change on dcu " << dcuid
+                                      << " from " << prev_data_size[ dcuid ]
+                                      << " to " << cur_header.dataBlockSize
+                                      << "\n";
+                        }
+                    }
+                }
+                prev_config_crc[ dcuid ] = cur_header.fileCrc;
+                prev_data_size[ dcuid ] = cur_header.dataBlockSize;
+            }
+            if ( first_iteration )
+            {
+                std::cout
+                    << "Completed the first iteration of the check_size test"
+                    << std::endl;
+                first_iteration = false;
+            }
+        }
+        return 0;
+    }
+} // namespace check_mbuf_sizes
\ No newline at end of file
diff --git a/src/drv/mbuf/mbuf_probe/check_size.hh b/src/drv/mbuf/mbuf_probe/check_size.hh
new file mode 100644
index 0000000000000000000000000000000000000000..221135bcabd8dae941d38a75faed49a9ea0cbe83
--- /dev/null
+++ b/src/drv/mbuf/mbuf_probe/check_size.hh
@@ -0,0 +1,22 @@
+//
+// Created by jonathan.hanks on 8/13/20.
+//
+
+#ifndef DAQD_TRUNK_CHECK_SIZE_HH
+#define DAQD_TRUNK_CHECK_SIZE_HH
+
+#include <cstddef>
+
+#include "mbuf_probe.hh"
+
+namespace check_mbuf_sizes
+{
+    int check_size_rmipc( volatile void*    buffer,
+                          std::size_t       buffer_Size,
+                          const ConfigOpts& options );
+    int check_size_multi( volatile void*    buffer,
+                          std::size_t       buffer_Size,
+                          const ConfigOpts& options );
+} // namespace check_mbuf_sizes
+
+#endif // DAQD_TRUNK_CHECK_SIZE_HH
diff --git a/src/drv/mbuf/mbuf_probe/gap_check.cc b/src/drv/mbuf/mbuf_probe/gap_check.cc
index 2e1fce44fed1a34039ef7dc328aee595188c1c47..3d347959063ab93047bef265bcdecd3fb61933bf 100644
--- a/src/drv/mbuf/mbuf_probe/gap_check.cc
+++ b/src/drv/mbuf/mbuf_probe/gap_check.cc
@@ -2,58 +2,12 @@
 // Created by jonathan.hanks on 3/13/20.
 //
 #include "gap_check.hh"
-#include <chrono>
-#include <daq_core.h>
-
-#include <sys/time.h>
-#include <unistd.h>
 
 #include <iostream>
+#include "mbuf_probe.hh"
 
 namespace check_gap
 {
-    static std::int64_t
-    time_now_ms( )
-    {
-        timeval tv;
-        gettimeofday( &tv, 0 );
-        return static_cast< std::uint64_t >( tv.tv_sec * 1000 +
-                                             tv.tv_usec / 1000 );
-    }
-
-    struct cycle_sample_t
-    {
-        unsigned int  cycle;
-        unsigned int  gps;
-        unsigned int  gps_nano;
-        unsigned int  gps_cycle;
-        std::uint64_t time_ms;
-    };
-
-    cycle_sample_t
-    wait_for_time_change( volatile daq_multi_cycle_header_t& header )
-    {
-        cycle_sample_t results;
-        unsigned int   cur_cycle = header.curCycle;
-        while ( header.curCycle == cur_cycle )
-        {
-            usleep( 2000 );
-        }
-        results.time_ms = time_now_ms( );
-        results.cycle = header.curCycle;
-
-        unsigned int   stride = header.cycleDataSize;
-        volatile char* buffer_data =
-            reinterpret_cast< volatile char* >( &header ) +
-            sizeof( daq_multi_cycle_header_t );
-        volatile daq_dc_data_t* daq =
-            reinterpret_cast< volatile daq_dc_data_t* >(
-                buffer_data + stride * header.curCycle );
-        results.gps = daq->header.dcuheader[ 0 ].timeSec;
-        results.gps_nano = daq->header.dcuheader[ 0 ].timeNSec;
-        results.gps_cycle = daq->header.dcuheader[ 0 ].cycle;
-        return results;
-    }
 
     int
     check_gaps( volatile void* buffer, std::size_t buffer_size )
diff --git a/src/drv/mbuf/mbuf_probe/mbuf_probe.cc b/src/drv/mbuf/mbuf_probe/mbuf_probe.cc
index 4e81684ac3808262b38f1128e3398fbd01cb3c21..e1879d55910c472e9732592555a8e1c38112b584 100644
--- a/src/drv/mbuf/mbuf_probe/mbuf_probe.cc
+++ b/src/drv/mbuf/mbuf_probe/mbuf_probe.cc
@@ -28,6 +28,10 @@
 #include "analyze_daq_multi_dc.hh"
 #include "analyze_rmipc.hh"
 #include "gap_check.hh"
+#include "check_size.hh"
+
+const int OK = 0;
+const int ERROR = 1;
 
 void
 usage( const char* progname )
@@ -42,6 +46,8 @@ usage( const char* progname )
     std::cout << "\tanalyze - continually read the mbuf and do some analysis\n";
     std::cout << "\tgap_check - continually scan the buffers looking for "
                  "gaps/jumps in the data stream\n";
+    std::cout << "\tcheck_sizes - check the given buffer's data segment sizes "
+                 "against the expected size as calculated in the ini files.";
     std::cout << "\t-b <buffer name> - The name of the buffer to act on\n";
     std::cout
         << "\t-m <buffer size in MB> - The size of the buffer in megabytes\n";
@@ -49,6 +55,8 @@ usage( const char* progname )
                  "multiple of 4k)\n";
     std::cout << "\t-o <filename> - Output file for the copy operation "
                  "(defaults to probe_out.bin)\n";
+    std::cout << "\t-i <filename> - Path to the master ini file (only used "
+                 "for the check_size action)\n";
     std::cout
         << "\t--struct <type> - Type of structure to analyze [rmIpcStr]\n";
     std::cout << "\t--dcu <dcuid> - Optional DCU id used to select a dcu for "
@@ -79,6 +87,7 @@ parse_options( int argc, char* argv[] )
     command_lookup.insert( std::make_pair( "delete", DELETE ) );
     command_lookup.insert( std::make_pair( "analyze", ANALYZE ) );
     command_lookup.insert( std::make_pair( "gap_check", GAP_CHECK ) );
+    command_lookup.insert( std::make_pair( "check_size", CHECK_SIZE ) );
 
     std::map< std::string, MBufStructures > struct_lookup;
     struct_lookup.insert( std::make_pair( "rmIpcStr", MBUF_RMIPC ) );
@@ -157,6 +166,17 @@ parse_options( int argc, char* argv[] )
             is >> offset;
             opts.decoder = DataDecoder( offset, format_spec );
         }
+        else if ( arg == "-i" )
+        {
+            if ( args.empty( ) )
+            {
+                opts.set_error(
+                    "You must specify a ini file path when using -i" );
+                return opts;
+            }
+            opts.ini_file_fname = args.front( );
+            args.pop_front( );
+        }
         else if ( arg == "--struct" )
         {
             if ( args.empty( ) )
@@ -325,9 +345,6 @@ list_shmem_segments( )
 int
 handle_analyze( const ConfigOpts& opts )
 {
-    const int OK = 0;
-    const int ERROR = 1;
-
     volatile void* buffer =
         shmem_open_segment( opts.buffer_name.c_str( ), opts.buffer_size );
     switch ( opts.analysis_type )
@@ -348,9 +365,6 @@ handle_analyze( const ConfigOpts& opts )
 int
 handle_gap_check( const ConfigOpts& opts )
 {
-    const int OK = 0;
-    const int ERROR = 1;
-
     if ( opts.analysis_type != MBUF_DAQ_MULTI_DC )
     {
         std::cout << "daq_multi_cycle is the only mode that the crc_check is "
@@ -363,6 +377,26 @@ handle_gap_check( const ConfigOpts& opts )
     return OK;
 }
 
+int
+handle_check_size( const ConfigOpts& opts )
+{
+    volatile void* buffer =
+        shmem_open_segment( opts.buffer_name.c_str( ), opts.buffer_size );
+    switch ( opts.analysis_type )
+    {
+    case MBUF_RMIPC:
+        check_mbuf_sizes::check_size_rmipc( buffer, opts.buffer_size, opts );
+        break;
+    case MBUF_DAQ_MULTI_DC:
+        check_mbuf_sizes::check_size_multi( buffer, opts.buffer_size, opts );
+        break;
+    default:
+        std::cout << "Unknown analysis type for the check size commandn";
+        return ERROR;
+    }
+    return OK;
+}
+
 int
 main( int argc, char* argv[] )
 {
@@ -408,6 +442,8 @@ main( int argc, char* argv[] )
         return handle_analyze( opts );
     case GAP_CHECK:
         return handle_gap_check( opts );
+    case CHECK_SIZE:
+        return handle_check_size( opts );
     }
     return 0;
 }
diff --git a/src/drv/mbuf/mbuf_probe/mbuf_probe.hh b/src/drv/mbuf/mbuf_probe/mbuf_probe.hh
index 2b1e64c71e7ad92bbbee261ff0481ae37f825615..9609af1d65deb0c970b37f9ee354c95245580baa 100644
--- a/src/drv/mbuf/mbuf_probe/mbuf_probe.hh
+++ b/src/drv/mbuf/mbuf_probe/mbuf_probe.hh
@@ -5,12 +5,17 @@
 #ifndef DAQD_MBUF_PROBE_HH
 #define DAQD_MBUF_PROBE_HH
 
+#include <chrono>
 #include <cstddef>
 #include <string>
 #include <vector>
+#include <type_traits>
 
+#include <sys/time.h>
 #include <unistd.h>
 
+#include <daq_core.h>
+
 #include "mbuf_decoders.hh"
 
 enum MBufCommands
@@ -22,6 +27,7 @@ enum MBufCommands
     DELETE,
     ANALYZE,
     GAP_CHECK,
+    CHECK_SIZE,
 };
 
 enum MBufStructures
@@ -35,8 +41,9 @@ struct ConfigOpts
 {
     ConfigOpts( )
         : action( INVALID ), buffer_size( 0 ), buffer_name( "" ),
-          output_fname( "probe_out.bin" ), error_msg( "" ), dcu_id( -1 ),
-          decoder( ), analysis_type( MBUF_INVALID )
+          output_fname( "probe_out.bin" ), error_msg( "" ),
+          ini_file_fname( "" ), dcu_id( -1 ), decoder( ),
+          analysis_type( MBUF_INVALID )
     {
     }
     MBufCommands   action;
@@ -44,6 +51,7 @@ struct ConfigOpts
     std::string    buffer_name;
     std::string    output_fname;
     std::string    error_msg;
+    std::string    ini_file_fname;
     int            dcu_id;
     DataDecoder    decoder;
     MBufStructures analysis_type;
@@ -115,6 +123,13 @@ struct ConfigOpts
                            "as well as daq_multi_cycle" );
             }
             break;
+        case CHECK_SIZE:
+            if ( buffer_name.empty( ) || buffer_size == 0 )
+            {
+                set_error( "To check sizes you must specify a buffer, size, "
+                           "and optionally an ini file" );
+            }
+            break;
         case INVALID:
         default:
             set_error( "Please select a valid action" );
@@ -134,17 +149,59 @@ struct ConfigOpts
     }
 };
 
-template < typename T >
+template < typename T, int CheckPeriodUS = 250 >
 unsigned int
 wait_until_changed( volatile T* counter, T old_counter )
 {
-    T cur_cycle = *counter;
+    typename std::remove_const< T >::type cur_cycle = *counter;
     do
     {
-        usleep( 250 );
+        usleep( CheckPeriodUS );
         cur_cycle = *counter;
     } while ( cur_cycle == old_counter );
     return cur_cycle;
 }
 
+inline std::int64_t
+time_now_ms( )
+{
+    timeval tv;
+    gettimeofday( &tv, 0 );
+    return static_cast< std::uint64_t >( tv.tv_sec * 1000 + tv.tv_usec / 1000 );
+}
+
+struct cycle_sample_t
+{
+    unsigned int  cycle;
+    unsigned int  gps;
+    unsigned int  gps_nano;
+    unsigned int  gps_cycle;
+    std::uint64_t time_ms;
+};
+
+template < int CheckPeriodUS = 2000 >
+cycle_sample_t
+wait_for_time_change( const volatile daq_multi_cycle_header_t& header )
+{
+    cycle_sample_t results;
+    unsigned int   cur_cycle = header.curCycle;
+    while ( header.curCycle == cur_cycle )
+    {
+        usleep( CheckPeriodUS );
+    }
+    results.time_ms = time_now_ms( );
+    results.cycle = header.curCycle;
+
+    unsigned int         stride = header.cycleDataSize;
+    const volatile char* buffer_data =
+        reinterpret_cast< const volatile char* >( &header ) +
+        sizeof( daq_multi_cycle_header_t );
+    const volatile daq_dc_data_t* daq =
+        reinterpret_cast< const volatile daq_dc_data_t* >(
+            buffer_data + stride * header.curCycle );
+    results.gps = daq->header.dcuheader[ 0 ].timeSec;
+    results.gps_nano = daq->header.dcuheader[ 0 ].timeNSec;
+    results.gps_cycle = daq->header.dcuheader[ 0 ].cycle;
+    return results;
+}
 #endif // DAQD_MBUF_PROBE_HH
diff --git a/src/epics/seq/main.c b/src/epics/seq/main.c
index 18835a8cdc1834515f09d377adac1ea412b85cd5..9ddc80775f62bb5176c7e157e71e81e42630f713 100644
--- a/src/epics/seq/main.c
+++ b/src/epics/seq/main.c
@@ -322,6 +322,7 @@ void cleanupCASDF();
 #else
 int getDbValueDouble(ADDRESS*,double *,time_t *);
 int getDbValueString(ADDRESS*,char *, int, time_t *);
+int getDbValueLong(ADDRESS *,unsigned int * ,time_t *);
 void dbDumpRecords(DBBASE *,const char *);
 #endif
 
diff --git a/src/epics/util/feCodeGen.pl b/src/epics/util/feCodeGen.pl
index 36f13a8f29d95ca230b88d62029e35fcccf7c712..06bf5ba555b6edb1fe2a1a5c1d23e98197cab624 100755
--- a/src/epics/util/feCodeGen.pl
+++ b/src/epics/util/feCodeGen.pl
@@ -111,12 +111,13 @@ $maxDioMod = pop(@mdmNum);
 # Initialize default settings.
 $sitedepwarning = 0;
 $adcmasterdepwarning = 0;
-$ifo = "M1"; # Default value for the ifo name
-$location = "mit"; # Default value for the location name
-$rate = "60"; # In microseconds (default setting)
+$timemasterdepwarning = 0;
+$ifo = "dummy"; # Default value for the ifo name
+$location = "zzz"; # Default value for the location name
+$rate = 0; # In microseconds (default setting)
 $brate = "52";
-$dcuId = 10; # Default dcu Id
-$targetHost = "localhost"; # Default target host name
+$dcuId = 0; # Default dcu Id
+$targetHost = "dummy"; # Default target host name
 $edcusync = "none";
 $specificCpu = -1; # Defaults is to run the FE on the first available CPU
 $iopModel = -1;
@@ -294,6 +295,7 @@ die unless CDS::Parser::process();
 
 close(IN);
 
+#Print warning messages if model contains Parameter block entries due for deprecation
 if(($iopModel == 1) and ($modelrate > $adcclock) and ($clock_div == 1)) 
 {
 	die "Error:\nModel rate $modelrate > ADC clock $adcclock\nFix adcclock in Param Block\n*****\n";
@@ -306,6 +308,10 @@ if($adcmasterdepwarning == 1) {
 	print WARNINGS "WARNING: The 'adcMaster=' designator in the model parameter block\n\t is scheduled for deprecation in future releases. \n";
 	print WARNINGS "*******: Please replace adcMaster=1 designator with iop_model=1 \n";
 }
+if($timemasterdepwarning == 1) {
+	print WARNINGS "WARNING: The 'time_master=' designator in the model parameter block\n\t is scheduled for deprecation in future releases. \n";
+	print WARNINGS "*******: Please replace time_master=1 designator with dolphin_time_xmit=1 \n";
+}
 
 #//	
 #// Model now consists of top level parts and single level subsystem(s). <em>Parser3.pm</em> has taken care of all part
diff --git a/src/epics/util/lib/Parameters.pm b/src/epics/util/lib/Parameters.pm
index 77011b5d371d02caf470d39046fb5fcffcd1fb4e..80b05e57483f93f17160d06b4a8e968cd87dfdd3 100644
--- a/src/epics/util/lib/Parameters.pm
+++ b/src/epics/util/lib/Parameters.pm
@@ -9,6 +9,7 @@ use Env qw(RCG_HOST);
 #//
 #// \n
 
+use Switch;
 
 # Print Epics communication structure into a header file
 # Current part number is passed as first argument
@@ -23,24 +24,32 @@ sub parseParams {
 	#print "Split array is @sp\n";
 	for (@sp) {
 		@spp = split(/=/);
+        # Find and convert params due for deprecation in later releases
 		if (@spp == 2) {
-			if ($spp[0] eq "site" ) {
+            if ($spp[0] eq "site" ) {
                 $::sitedepwarning = 1;
+                $spp[0] = "ifo";
             }
-			if ($spp[0] eq "adcMaster" ) {
+            if($spp[0] eq "adcMaster") {
                 $::adcmasterdepwarning = 1;
+                $spp[0] = "iop_model";
             }
-			if (($spp[0] eq "site") or ($spp[0] eq "ifo") ) {
-				$spp[1] =~ s/,/ /g;
-
-                                if (lc($spp[1]) ne $::ifo_from_mdl_name) {
-                                   $errmsg = "***ERROR: Model <ifo> name part does not match cdsParameters: ";
-                                   $errmsg .= $::ifo . ", " . $spp[1] . "\n";
-
-                                    die $errmsg;
-                                }
+            if($spp[0] eq "time_master") {
+                $::timemasterdepwarning = 1;
+                $spp[0] = "dolphin_time_xmit";
+            }
+            switch($spp[0])
+            {
+                case  "ifo" {
+				    print "PARAM ifo set to $spp[1]\n";
+				    $spp[1] =~ s/,/ /g;
+                    if (lc($spp[1]) ne $::ifo_from_mdl_name) {
+                        $errmsg = "***ERROR: Model <ifo> name part does not match cdsParameters: ";
+                        $errmsg .= $::ifo . ", " . $spp[1] . "\n";
+                        die $errmsg;
+                    }
 
-				$::ifo = $spp[1];
+				    $::ifo = $spp[1];
 			        if ($::ifo =~ /^M/) {
                 			$::location = "mit";
         			} elsif ($::ifo =~ /^A/) {
@@ -62,146 +71,289 @@ sub parseParams {
         			} elsif ($::ifo =~ /^X/) {
                 			$::location = "tst";
         			}
-			} elsif ($spp[0] eq "rate") {
-				print "Rate set to $spp[1]\n";
+                }
+                case "rate"
+                {
+				    print "PARAM Rate set to $spp[1]\n";
         			my $param_speed = $spp[1];
-        			if ($param_speed eq "2K") {
+                    switch($param_speed)
+                    {
+        			case "2K" {
                 			$::rate = 480;
                 			$::modelrate = 2;
                 			$::servoflag = "-DSERVO2K";
-        			} elsif ($param_speed eq "4K") {
+        			} 
+        			case "4K" {
                 			$::rate = 240;
                 			$::modelrate = 4;
                 			$::servoflag = "-DSERVO4K";
-        			} elsif ($param_speed eq "16K") {
+        			} 
+                    case "16K" {
                 			$::rate = 60;
                 			$::modelrate = 16;
                 			$::servoflag = "-DSERVO16K";
-        			} elsif ($param_speed eq "32K") {
+                    }
+                    case "32K" {
                 			$::rate = 30;
                 			$::modelrate = 32;
                 			$::servoflag = "-DSERVO32K";
-        			} elsif ($param_speed eq "64K") {
+                    }
+                    case "64K" {
                 			$::rate = 15;
                 			$::modelrate = 64;
                 			$::servoflag = "-DSERVO64K";
-        			} elsif ($param_speed eq "128K") {
+                    }
+                    case "128K" {
                 			$::rate = 8;
                 			$::modelrate = 128;
                 			$::servoflag = "-DSERVO128K";
-        			} elsif ($param_speed eq "256K") {
+                    }
+                    case "256K" {
                 			$::rate = 4;
                 			$::modelrate = 256;
                 			$::servoflag = "-DSERVO256K";
-        			} elsif ($param_speed eq "512K") {
+                    }
+                    case "512K" {
                 			$::rate = 2;
                 			$::modelrate = 512;
                 			$::servoflag = "-DSERVO512K";
-        			} elsif ($param_speed eq "1024K") {
-                			$::rate = 1;
-                			$::modelrate = 1024;
-                			$::servoflag = "-DSERVO1024K";
-        			} else  { die "Invalid speed $param_speed specified\n"; }
-
-			} elsif ($spp[0] eq "dcuid") {
-				print "Dcu Id is set to $spp[1]\n";
-				$::dcuId = $spp[1];
-				print "GDS node id is set to $::dcuId \n";
-				$::gdsNodeId = $::dcuId;
-			} elsif ($spp[0] eq "host") {
-				print "Target host name is set to $spp[1]\n";
-				$::targetHost = $spp[1];
-				if ($RCG_HOST) {
-					$::targetHost = $RCG_HOST;
-				}
-			} elsif ($spp[0] eq "plant_name") {
-				print "Plant name is set to $spp[1]\n";
-				$::plantName = $spp[1];
-			} elsif ($spp[0] eq "daq_prefix")  {
-				$::daq_prefix = $spp[1];
-			} elsif ($spp[0] eq "no_sync" && $spp[1] == 1) {
-                # This essentially set up IOP for a Cymac
-				print "Will not sync up to 1PPS\n";
-				$::no_sync = 1;
-			} elsif ($spp[0] eq "no_daq" && $spp[1] == 1) {
-                # Will compile code not to use DAQ
-				print "Will not connect to DAQ\n";
-				$::no_daq = 1;
-			} elsif ($spp[0] eq "enable_fir" && $spp[1] == 1) {
-                # Will compile code to use FIR filtes
-				print "Will use FIR filters\n";
-				$::useFIRs = 1;
-			} elsif ($spp[0] eq "no_oversampling" && $spp[1] == 1) {
-				print "Will not oversample\n";
-				$::no_oversampling = 1;
-			} elsif ($spp[0] eq "no_dac_interpolation" && $spp[1] == 1) {
-				print "Will not interpolate DAC\n";
-				$::no_dac_interpolation = 1;
-			} elsif ($spp[0] eq "specific_cpu") {
-				print "FE will run on CPU $spp[1]\n";
-				$::specificCpu = $spp[1];
-			} elsif ($spp[0] eq "adcMaster") {
-				print "FE will run as IOP\n";
-				$::iopModel = $spp[1];
-			} elsif ($spp[0] eq "iop_model") {
-				print "FE will run as IOP\n";
-				$::iopModel = $spp[1];
-			} elsif ($spp[0] eq "diagTest") {
-				print "FE Compiles as DIAG TEST CODE\n";
-				$::diagTest = $spp[1];
-			} elsif ($spp[0] eq "dacwdoverride") {
-				print "FE Compiles with override of bad DAC error\n";
-				$::dacWdOverride = $spp[1];
-			} elsif ($spp[0] eq "dolphin_time_xmit") {
-				$::dolphin_time_xmit = $spp[1];
-			} elsif ($spp[0] eq "dolphin_recover") {
-				$::dolphin_recover = $spp[1];
-			} elsif ($spp[0] eq "dolphin_time_rcvr") {
-				$::dolphinTiming = $spp[1];
-			} elsif ($spp[0] eq "no_cpu_shutdown") {
-				$::no_cpu_shutdown = $spp[1];
-			} elsif ($spp[0] eq "pciRfm") {
-				print "FE will run with PCIE RFM Network\n";
-				$::pciNet = $spp[1];
-			} elsif ($spp[0] eq "dolphingen") {
-				print "FE will run with PCIE RFM Network\n";
-                # Set Dolphin Gen to run with; default=2
-				$::dolphinGen = $spp[1];
-			} elsif ($spp[0] eq "remoteGPS") {
-				print "FE will run with EPICS for GPS Time\n";
-				$::remoteGPS = $spp[1];
-			} elsif ($spp[0] eq "rfm_delay") {
-				$::rfmDelay = 1;
-			} elsif ($spp[0] eq "flip_signals") { 
-				$::flipSignals = $spp[1];
-			} elsif ($spp[0] eq "edcu") { 
-				$::edcu = $spp[1];
-			} elsif ($spp[0] eq "sdf") { 
-				$::globalsdf = $spp[1];
-			} elsif ($spp[0] eq "casdf") {
-				$::casdf = $spp[1];
-			} elsif ($spp[0] eq "requireIOcnt") { 
-				$::requireIOcnt = $spp[1];
-			} elsif ($spp[0] eq "virtualIOP") { 
-				$::virtualiop = $spp[1];
-			} elsif ($spp[0] eq "use_shm_ipc") { 
-				$::force_shm_ipc = $spp[1];
-			} elsif ($spp[0] eq "adcclock") { 
-				$::adcclock = $spp[1];
-			} elsif ($spp[0] eq "clock_div") { 
-				$::clock_div = $spp[1];
-			} elsif ($spp[0] eq "sync") { 
-				$::edcusync = $spp[1];
-			} elsif ($spp[0] eq "optimizeIO") { 
-				$::optimizeIO = $spp[1];
-			} elsif ($spp[0] eq "no_zero_pad") { 
-				$::noZeroPad = $spp[1];
-			} elsif ($spp[0] eq "ipc_rate") { 
-                # Specify IPC rate if lower than model rate
-				$::ipcrate = $spp[1];
-			}
-		}
+        			} 
+                    else  { 
+                        $errmsg = "\n************\n";
+                        $errmsg .= "***ERROR: Invalid Parameter Block Entry: rate = $param_speed \n";
+                        $errmsg .= "************\n\n";
+                        die $errmsg;
+                    }
+                    }
+                }
+
+                case "dcuid"
+                {
+				    print "PARAM Dcu Id is set to $spp[1]\n";
+				    $::dcuId = $spp[1];
+				    print "GDS node id is set to $::dcuId \n";
+				    $::gdsNodeId = $::dcuId;
+                }
+                case "host"
+                {
+				    print "PARAM Target host name is set to $spp[1]\n";
+				    $::targetHost = $spp[1];
+				    if ($RCG_HOST) {
+					    $::targetHost = $RCG_HOST;
+				    }
+                }
+                case "plant_name"
+                {
+				    print "Plant name is set to $spp[1]\n";
+				    $::plantName = $spp[1];
+                }
+                case "daq_prefix"
+                {
+				    $::daq_prefix = $spp[1];
+                }
+                case "no_sync"
+                {
+                    # This essentially set up IOP for a Cymac
+				    print "Will not sync up to 1PPS\n";
+				    $::no_sync = 1;
+                }
+                case "no_daq"
+                {
+                    # Will compile code not to use DAQ
+				    print "Will not connect to DAQ\n";
+				    $::no_daq = 1;
+                }
+                case "enable_fir"
+                {
+                    # Will compile code to use FIR filtes
+				    print "Will use FIR filters\n";
+				    $::useFIRs = 1;
+                }
+                case "no_oversampling"
+                {
+				    print "Will not oversample\n";
+				    $::no_oversampling = 1;
+                }
+                case "no_dac_interpolation"
+                {
+				    print "Will not interpolate DAC\n";
+				    $::no_dac_interpolation = 1;
+                }
+                case "specific_cpu"
+                {
+				    print "PARAM FE will run on CPU $spp[1]\n";
+				    $::specificCpu = $spp[1];
+                }
+                case "iop_model"
+                {
+				    print "PARAM FE is IOP\n";
+				    print "FE will run as IOP\n";
+				    $::iopModel = $spp[1];
+                }
+                case "diagTest"
+                {
+				    print "PARAM FE Compiles as DIAG TEST CODE\n";
+				    $::diagTest = $spp[1];
+                }
+                case "dacwdoverride"
+                {
+				    print "FE Compiles with override of bad DAC error\n";
+				    $::dacWdOverride = $spp[1];
+                }
+                case "dolphin_time_xmit"
+                {
+				    $::dolphin_time_xmit = $spp[1];
+                }
+                case "dolphin_recover"
+                {
+				    $::dolphin_recover = $spp[1];
+                }
+                case "dolphin_time_rcvr"
+                {
+				    $::dolphinTiming = $spp[1];
+                }
+                case "no_cpu_shutdown"
+                {
+				    $::no_cpu_shutdown = $spp[1];
+                }
+                case "pciRfm"
+                {
+				    print "PARAM FE will run with PCIE RFM Network\n";
+				    $::pciNet = $spp[1];
+                }
+                case "dolphingen"
+                {
+				    print "PARAM FE will run with PCIE RFM Network\n";
+                    # Set Dolphin Gen to run with; default=2
+				    $::dolphinGen = $spp[1];
+                }
+                case "remoteGPS"
+                {
+				    print "FE will run with EPICS for GPS Time\n";
+				    $::remoteGPS = $spp[1];
+                }
+                case "rfm_delay"
+                {
+				    $::rfmDelay = 1;
+                }
+                case "flip_signals"
+                {
+				    $::flipSignals = $spp[1];
+                }
+                case "sdf"
+                {
+				    $::globalsdf = $spp[1];
+                }
+                case "casdf"
+                {
+				    $::casdf = $spp[1];
+                }
+                case "requireIOcnt"
+                {
+				    $::requireIOcnt = $spp[1];
+                }
+                case "virtualIOP"
+                {
+				    $::virtualiop = $spp[1];
+                }
+                case "use_shm_ipc"
+                {
+				    $::force_shm_ipc = $spp[1];
+                }
+                case "adcclock"
+                {
+				    $::adcclock = $spp[1];
+                }
+                case "clock_div"
+                {
+				    $::clock_div = $spp[1];
+                }
+                case "sync"
+                {
+				    $::edcusync = $spp[1];
+                }
+                case "optimizeIO"
+                {
+				    $::optimizeIO = $spp[1];
+                }
+                case "no_zero_pad"
+                {
+				    $::noZeroPad = $spp[1];
+                }
+                case "ipc_rate"
+                {
+                    # Specify IPC rate if lower than model rate
+				    $::ipcrate = $spp[1];
+                }
+                # Following are old options that are no longer required
+                case "biquad"
+                {
+				    $nolongerused = 1;
+                }
+                case "adcSlave"
+                {
+				    $nolongerused = 2;
+                }
+                case "accum_overflow"
+                {
+				    $nolongerused = 2;
+                }
+                case "shmem_daq"
+                {
+				    $nolongerused = 2;
+                }
+                case "rfm_dma"
+                {
+				    $nolongerused = 2;
+                }
+			    else {
+                $errmsg = "***ERROR: Unknown Parameter Block Entry: ";
+                $errmsg .=  $spp[0] . "\n";
+                die $errmsg;
+                }
+		    }
+        }
 	}
+    # Check that all required Parameter block entries have been set
+    if($::ifo eq "dummy")
+    {
+        $errmsg = "\n************\n";
+        $errmsg .= "***ERROR: Missing Required Parameter Block Entry: ifo\n";
+        $errmsg .= "************\n\n";
+        die $errmsg;
+    }
+    if($::targetHost eq "dummy")
+    {
+        $errmsg = "\n************\n";
+        $errmsg .= "***ERROR: Missing Required Parameter Block Entry: host\n";
+        $errmsg .= "********: Please add host=targetname, where: \n";
+        $errmsg .= "********: \ttargetname is name of computer on which code will run\n";
+        $errmsg .= "************\n\n";
+        die $errmsg;
+    }
+    if($::rate eq 0)
+    {
+        $errmsg = "\n************\n";
+        $errmsg .= "***ERROR: Missing Required Parameter Block Entry: rate\n";
+        $errmsg .= "************\n\n";
+        die $errmsg;
+    }
+    if($::dcuId eq 0)
+    {
+        $errmsg = "\n************\n";
+        $errmsg .= "***ERROR: Missing Required Parameter Block Entry: dcuid\n";
+        $errmsg .= "************\n\n";
+        die $errmsg;
+    }
+    if($::specificCpu eq -1 && $::iopModel ne 1)
+    {
+        $errmsg = "\n************\n";
+        $errmsg .= "***ERROR: Missing Required Parameter Block Entry: specific_cpu\n";
+        $errmsg .= "********: Please add specific_cpu=x, where: \n";
+        $errmsg .= "********: \tx = CPU core on which code will run\n";
+        $errmsg .= "************\n\n";
+        die $errmsg;
+    }
 }
 
 sub printHeaderStruct {
@@ -223,6 +375,7 @@ sub printFrontEndVars  {
 # Check inputs are connected
 sub checkInputConnect {
         my ($i) = @_;
+				    print "PARAM doin connect check\n";
         return "";
 }
 
diff --git a/src/epics/util/skeleton.st b/src/epics/util/skeleton.st
index 6550232e0c7d293e57c5dd7ce75c6eb0550224e9..3192470178a98d982b20647aa54537a7c161b514 100644
--- a/src/epics/util/skeleton.st
+++ b/src/epics/util/skeleton.st
@@ -73,6 +73,7 @@ program %SEQUENCER_NAME%
 %% static %EPICS_TYPE% *pEpics;
 %% static unsigned int sysnum;
 %% extern void *findRfmCard(int);
+%% extern int fmCreatePartial(char *, char *, char *);;
 #else
 %% static VME_COEF vmeCoeffSpace;
 %% static COEF coeffSpace;
diff --git a/src/include/rcgversion.h b/src/include/rcgversion.h
index 279329e5983096fd3c1f579fbb5b96142e7d8841..551eee401ec55133a251fcd8ba730fcd716d9fe8 100644
--- a/src/include/rcgversion.h
+++ b/src/include/rcgversion.h
@@ -1,4 +1,4 @@
 #define RCG_VERSION_MAJOR 4
 #define RCG_VERSION_MINOR 0
-#define RCG_VERSION_SUB 1
+#define RCG_VERSION_SUB 2
 #define RCG_VERSION_REL 1