We want to convert the following small CCS source.
Imagine the follwing source is named interrupt.c and is located alone in a
directory called test. We go into this directory and call our shell script:
$ cd test
We get a new directory SDCC:
$ /path/to/file/convert.sh
Converting ./interrupt.c
$ cd SDCC
Now lets have a look at the code and what our tools did with it:
$ ls
disptab.c interrupt.c
before | after | |
#include "18F6720.h"
|
#include <compat.h>
|
Included our "compatibility layer" compat.h and replaced the #use pragmas by our preprocessor macros. The other preprocessor macros were left untouched. |
#byte foo = 0x10
|
uint8_t at 0x10 foo;
|
#byte pragmas were mapped to SDCC readable constructions, except those starting with PIC_. We guess, we can map them to existing symbols already defined in the SDCC headers. |
void PCLedRed (int state) {
|
void PCLedRed (uint8_t state) {
|
int was modified to uint8_t and the binary constant was converted into a hexadecimal constant. |
#inline
|
|
#inline was removed (has to be implemented manually) and symbols and labels appearing in inline assembler code were wrapped with a preprocessor macro that adds a "_" prefix. |
#int_timer1
|
#define timer1_handler timer1handler
|
#int was replaced by a preprocessor macro. |
#define hi(x) (*(&x+1))
|
#define hi(x) (*(&x+1))
|
Types were modified and #separate pragma was removed. |
int main () {
|
uint8_t main () {
|
Types were modified, variable data was renamed to __PIC_data (conflict with SDCC keyword) and delay_us(10) was replaced by delay_us_short(10). Although NINE will be expanded to 9, this line was not modified because the Perl script cannot interpret this macro. |
#fuses hs,noprotect,nobrownout,nolvp,put,nowdt
|
code char at __CONFIG1H config1h = 0xFF & _OSC_HS_1H;
|
Configuration words were replaced, noprotect was ignored. (not yet implemented) |
According to the migration guide, we have to adjust some things manually:
Script output | after manual modifications | |
#include <compat.h>
|
#include <compat.h>
|
Only a single preprocessor directive may appear per line. We also do not need the former include file from CCS. |
uint8_t at 0x10 foo;
|
uint8_t at 0x40 foo;
|
The locations of foo and bar raise a conflict. SDCC reserves the area from 0x00 to 0x22 for local variables, so foo and bar were moved. |
void PCLedRed (uint8_t state) {
|
void PCLedRed (uint8_t state) {
|
Everything is fine here, no additional work to be done. |
void my_delay (uint16_t time) {
|
void my_delay (uint16_t time) {
|
Replaced label and symbol in the inlined assembler code for better readability. This function will still not be inlined, which could be achieved by replacing the function with a #define. But this would not be enough, because the label loop will appear twice in the main functionthen , raising an error in the assembler. So if we wanted to inline this code, we had to replace the whole part and remove the label somehow. |
#define timer1_handler timer1handler
|
#define timer1_handler timer1handler
|
Everything is fine here, too. |
#define hi(x) (*(&x+1))
|
#define hi(x) (*(((char *)&x)+1))
|
Modified the hi macro, because SDCC &inttype + 1 would increase the address by two bytes (sizeof(int)), not 1 byte (CCS); hi(inttype) would return the value of the next integer in the registers behind inttype, not the upper byte of it. In addition to this, we had to add some types in the function parameter list. |
uint8_t main () {
|
uint8_t main () {
|
Included disptab.c and added calls to initialize the interrupt priority registers and to enable the low priority interrupts. |
code char at __CONFIG1H config1h = 0xFF & _OSC_HS_1H;
|
code char at __CONFIG1H config1h = 0xFF & _OSC_HS_1H;
|
Nothing to do here. |
Back to the CCSC2SDCC migration guide.