mbed Clock Control / Benchmarks
I wrote a few small functions to control the clock and PLL frequency, and I made a few discoveries along the way.
Update (1/26): Note that these tests are with the PHY on and an Ethernet cable plugged in. See http://mbed.org/users/no2chem/notebook/mbed-power-controlconsumption/ for more information on power draw by the PHY. Essentially, you can subtract about 76mA from the current readings.
I ported CoreMark (http://www.coremark.org) to the mbed LPC1768 and ran some tests. You can see the demonstration program here:
The demo app isn't certified as I made a wrapper to call CoreMark's main() from my main(). The tests below are run from a "certified" version of CoreMark, however. The code to read the clock speed comes verbatim from Simon Ford's post: http://mbed.org/forum/mbed/topic/229/?page=1#comment-1225
As with the previous power control tests, I ran the mbed on an Agilent E3615A power supply at 5.0V (NB: Last calibration 2002). I realized this time, however, that the current reading from my DMM is more precise than the power supply (mA range), so current readings are off a Protek 6300 DMM (NB: NOT calibrated). The mbed was disconnected from USB during the power reading and the power supply was connected to VIN on the mbed. The reading was taken while the mbed was waiting for input via scanf (more precisely, the Run CoreMark (Y/N)? line.)
Table 1. Performance and current draw at different frequencies. ERROR means that no performance reading could be made. M and N are multipliers and dividers for the PLL multiplier and divider, respectively.
Figure 1. Frequency vs CoreMark. A slope of 1.5849 CoreMarks per MHz was obtained. The data is completely linear.
Figure 2. Frequency vs Current. A slope of 0.4118 mA per MHz was obtained. The data is almost completely linear.
It appears the LPC1768 part is quite capable of performing at the ~120 MHz range, so perhaps overclocking might be a better option than using the LPC1769 "120MHz" operation part. Then again, perhaps I got lucky with my LPC1768, or NXP might be selling the higher quality chips as 1769s. Operation above 128MHz caused sporadic errors, although I was able to get serial output, the timer function was severely broken.
Lowering the frequency to 48MHz will be beneficial to low power operation at a 11.39% power savings, and USB should be able to work directly off a 48MHz clock on PLL0. I didn't test any peripherals, so I can't attest to their operation, other than proper emission of serial output.
Overcloking to 128MHz resulted in a 33.35% performance increase, at a cost of 7.34% power. This might be beneficial for demanding operations, or intense bit-banging. Given the problems with operation at 132 and 133 MHz, stability will have to monitored.
I experienced problems with serial output after changing clock frequencies. I resolved that issue by calling the constructor of the serial function again after frequency change - Serial pc(USBTX, USBRX);. This probably reinitializes the UART to the new clock frequency. Other peripherals will probably have to be reinitialized too, so clock frequency changes are best done at startup.
The other issue was with the clock() function, which seemed to have major skew issues after clock frequency changes. I don't think there's a way to reset this function besides a hard reset, which you can call via NVIC_SystemReset(). Fortunately, the clock function doesn't start ticking until the first time you call it, so just call it AFTER you're done with all the frequency changes.
It's not really a "library" a clock change function essentially taken out of CMSIS's init routine, and a wrapper for change the clock of the MCU. For M and N values, see table above as well as NXP's datasheet.
unsigned int setSystemFrequency(unsigned char clkDivider, unsigned char clkSrc, unsigned short M, unsigned char N);
Sets the system clock frequency with the target parameters. Also updates SystemCoreClock value. Returns the current clock speed. (NB: don't printf the clockspeed without reinit of the serial - store the result in a variable, reinit the serial, then print the clock speed).
void setPLL0Frequency(unsigned char clkSrc, unsigned short M, unsigned char N);
Set the frequency of PLL0 with the target parameters.
void setPLL1Frequency(unsigned char clkSrc, unsigned short M, unsigned char N);
Set the frequency of PLL1 with the target parameters.
Please log in to post a comment.