I have a weird problem. I am using WinARM with a Philips LPC2124, and am getting very slow operation, nowhere near the 60MHz PLL-enabled performance I expect. I made a simple program to blink an LED attached to one of the port pins. It blinks the LED three times, then configures the PLL for 60MHz operation (using an external 12MHz crystal), and blinks the LED three more times. If I compile the code in Keil, it blinks at a moderate speed the first three times, then much faster the second three times, as expected. If I then compile the exact same code in WinArm, the LED blinks very slowly the first three times, then faster the second three times, but neither are anywhere near as fast as the Keil-compiled code. This would indicate to me that my PLL setup code is indeed functional, because the second set of blinks is indeed faster than the first set (which should be the default startup speed with no PLL enabled). However, the code running so much slower concerns me. The delay loop is a simple loop as follows, which I call with a value of 200000 in between blinks: void delay(unsigned long value) { volatile unsigned long loop; for ( loop = value ; loop > 0 ; loop--); } I am beginning to suspect that I may be somehow running in thumb mode as opposed to ARM mode. The makefile has the following statements, which I assume should compile in ARM mode: # List C source files here. (C dependencies are automatically generated.) SRC = # List C source files here which must be compiled in ARM-Mode. # use file-extension c for "c-only"-files SRCARM = main.c # List Assembler source files here. ASRC = # List Assembler source files here which must be assembled in ARM-Mode.. ASRCARM = crt0.S Is there anything else that needs to be done to insure ARM-mode compilation? Otherwise, is there anything that needs to be set in the makefile or crt0.S file to set the operating frequency? Any help on this strange problem is greatly appreciated. Thanks, Randall Aiken
Well, I found part of the problem - the Keil compiler initializes the memory accelerator module (MAM) in their automatically-generated startup.s file. I took it out of there and put the initialization in main.c, and now the Keil and WinARM are much closer, but the Keil still looks to be about twice as fast. Any other ideas would be welcomed! Randall Aiken
Randall Aiken wrote: >I took it out of there and put the initialization in > main.c, and now the Keil and WinARM are much closer, but the Keil still > looks to be about twice as fast. I ran across a problem once that made me think I was running much slower than I actually was; for loops. I calculated how long each instruction would take, an executed a for loop to try and estimate my speed. On WinArm, I noticed it was actually about 10 times slower than I had estimated it to be. This may be a function of the GCC compiler, the optimization level I was running at (1) and who knows what else. Its entirely possible that the Keil compiler is optimizing the for loop different than GCC (perhaps a difference between thumb and arm mode), so that although you are actually running at 60 MHz, the Keil codes faster for loop makes it look like you are going fast. Then again, you may have messed up initialization in WinArm :) I suggest you post your start up file where you initialize clock stuff. I've never used any LPC processors, but I'm sure someone else here has and may be able to help you.
Jim Kaz wrote: > I ran across a problem once that made me think I was running much slower > than I actually was; for loops. I calculated how long each instruction > would take, an executed a for loop to try and estimate my speed. On > WinArm, I noticed it was actually about 10 times slower than I had > estimated it to be. This may be a function of the GCC compiler, the > optimization level I was running at (1) and who knows what else. Its > entirely possible that the Keil compiler is optimizing the for loop > different than GCC (perhaps a difference between thumb and arm mode), so > that although you are actually running at 60 MHz, the Keil codes faster > for loop makes it look like you are going fast. > > Then again, you may have messed up initialization in WinArm :) > > I suggest you post your start up file where you initialize clock stuff. > I've never used any LPC processors, but I'm sure someone else here has > and may be able to help you. After a bit more thought late last night, I came to the same conclusion. Today I am going to write a routine that just toggles a pin in an infinite loop. I'll stick the oscilloscope on the pin and measure the frequency. This will take the delay loop and any optimization out of the equation (I think!). If nothing else, it will tell me exactly what the frequency difference is. Thanks! Randall Aiken
Now it gets interesting... I put in the following code: while(1) { IOCLR0 |= P0_STATUS_LED_o; IOSET0 |= P0_STATUS_LED_o; } The Keil compiler executes this at a 1.44MHz toggle rate. The WinArm compiler executes the same routine at a 1.58MHz toggle rate, so it is actually faster than Keil! So, I guess it is indeed a loop optimization problem, although I would have thought the above code would have run at the same speed regardless of the compiler. Thanks! Randall Aiken
Randall Aiken wrote: > Now it gets interesting... > > I put in the following code: > > while(1) > { > IOCLR0 |= P0_STATUS_LED_o; > IOSET0 |= P0_STATUS_LED_o; > } > > > The Keil compiler executes this at a 1.44MHz toggle rate. Try to use RealView, it's the compiler (better toolchain) RV-MDK from Keil uses "behind" the uVision IDE. > The WinArm compiler executes the same routine at a 1.58MHz toggle rate, > so it is actually faster than Keil! There is no WinARM compiler. The WinARM package just includes a precompiled GNU cross-compiler for ARM. Try to use "arm-elf-gcc Version x.x.x" > So, I guess it is indeed a loop optimization problem, although I would > have thought the above code would have run at the same speed regardless > of the compiler. For GNU you can output the assembler-code the compiler generates or create a disassembly from the elf-file (objdump "lss-file"). IRC RealView also creates elf-binaries so you can objdump this too and compare the assembly-code and see which kind of optimization has been done. I think there is also an option in uVision to enable assembler-listings When looking at code for RealView or the IAR EWARM toolchain I sometimes think that both have some kind of "forgotten volatile protection" which might decrease speed since values are updated in RAM too and not only in a core-register. But this is just speculation, the (dis)assembly will show the difference. Martin Thomas
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.