As mentioned in #Adventures with a STC89C52 development board I bought that development kit because it could accept some AVR MCUs that are almost pin-compatible with the STC89C52. This got me thinking of how I could use the couple of ancient AVR chips that I have. Ideally I would like to reuse firmware that I have written and not have to develop from scratch. So as an exercise in learning more about AVR architecture, I decided to see if I could modify the STC89C52 code so that it could be compiled for more than one type of MCU.
My requirements are:
- Make it possible to select MCU type with a #define.
- Restrict the MCU specific code to as few files as possible. This means that lots of #ifdefs in the main functions of the code are not acceptable.
- Share the rest of the files unmodified. It's ok for these files to contain macro invocations that expand differently depending on the target.
I went in and hacked at it until I had something acceptable. I was lucky in some respects:
- The STC89 and AT90S families are similar in that 4 8-bit GPIO ports are exposed. They both also have two timers. If the families had been more disparate, it would have been a harder job.
- Both avr-gcc and SDCC accept a fairly comprehensive set of C language features, and the differences are easy to use macros to hide.
- The business logic (which is for a clock) is quite independent of the MCU architecture so large chunks of code contain no hardware specific manipulation.
- The hardware specific parts of the code only have to deal with GPIO ports, timers, and interrupt handlers. A more complex MCU application might have more MCU specific code.
Some constants, like those used for time constants for the button UI can be defined in common include files. Other constants, such as the values loaded into MCU registers, are in MCU specific include files.
The overhead is very acceptable, only increasing the binary size by tens of bytes due to some inline code being turned into functions.
I noted that for avr-gcc it's ok for static functions to be defined in .h files because avr-gcc is smart enough to not emit code for the body if the function is not used later in the .c file. In SDCC the functions need to be in a .c file and global rather than static otherwise if in a .h file there will be a copy for every .c file it's included in.
The changes have been pushed to the Github archive.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.