I am new to programming in c and to ARM also, so forgive me silly question. I would like to find answer on the net rather than to bother you, but there is not many materials in the web. I am using Arduino Due board with Atmel SAM3X8E, ARM Cortex M3 and Atmel Studio 6 instead of Arduino IDE.

I wanted to create simple program based on sleep function to blink diode. Sure, there is no point in using sleep function instead of timers. I was just about to check if that work and get familiar with interrupts. But it doesn't work...

Because as I found out here there is no delay functions for ARM, so I created my one. When I put the for loop into main function (In the places I show in comments) everything is okay, diodes blinks alternately. When I use mySleep() they both blink continuously. I've generated similiar program in CodeBlocks on PC with stdio.h and printf instead of asf.h and PIO registers. That works as I wanted. Here is code below:

#include <asf.h>

void mySleep(void);

int main (void)

        PIOB->PIO_SODR = PIO_PB26;
        PIOA->PIO_CODR = PIO_PA14;
        //for(unsigned long long i=0;i<1000000;i++);    
        PIOB->PIO_CODR = PIO_PB26;
        PIOA->PIO_SODR = PIO_PA14;
        //for(unsigned long long i=0;i<1000000;i++);

void mySleep(void)
    for(unsigned long long i=0;i<1000000;i++);

Program is bulit with no error. Here is my question. What is the difference between programming on PC and ARM? What should I do to get user-defined funtion work? Is there any additional library needed?

Thanks in advance.

  • 1
    \$\begingroup\$ If everything is working as expected, what is the actual question? The questions you asked are far too broad to answer here. \$\endgroup\$ – Dave Tweed Mar 30 '16 at 11:23

The difference isn't in the platfrom.

The difference is that CodeBlocks probably compiles to no optimisation at Debug setting, whereas many, if not most, embedded compilers - as configured out of the box - optimise away function calls that have no macroscopic effect.

If you go to debug mode you will see you can't put any breakpoints inside mySleep(). This is because the compiler decided to not include it in the limited code space of your processor, since inside it nothing happens.

That said, Atmel has Delay(), Delay_ms() and Delay_us() that use an ASM VOLATILE nop loop to get very close to guaranteed delays if the CPU speed is set correctly.

You can also include inline ASM code (google it if you want) as VOLATILE inside your loop, having it execute a single NOP instruction (NOP = No Operation = Do nothing). For ARM GCC, an online cookbook quotes:

asm volatile("mov r0, r0");

Volatile means "do not touch!" or otherwise "Do not optimise it away for me!".

I'm too lazy to check, but I believe ARM also has the NOP instruction.

You can also probably change the settings for optimisation, but that means your code will become huge very quickly if you're just starting out.

  • \$\begingroup\$ Thank you for your time! Yes, the difference was in compiler settings, I've unchecked optimisation and now it works, as I expected. Atmel has delay functions, but they are made only for AVR. That's my research said, but I could failed. Yes, ARM has NOP instruction, I will get back to it soon. I have to cope with more basic stuff first. Thank for information about that. \$\endgroup\$ – Seedorfan Mar 30 '16 at 12:25

You never say what your error actually is, but I suspect that because your function does nothing in main, it is being optimized out by your compiler. Try compiling with optimization turned off

  • \$\begingroup\$ That's it. Unchecking optimization solved my problem. Thank you \$\endgroup\$ – Seedorfan Mar 30 '16 at 11:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.