|
|
(5 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) |
Zeile 1: |
Zeile 1: |
− | = 8-bit AVRs and similar microcontrollers are not OK anymore =
| + | #REDIRECT [[Benutzer:Rdiez/PageRemoved]] |
− | | + | |
− | 8-bit CPUs are obsolete and should not be used anymore in most situations.
| + | |
− | | + | |
− | Unless you manufacture hundreds of thousands of devices, sooner or later you will realise that
| + | |
− | the software investments by far outweigh the hardware costs. The constraints imposed by 8-bit architectures will make development harder, and speed and space issues will probably force you to write more code in assembly language than otherwise necessary. Furthermore, the tight architectural limitations will probably shorten the product lifetime or hold desired features back in the future.
| + | |
− | | + | |
− | If you finally decide to migrate to a 32-bit CPU, you will find that sharing code between 8-, 16- and 32-bit platforms is difficult, even without the memory address issues described below. Therefore, you will probably have to leave the existing 8-bit software aside and create a separate branch for the new processor.
| + | |
− | | + | |
− | = CPU architectures with different address spaces are especially nasty =
| + | |
− | | + | |
− | Many 8-bit CPUs, like the Atmel AVR microcontrollers, are not actually compatible with the C/C++ language.
| + | |
− | The C standard requires a flat memory space, but AVRs provide two of them: program memory and data memory.
| + | |
− | Therefore, a given memory address like 0x0000 is ambiguous, as it could refer to the first code word in program space (usually flash memory) or to the first data word in data space (usually SRAM).
| + | |
− | This is what the datasheets mean when they say that the AVRs have a [http://en.wikipedia.org/wiki/Harvard_architecture Harvard architecture], although the architecture itself has actually nothing to do with the ambiguous addressing issues.
| + | |
− | | + | |
− | An AVR memory address needs to be qualified at C language level
| + | |
− | in order to disambiguate it. This is what PROGMEM, PGM_P, PSTR and the like do in the 8-bit AVR world,
| + | |
− | and that is why there are 2 or even 3 versions of many C runtime library routines, such as strlen(), strlen_P() and strlen_PF().
| + | |
− | | + | |
− | Other CPU architectures have even more memory spaces, there are DSPs out there with X, Y and Z address spaces.
| + | |
− | Avoid such CPUs like the plague! With such architectures, you cannot copy C/C++ source
| + | |
− | off the Internet and use it directly on your CPU, you need to carefully inspect all the code
| + | |
− | and add the memory space qualifiers to the pointers that need it. You may need to call strlen() in one place, and strlen_PF() in another one. If you miss one of those, you may not notice
| + | |
− | straight away, but your program may crash later on. And you will not be able to easily share the code
| + | |
− | with other CPUs, because those tricks are usually platform specific. Nowadays, this is just not worth the trouble.
| + | |
− | | + | |
− | = No memory protection at all =
| + | |
− | | + | |
− | Many microcontrollers have no memory protection whatsoever, not even the most basic tricks. It would be really easy to leave the first and last 4 KBytes of memory space unused, and trigger some sort of access violation if somebody tries to access them. That would catch most NULL pointer errors in C/C++, which would help prevent many nasty bugs and save a great deal of debugging time. Furthermore, any unmapped or unused memory region should also trigger an access violation, which would also help catch bugs like trying to dereference an uninitialised pointer.
| + | |
− | | + | |
− | However, most microcontrollers just ignore invalid addresses. Or worse, most architectures place critical data structures, like interrupt vectors or I/O addresses, at the first memory addresses, where they are most likely to be hit by NULL pointer bugs.
| + | |
− | | + | |
− | = Drawbacks specific to the AVR architecture =
| + | |
− | | + | |
− | At the beginning, 16 bits probably seemed enough for memory addressing purposes, so strlen_P() and friends sufficed. Remember that an AVR program space address is 16-bit wide, instead of the usual 8 bits, so with a 16-bit address you can access 64 K x 16 bits = 128 KBytes of program memory (Flash). But then AVRs with 256 KBytes of Flash came along, and then you suddenly needed more than 16 bits to address all of it, so Atmel came up with hacks like strlen_PF() and the RAMPZ register.
| + | |
− | | + | |
− | In C/C++, 24-bit integers are rare, so the new ''uint_farptr_t'' type got mapped to uint32_t. Addresses are now 4-byte long, but the CPU can only read and compute 8 bits at a time, so the code becomes bigger and slower. Smaller AVRs do not support those address extensions, which is the reason why the code needs to be recompiled for smaller chips. The conditional compilation for all those hacks has rendered [http://www.nongnu.org/avr-libc/ AVR Libc]'s source code unreadable. Note that the AVRs need a separate libc, as sharing such code with other CPUs is impractical.
| + | |
− | | + | |
− | And there is yet another addressing hack: if the AVR has more than 256 bytes of SRAM, the stack pointer becomes 16-bit wide, but the AVR can only write 8 bits at a time, which means each function prolog and epilog needs to disable interrupts for a short time in order to save and restore the stack frame pointer. Otherwise, an interrupt could trigger at the wrong time and corrupt the stack pointer.
| + | |