full cloning one fully functional RCM3100 to a new RCM3100 Board

It’s the same procedure to clone a rcm3100 to another rcm3100 board as you said above?
Thanx in advance

It’s a bit different because the RCM3100 uses a parallel flash for program storage and I don’t think it has Ethernet. You’d still need to compile a program to RAM, but then you need to find a way to transfer the program to your PC. You could possibly do a hex dump and capture the debug session.

I can do this with any kind of jtag programmer?

The RCM3100 doesn’t have a JTAG interface. I don’t know if it’s possible to clip some hardware onto the parallel flash chip to read from it. I will look into creating a program that you can compile to RAM that will read the flash and dump it in a way that you can process.

Give this program a try and let me know if you have any problems with it.


/*
   Copyright (c) 2017, Digi International Inc.

   Permission to use, copy, modify, and/or distribute this software for any
   purpose with or without fee is hereby granted, provided that the above
   copyright notice and this permission notice appear in all copies.

   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
	extract_flash.c
	
	A program you can compile to RAM on Rabbit hardware in order to dump a copy
	of the firmware stored on the flash.  You can use the Rabbit Field Utility
	(RFU) to install the firmware on a new board after converting the Base64
	dump to a binary file (using the built-in Windows command-line CERTTOOL.EXE).
	
	You may need to temporarily comment out compiler warnings in BOARDTYPES.LIB
	around line 336:
		#error "Compile to RAM option programs the battery-backed RAM on CS1 and destroys any persistent data stored there."
		#fatal "Comment out this error if you still want to run off the ram on CS1."

	Limitations
	===========
	Limited testing included devices with 256KB and 512KB flash configurations,
	but not 128KB (BL1810 and BL1820).  Detecting prog_param structure (used
	to calculate image size) worked on firmware built with Dynamic C versions
	from 8.61 to 9.62.
	
	Not designed/tested for systems using the DLM/DLP or "COMPILE_SECONDARY_PROG"
	compiler option.
	
	If you need to comment out the compiler warnings in BOARDTYPES.LIB (see
	above), this process will erase the board's non-volatile, battery-backed RAM.
	
	If extracting the entire flash, look for a large run of 0xFF bytes to find
	the end of the program.
	
	How to use it
	=============
	Run from Dynamic C and confirm that the program finds the prog_param
	structure at the start of the flash.  It uses that structure to
	determine the firmware image size.  Without it, it will just dump the
	entire flash and you'll have to manually truncate it.
	
	Then run from the command line and confirm that it still works.  If you leave
	the IDE running, be sure to choose "Close Connection" from the "Run" menu
	to free up the serial port.
	
		C:\DCRABBIT_9.62>dccl_cmp extract_flash.c
		
	Then run again with DUMP_FIRMWARE defined to create a base64-encoded file.
	NOTE: This could take minutes to complete -- be patient!
	
		C:\DCRABBIT_9.62>dccl_cmp extract_flash.c -d DUMP_FIRMWARE > firmware.b64

	Then use the Windows program CERTTOOL.EXE to convert it to a binary file:
	
		C:\DCRABBIT_9.62>certutil -decode firmware.b64 firmware.bin

	You should now be able to program a new board with firmware.bin using RFU.
	
	If you want an image of the entire flash, define the macro DUMP_FLASH
	instead of DUMP_FIRMWARE.

*/

#ifndef RAM_COMPILE
#error "Must compile to RAM so you don't overwrite the flash!"
#fatal "Choose Options/Project Options/Compiler/BIOS Memory Setting/Code and BIOS in RAM"
#endif

#use "base64.lib"

#if FLASH_SIZE == 512>>2
	#define BASE_ADDR   0x80000ul
	#define FLASH_BYTES 0x80000ul
#elif FLASH_SIZE == 256>>2
	#define BASE_ADDR   0xC0000ul
	#define FLASH_BYTES 0x40000ul
#elif FLASH_SIZE == 128>>2
	#warns "128KB flash untested and based on guesses about the memory map!"
	#define BASE_ADDR   0xC0000ul
	#define FLASH_BYTES 0x20000ul
#else
#fatal "Designed for 256KB or 512KB flash."
#endif

// Dynamic C 9 does not support defined() in preprocessor
#ifndef DUMP_FLASH
	#define SEARCH_PROG_PARAM
#endif
#ifdef DUMP_FIRMWARE
	#define DUMPING_BASE64
#else
	#ifdef DUMP_FLASH
		#define DUMPING_BASE64
	#endif
#endif

#ifndef ALTERNATE_PATTERN
// Search for this signature from the prog_param.RCDB/RCDE
const char search_pattern[] = { 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00 };
#define PATTERN_OFFSET 32
#else
// Alternate search pattern that might work if the first pattern doesn't.
// Searches for this signature from the prog_param.XDB/XDE
const char search_pattern[] = { 0x00, 0xE0, 0x7E, 0x00, 0x00, 0xE0, 0x7E, 0x00 };
#define PATTERN_OFFSET 24
#endif

// keep a buffer of the start of flash so we can hopefully find the prog_param
char flash_start[12*1024];

#define PRINT_ADDR24(x, desc) \
	printf(desc " %02X:%04X to %02X:%04X
", \
	flash_prog_param->x##B.aaa.a.base, flash_prog_param->x##B.aaa.a.addr, \
	flash_prog_param->x##E.aaa.a.base, flash_prog_param->x##E.aaa.a.addr)
#define CHUNK_SIZE 57   // 57 bytes allows for 76-byte lines of base64 output
int main()
{
	char base64_buffer[((CHUNK_SIZE+2)/3*4)+1];
	char flash_buffer[CHUNK_SIZE];
	char *p, *end;
	struct progStruct *flash_prog_param;
	unsigned int copy;
	unsigned long addr;
	unsigned long dump_bytes, firmware_size;
	
	flash_prog_param = NULL;
	
#if FLASH_SIZE == 512>>2
	// 512KB of flash (single or 2x256KB?) mapped to MB2 and MB3
	WrPortI(MB2CR, &MB2CRShadow, FLASH_WSTATES | 0x00);
	WrPortI(MB3CR, &MB3CRShadow, FLASH_WSTATES | 0x00);
	_InitFlashDriver(0x0C);
#elif FLASH_SIZE == 256>>2 || FLASH_SIZE == 128>>2
	// single flash (256KB or 128KB?) mapped to MB3
	WrPortI(MB3CR, &MB3CRShadow, FLASH_WSTATES | 0x00);
	_InitFlashDriver(0x08);
#endif
	
	dump_bytes = FLASH_BYTES;

#ifdef SEARCH_PROG_PARAM
	xmem2root(flash_start, BASE_ADDR, sizeof flash_start);
	end = &flash_start[sizeof flash_start - 8];
	for (p = flash_start; p < end; ++p) {
		p = memchr(p, search_pattern[0], end - p);
		if (p == NULL) {
			break;
		}
		if (memcmp(p, search_pattern, 8)) {
			continue;
		}
      flash_prog_param = (void *)(p - PATTERN_OFFSET);
      dump_bytes = flash_prog_param->HPA.aaa.a.addr +
         (flash_prog_param->HPA.aaa.a.base << 12lu);
      break;
	}

#ifndef DUMPING_BASE64
	if (flash_prog_param == NULL) {
		printf("Did not locate prog_param in first %uKB; unknown image size.
",
			sizeof(flash_start)/1024);
#ifndef ALTERNATE_PATTERN
		printf("You could try again with ALTERNATE_PATTERN defined.
");
#endif
	} else {
		printf("Found prog_param at 0x%04X (using %s pattern).
",
			(char *)flash_prog_param - flash_start,
			#ifdef ALTERNATE_PATTERN
				"alternate"
			#else
				"primary"
			#endif
			);
		#ifdef VERBOSE
			PRINT_ADDR24(RC, "root code");
			PRINT_ADDR24(XC, "extended code");
			PRINT_ADDR24(RD, "root data");
			PRINT_ADDR24(XD, "extended data");
			PRINT_ADDR24(RCD, "root constant data");
			printf("HPA 0x%06lX (%lu bytes)
", dump_bytes, dump_bytes);
			printf("auxStk 0x%04X to 0x%04X
",
				flash_prog_param->auxStkB, flash_prog_param->auxStkE);
			printf("stk 0x%04X to 0x%04X
",
				flash_prog_param->stkB, flash_prog_param->stkE);
			printf("free 0x%04X to 0x%04X
",
				flash_prog_param->freeB, flash_prog_param->freeE);
			printf("heap 0x%04X to 0x%04X
",
				flash_prog_param->heapB, flash_prog_param->heapE);
			printf("
");
		#endif // VERBOSE
		if (dump_bytes > FLASH_BYTES) {
			printf("Calculated %lu-byte firmware larger than %lu-byte flash
",
				dump_bytes, FLASH_BYTES);
		} else {
			printf("Define DUMP_FIRMWARE to extract %lu-byte firmware image.
",
				dump_bytes);
		}
	}
	printf("Define DUMP_FLASH to extract entire %uKB flash.
",
		(unsigned)FLASH_SIZE << 2);
	return 0;
#endif // ! DUMPING_BASE64
#endif // SEARCH_PROG_PARAM

	addr = BASE_ADDR;
	while (dump_bytes) {
		copy = CHUNK_SIZE;
		if (copy > dump_bytes) {
			copy = (unsigned int) dump_bytes;
		}
		
		xmem2root(flash_buffer, addr, copy);
		base64_encode(base64_buffer, flash_buffer, copy);
		printf("%s
", base64_buffer);
		
		dump_bytes -= copy;
		addr += copy;
	}
	
	return 0;
}

I’ll be adding this program to the Dynamic C 9.62 repository on GitHub after some further testing.

Hello friend i get this error "Did not locate prog_param in first 12KB; unknown image size.
You could try again with ALTERNATE_PATTERN defined.
Define DUMP_FLASH to extract entire 256KB flash.

OK, did it find the structure after defining ALTERNATE_PATTERN? If not, were you able to get a copy of the entire flash by downloading DUMP_FLASH and reading the code comments on how to convert it to binary? If you send me a copy of the binary (tom.collins with digi.com as a domain name) I will figure out the image size for you.

No the program stopped and it’s shows this “program terminated.exit code 0.”

Did you follow the directions in the documentation to use the command-line compiler and dump the results to a file? Defining “DUMP_FLASH” before running should result in a dump of the flash contents before the program exits.

Hi, I am able to run the program in dynamic C and it is able to locate prog_param successfully. When I run it in the command line with “dccl_cmp extract_flash.c -d DUMP_FLASH > flashtest.b64” it creates the flashtest.b64 file successfully, but in the file it says “Error Timeout while waiting for response from target.” What am I doing wrong?

I am now able to run the program with DUMP_FIRMWARE, but it is saving .b64 files larger than the flash. When I run without anything defined it will also output “Calculated 1089022-byte firmware larger than 524288-byte flash”