You’re certain that this happens with unmodified versions of Dynamic C? Always the same address? How about test programs that don’t use TCP/IP? Programs with TCP/IP make use of the external memory of the RCM6760, but simpler programs do not.
I’m attaching a test program for the external SRAM that you could try. It was used to troubleshoot a hardware issue triggered by 32-bit reads of the SRAM on a revision of RCM6650W boards (that did not ship to customers).
Please reach out to your sales rep or Digi support (http://www.digi.com/support) about this issue to identify possible causes.
// set this define to 1 for verbose output for each test failure, 0 for quiet
#define VERBOSE 1
// uncomment this define to initialize memory at startup
#define INITIALIZE_MEMORY
#define STDIO_DEBUG_SERIAL SADR
#define STDIO_DEBUG_BAUD 115200
#define STDIO_DEBUG_ADDCR
#define START_ADDRESS 0x00100000ul
#define STOP_ADDRESS (START_ADDRESS + 0x00100000ul)
unsigned long run_test(int verbose)
{
// track the mis-read bits in the 2nd MSB of the reads
unsigned int failure_patterns[256] = { 0 };
// track the flipped bits in the reads
unsigned int failure_bits[32] = { 0 };
// track which read failed by finding the odd-man out
// 0 = all three read differed; 1, 2, 3 = read that differed
unsigned int failed_read[4] = { 0 };
unsigned long address, readaddress;
unsigned long read1, read2, read3;
unsigned long badvalue, flippedbits, mask;
unsigned long test_count = 0, failures = 0;
int i;
if (verbose)
{
printf("Testing 32-bit reads from odd addresses from 0x%06lx to 0x%06lx.
",
START_ADDRESS, STOP_ADDRESS);
}
for (address = START_ADDRESS + 1; address < STOP_ADDRESS - 3; address += 2)
{
++test_count;
#asm __nodebug
ipset 3
ld pz, (sp+@sp+address)
ld pw, (pz)
ld px, (pz)
ld py, (pz)
ld (sp+@sp+read1), pw
ld (sp+@sp+read2), px
ld (sp+@sp+read3), py
ld (sp+@sp+readaddress), pz
ipres
#endasm
if (read1 != read2 || read1 != read3)
{
// which read failed?
if (read1 == read2) // read3 mismatch
{
badvalue = read3;
++failed_read[3];
}
else if (read1 == read3) // read2 mismatch
{
badvalue = read2;
++failed_read[2];
}
else if (read2 == read3) // read1 mismatch
{
badvalue = read1;
++failed_read[1];
}
else // no reads matched
{
badvalue = 0;
++failed_read[0];
}
++failures;
flippedbits = (read1 != read2) ? (read1 ^ read2) : (read2 ^ read3);
// mark which bits were flipped in the reads
for (i = 0, mask = 1; i < 32; mask <<= 1, ++i)
{
if (flippedbits & mask)
{
++failure_bits[i];
}
}
if (verbose)
{
++failure_patterns[(unsigned char)(badvalue >> 16)];
printf("ERR: Read 0x%08lx, 0x%08lx, 0x%08lx from 0x%06lx (BYTE2:0x%02x)
",
read1, read2, read3, address, (unsigned char)(badvalue >> 16));
}
}
if (readaddress != address)
{
++failures;
if (verbose)
{
printf("ERR: read back address 0x%06lx as 0x%06lx (bad bits: 0x%06lx)
",
address, readaddress, readaddress ^ address);
}
}
}
if (verbose)
{
if (failures != 0)
{
printf("%lu total failures of %lu (%.6f%%)
", failures, test_count,
failures * 100.0 / test_count);
for (i = 1; i < 4; ++i)
{
printf(" read%u mismatch:%5u
", i, failed_read[i]);
}
printf( "no reads matched:%5u
", failed_read[0]);
for (i = 0, mask = 1; i < 32; mask <<= 1, ++i)
{
printf(" bit %2u (0x%08lx):%5u
", i, mask, failure_bits[i]);
}
for (i = 0; i < 256; ++i)
{
if (failure_patterns[i])
{
printf(" pattern 0x%02x:%5u
", i, failure_patterns[i]);
}
}
}
else
{
printf("Test PASSED
");
}
}
return failures;
}
void main(void)
{
unsigned long address, error_count;
// Note that this test works regardless of the SRAM contents. During
// testing, we found that varying data stored in memory resulted with
// a higher failure rate, so recommended test procedure is to initialize
// memory at the start of the test.
#ifdef INITIALIZE_MEMORY
printf("Initializing memory to low byte of address.
");
for (address = START_ADDRESS; address < STOP_ADDRESS; ++address)
{
*(unsigned char far *)address = (unsigned char)(address & 0xFF);
}
#endif
error_count = run_test(VERBOSE);
if (error_count)
{
printf("SRAM Test: %lu total FAILURES
", error_count);
}
else
{
printf("SRAM Test: PASSED
");
}
}