I've been looking at SDCC and I notice two things, one is it has almost zero activity on the sdcc users mailing list the second thing is that each and every example of sdcc code has its own delay function.
Its fine for a desktop ANSI style compiler to ignore time, but not an embedded compiler. I personally think its important for the compiler to be aware of the CPU clock speed and to have access to a built in set of delay functions.
Its the job of the linker to leave unused functions on the cutting room floor so its hardly code bloat to have a built in for delay_ms and delay_us ?
Its verging on retarded for each application developer for each target CPU to hand code a set of delay functions.
Things I would like to see in SDCC are a proper preprocessor function to support a #fuses like for pics like with the ccs compiler, and also some mechanism to tell the compiler about clocks. The common clock code could then be used to impliment software UART, I2C etc that should then be portable accorss CPUS.
I would be willing to help build the tables of OPCODES/Vs cycles for this work.
I think this has been covered either here or on the list years ago.
I'm just a user of SDCC, and only use a few different 8051's. Some of the problems implementing this are the 1000's of different 8051/2's. Depending on the chip or your board you have a different clock rate. Then different CPUs have different number of instructions/clock. Then some CPUs have clocks which have a configurable clock rate to save power, just by changing a register.
I've done a little bit with PICs just to know you have 100's or 1000's of pics with the same issues.
Some people may have a timer, or RTC available to do a delay count, others may only be able to do a busy loop. Then there are questions of weather you care that you are interrupted or not, or weather you can call this function from a interrupt.
IMHO on parts with only a few KB of ROM and maybe only 128 bytes of RAM, it's probably better to let the programmer decide what is the best way to implement your delay..
I'm with Karl H. It's very implementation dependant. Having said that, I have found that it is almost universal to implement a Heartbeat interrupt. If nothing else, then to service the watchdog. I point this out as highly interrupted processors have somewhat preempted the necessity of Watchdog timers and tight timing loops.
I have easily implemented a RTC based on a heartbeat interrupt. When you consider, for instance, a Silicon Labs C8051F060 series with nearly 30 interrupt sources, five timer counters and a programmable counter array, you can easily dedicate a timer interrupt source for a heartbeat. The Silabs I/O configurator takes care of the clock calculations. Though you could embed the clock frequency in a header, there really is no need.
I think your over stating the problems. If the compiler is told the clock rate (Xtal speed) and the osc type then it should be able to calculate the true execution rate. If the application chooses to change the execution rate then it can simple re-tell the compiler in the source. At the moment the compiler has no awareness of execution rates at all, or with PICS the fuse ?
As for the interrupt vs non-interrupt I don't think its a major issue, a small delay would be skewed by executing an interrupt service routine during the delay not a big deal - if you need absolute delays then it could be done as a macro or calling the delay function with interrupts disabled.. What about a standard delay lib instead then ? Something like #include <delay.h> with functions delay_us and delay_ms ?? That way I2C and software serial can be built on top without having to tailor each to the target ......
As for "to let the programmer decide what is the best way to implement your delay" isn't that rasing the bar for a minimum program to high. Plently of people have looked at sdcc vs other compilers and run screaming from the room,
I for one fail to see the joy in having to get the processor datasheet out to make an LED flash- with that little help from the compiler you might as well use the assembler !
I have to say that choosing how to implement a delay is a tricky issue on nearly every micro. The optimal solution depends so much on the target application and on the length and accuracy of the required delay that it always ends up as a problem for the coder. C doesn't address the issue at all, so you can't say that SDCC is deficient.
"C doesn't address the issue at all, so you can't say that SDCC is deficient."
Well yes and no ........ its the old hide behind ANSI argument.
The compiler writer says "My compiler meets the lowest common denominator standard, therefor anything missing isn't my problem" - its an argument, just not a good one.
An embedded device compiler should be suited to its target market, embedded devices. If ALL embedded devices rely heavily on I/O and timing then the compiler should be aware and have good functionality for I/O and timing, otherwise its a poor fit and few people will use it .......
SDCC has loads of extensions to support sfrs and multiple memory spaces, so you can't say that it's not appropriate for its target microcontrollers. A library of delay functions might be useful, but I think it will still be up to the coder to choose the implementation that best suits his target.
I guess so, but im still not convinced...........
I have a project that I would i'd like to make fully open source. I don't think sdcc has the functionality ?
PCB and code here, any comments welcome jon AT jonshouse DOT co DOT uk
I have use this macro for setup of Baud on my Pic and this is good macro for Serial baud setting but i hope insert macro same to this for calibrate routine of delay. Now i have find only digital scope with memory for setup my delay routine and check sequence of command on i2bus and Spi interface. And i have find now on bug with for(loop) and instruction genearate on asm see this forum......
// If KHZ is not specified by the makefile, assume it to be 12 MHZ
#define KHZ 12000
#define BAUD 9600
#define BAUD_HI 1
#if (BAUD_HI == 1)
#define BAUD_FACTOR (16L*BAUD)
#define BAUD_FACTOR (64L*BAUD)
#define SPBRG_VALUE (unsigned char)(((KHZ*1000L)-BAUD_FACTOR)/BAUD_FACTOR)