4

Can I use an SD card as ROM for my microcontroller? What other options are there if I want a large amount of ROM memory (cheap)?

Peter Mortensen
  • 1,676
  • 3
  • 17
  • 23
Inquisitive
  • 321
  • 3
  • 12
  • 2
    short answer Yes. Somewhat longer answer: most microcontrollers cannot run a program from it due to its Harvard architecture. – jippie Dec 26 '12 at 18:46
  • It depends as what you mean by ROM. Do you mean just some memory that you read and don't modify, or do you mean RAM that is accessed by the CPU? If you're just looking for some memory to place data, then yes, SD cards can act as such, but their speed will be nowhere near the speed of that the memory closest to the CPU can provide. – Gustavo Litovsky Dec 26 '12 at 18:54
  • @gl3829 I want a cheapest method to have additional ROM where I will be storing the program to be executed. – Inquisitive Dec 26 '12 at 18:56
  • Using an SD card for this is very involved (bordering on almost impossible) since you'll have to read the program code to the microcontroller's memory. Consider that you will spend a lot of time to get this working and since time is money, the cheapest alternative is to just buy a bigger microcontroller or optimize the code so that it fits. Also, this method will cause execution to suffer depending on how much transfers you need and how fast it can be done. Can you give an idea of size that you need as far as program code space? – Gustavo Litovsky Dec 26 '12 at 19:02
  • 4
    What kind of microcontroller? – Dave Tweed Dec 26 '12 at 19:02
  • 1
    @gl3829 I think "bordering on impossible" is an exaggeration. This is very doable in both C and in assembly, though definitely non-trivial. Definitely going to make execution speed take a serious hit, and will require about 512 bytes of ram to be spare at every call/return which goes to the card, but possible. Depends on how crazy he wants to be! (I'm kind of digging the crazy aspect right now >:D ) – Kit Scuzz Dec 26 '12 at 20:31
  • Ok. Maybe I went too far in calling it bordering impossible :D The op wanted something very inexpensive. As time goes, this is one of those things. I've done similar things in the past, and it's usually not worth the effort except in some very specific cases. – Gustavo Litovsky Dec 26 '12 at 20:34
  • I agree that it's likely not worth it! – Kit Scuzz Dec 26 '12 at 20:43

2 Answers2

8

So it depends on what you want to do. As a general rule: if you're willing to run slowly enough, you can do whatever the heck you want.

On microcontrollers (like a PIC or an ATMega processor (not including PIC32 or Atmel's ARM processors)) you normally have a Harvard Architecture which means that code and data are stored in different parts of memory and accessed differently. This means that if you load up a piece of code from an SD card, it will be in RAM, and you will not be able to treat it as code without some special acrobatics. You can write the loaded information to the internal code banks (which is how bootloaders work), but essentially you'll never be able to have more code loaded than what your microcontroller started with for code size limits. Now, you could (with some effort) write special "call" and "return" features in your code which essentially were functions which would load the requested address out of the SD card and write it into the internal code banks and then call the newly loaded code. This would necessitate that every function you had was smaller than the internal code banks, but that wouldn't be hard. The tough part would be that this would cause a lot of wear on the code sections of memory in your chip, which are frequently only rated for ~100,000 writes (or as mentioned below, as low as 10,000 writes!).

On most Von Neumann architecture (and Hybrid-harvard) machines (ARM, Mips, and x86 as well as others), data and instructions are interchangeable. This means that you can much more easily write code to load the instructions out of the SD card and into ram, and then start running. If you don't have as much RAM as you have code (which, based on your original premise sounds unlikely), then you'll still need to do some tricky stuff to either repeatedly call to load from SD card into RAM, just like the previous example called to load from the SD card into program memory.

If you have a Von Neumann architecture and are lucky enough to have a microcontroller with a memory management unit or some sort of software-defined paging mechanism (I think they have this now but I don't know what it is), then you can start applying virtual memory concepts. You'll put all of the code into RAM, and page out code to the SD card. This is super complex if not already implemented on/in your microcontroller, so I won't go through explaining it unless you think this is what your planning to do (I'll need to look some of the ARM-based software paging mechanisms in order to help). This one requires the fewest changes to your initial code, but essentially requires an operating system on top of your code to handle code page switches.

Hope that helps!


EDIT:

As many have mentioned in the comments below, perhaps your best bet is to build an interpreter which fetches instructions from the SD card and executes them using code in the internal ROM. This works for both Harvard and Von Neumann architectures, as you have code which is permanent which executes based on data from the SD card. There are several implementations of this already in existence: see Basic Stamp or NanoVM for some jumping off points. Understand that this will, of course, always be pretty slow. And if you don't want to use a pre-made example of this you'll be caught making your own compiler/tokenizer as well as the interpreter, which will lead to a lot of complicated debugging. Upsides to this is that once you have it all working you can port your interpreter to any architecture and you'll be ready to go very quickly!

Kit Scuzz
  • 3,279
  • 21
  • 19
  • 1
    An interpreter'like setup will work with Harvard. Pseudo code can be loaded from SD and executed by the interpreter in ROM. – jippie Dec 26 '12 at 21:12
  • @jippie Yikes! Yes, that's definitely true and I've [seen it done before](http://dmitry.co/index.php?p=./04.Thoughts/07.%20Linux%20on%208bit) though I'm not sure I'd ever recommend it in a serious context... – Kit Scuzz Dec 26 '12 at 21:16
  • I think 8051 chips are an exception for this. Please verify my comment. – Standard Sandun Dec 26 '12 at 21:34
  • There are several working/commercial modules executing interpreted language on a µC; for example the ["Basic Stamp"](http://en.wikipedia.org/wiki/BASIC_Stamp) or the ["C-Control"](http://de.wikipedia.org/wiki/C-Control). – JimmyB Dec 26 '12 at 22:04
  • @HannoBinder I explicitly made your first point about the limited number of writes right in the answer! I said 100,000, but that may not be completely accurate. As for your second point: yes, this is definitely true they are just slow and writing your own interpreter is still a big daunting task (and in my head I was also imagining trying to write something bigger than those). I suppose doing something like taking a basic stamp and modifying it to take a stream of instructions from an SD card would likely not be too difficult, and definitely simpler than some of the stuff I suggested... – Kit Scuzz Dec 26 '12 at 22:09
  • @sandundhammika I don't understand your comment. And exception to what? – Kit Scuzz Dec 26 '12 at 22:10
  • @KitScuzz: Sorry, must've over-read that part of your answer; I'm deleting that comment :) – JimmyB Dec 26 '12 at 22:12
  • Of course, before storing it to the SD card, one would 'compile' the interpreted language to some 'byte code' that is easily interpreted by the µC. I assume this is just how the commercial modules do it. - For performance one would then only delegate non-time-critical logik to the interpreter while doing other tasks 'natively'. – JimmyB Dec 26 '12 at 22:15
  • @HannoBinder - I don't know how recent solutions have done it, but early BASIC's tended to tokenize - ie, they pre-parsed, but didn't really compile. In part because they were interactive, ie you could develop on the device and make immediate statements. – Chris Stratton Dec 26 '12 at 22:18
  • Oh, and there is the [NanoVM](http://en.wikipedia.org/wiki/NanoVM), which provides everything needed for a simplified Java interpreter. – JimmyB Dec 26 '12 at 22:20
  • I think 8051 is not your harvard architecture – Standard Sandun Dec 26 '12 at 22:23
  • @ChrisStratton Yes, I remember those times too... :) – JimmyB Dec 26 '12 at 22:31
  • @sandundhammika [Wikipedia seems to suggest](http://en.wikipedia.org/wiki/8051) that the 8051 is a Harvard Architecture chip. – Kit Scuzz Dec 26 '12 at 22:35
  • @ChrisStratton / HannoBinder Once we get to the point where you're either making your own compiler/tokenizer I imagine you've passed the realm of reason for most projects! That being said it's good advice, I'll add it to the answer. – Kit Scuzz Dec 26 '12 at 22:37
2

While hard to work with, there are situations where the "overlay" technique once used in the past of computing could be workable.

Typically, that consisted of explicitly swapping major functional fractions of a program into limited RAM from disk in turn as they were needed for various distinct modes of operation. While "slow" compared to dedicated program memory, sdcards are orders of magnitude faster than the floppy drives with which the technique was often used - especially in read mode.

To a substantial extent, modern virtual memory is a sort of automatic, often nearly invisible implementation of this idea - a lot easier to work with, but requiring hardware support.

The problem with the explicit overlay technique though is that you need to be able to divide your program into distinct, largely self-contained pieces, or at least ones that only have interactive dependency on the fixed portion of the program but not on each other. Thus it would be more suited to occasionally used extras, plug ins, etc than to features which must constantly be utilized in rapid or interleaved sequence.

Chris Stratton
  • 33,282
  • 3
  • 43
  • 89
  • 1
    This also demands that you have a "hybrid-harvard" or Von Neumann architecture. With a standard PIC or ATMega (Harvard Architecture), you can't execute code from RAM! – Kit Scuzz Dec 26 '12 at 22:04
  • That pretty much goes without saying. Though technically, you could, with a virtual machine or interpreter as I now see others have been mentioning. – Chris Stratton Dec 26 '12 at 22:16