Bill Greiman
Well-known member
This is not a fault in the K66 chip but a problem in using all of SRAM as one contiguous block.
Here is a quirk common to various Cortex-M4 devices including Teensy 3.6/3.5. For critical systems care in SRAM use is required.
Many Cortex-M4 chips have several blocks of SRAM that appear as a large contiguous block.
Here is a quote from the data sheet for K66 processors.
So if you cross the boundary with a misaligned access, strange things happen. I may do that in the SDIO driver, depending on file position and user buffer alignment.
Even memcpy() fails for a misaligned copy across the boundary!
Here is an example.
Output from the program:
Here is a quirk common to various Cortex-M4 devices including Teensy 3.6/3.5. For critical systems care in SRAM use is required.
Many Cortex-M4 chips have several blocks of SRAM that appear as a large contiguous block.
Here is a quote from the data sheet for K66 processors.
The CPU does not fault for misaligned access at the boundary and the Cortex-M4 spec only says the access will be unpredictable.This device contains SRAM tightly coupled to the ARM Cortex-M4 core. The on-chip SRAM is split into SRAM_L and SRAM_U regions where the SRAM_L and SRAM_U ranges form a contiguous block in the memory map anchored at address 0x2000_0000. As such:
• SRAM_L is anchored to 0x1FFF_FFFF and occupies the space before this ending address.
• SRAM_U is anchored to 0x2000_0000 and occupies the space after this beginning address.
SRAM_L is 64 KB, SRAM_U is 192 KB.
NOTE:
Misaligned accesses across the 0x2000_0000 boundary are not supported in the ARM Cortex-M4 architecture.
So if you cross the boundary with a misaligned access, strange things happen. I may do that in the SDIO driver, depending on file position and user buffer alignment.
Even memcpy() fails for a misaligned copy across the boundary!
Here is an example.
Code:
uint32_t buf[4];
void setup() {
Serial.begin(9600);
// Fill memory with aligned access.
uint32_t *p = (uint32_t*)0X20000000;
for (int i = -2; i <= 2; i++) {
p[i] = 0X87654321;
}
// Check memory with aligned access.
Serial.println("aligned print");
for (int i = -2; i < 2; i++) {
Serial.print((uint32_t)&p[i], HEX);
Serial.print(' ');
Serial.println(p[i], HEX);
}
// Show misaligned access fails.
Serial.println("\nmisaligned print");
for (int i = -8; i <= 4; i++) {
uint32_t* m = (uint32_t*)(0x20000000 + i);
Serial.print((uint32_t)m, HEX);
Serial.print(' ');
Serial.println(*m, HEX);
}
// Misaligned memcpy fails at boundary.
Serial.println("\nmemcpy");
memcpy(buf, (uint32_t*)(0X20000000 -7), 16);
for (int i = 0; i < 4; i++) {
Serial.println(buf[i], HEX);
}
}
void loop() {
}
Output from the program:
aligned print
1FFFFFF8 87654321
1FFFFFFC 87654321
20000000 87654321
20000004 87654321
misaligned print
1FFFFFF8 87654321
1FFFFFF9 21876543
1FFFFFFA 43218765
1FFFFFFB 65432187
1FFFFFFC 87654321
1FFFFFFD 876543 <-- should be 21876543
1FFFFFFE 8765 <-- should be 43218765
1FFFFFFF 3000087 <-- should be 65432187
20000000 87654321
20000001 21876543
20000002 43218765
20000003 65432187
20000004 87654321
memcpy
21876543
876543 <-- should be 21876543
21876543
21876543
Last edited: