Long time reader first time poster.
Im designing my own board for another purpose using the same ATSAM3X chip, and after reading this thread I am still a little confused as to how to setup External ram as a continuation of the internal ram - presumable this is possible.
What I mean by this, assuming that all the control, data and address lines are connected correctly to an external chip, how does the MCU know to point the stack to this external memory once all of the internal 48Kb internal ram is used ? is it automatic after setting some SMC control bit in some register?
If this is not possible, then it requires some memory management in code which is quite annoying. Any help would be appreciated.
Fair question. The external memory appears to the MCU as a block of memory at an address depending on its Chip Select line. (These pins are labelled NCS0-NCS7 on the SAM3X). Typically you would connect CSx to the CS pin on your memory device. The lowest 24 bits of a memory address are decoded by the external memory device, the upper 8 bits are decoded in the memory controller. The locations of the memory sections are shown in Figure 8-1 of the SAM3X User Manual. For example, CS0 maps to 0x60000000.
The second question is how to map the application code to memory regions. This can be done very simply by direct access and setup from the application code, but this method is less flexible. You can allocate dynamic variables at runtime just by setting their address to a hardcoded value correspodning to the external memory. If you want to get automatic placement of variables, then you would need to use the linker.
By changing the linker file, you can specify the additional memory region, and what should go into it. At runtime, RAM variables will be zeroed or initialised with data copied from Flash as necessary. This is part of the Standard C initialisation procedure. With GCC toolchain you may need to edit a startup file to include the additional memory regions.
Note that you will need to edit the startup code to setup the memory controller before letting the code does its memory copying/zeroing. If you put the stack into external memory, you must make sure your startup code does not use it before it is setup! It is probably best to set a temporary stack in internal RAM for the startup code, and then change stack after the external memory is setup. It is simpler though to keep stack in internal memory, and use the external memory for other stuff.
The third question is how to get the application to use the extended memory. This can be done in the linker file, using combination of "pragma section" and the linker file, or explicitly in the application, depending on taste.
If this all seems quite complicated, then you are probably right. It needs good knowledge of the MCU and the toolchain to set the right things at the right point. Once setup, it becomes fairly seamless, but get one tiny thing wrong and it falls over in a heap.
To keep it simple, I would probably use direct setup from the application, and use the external memory as a pool of dynamic buffers for bulk data.