0

I'm developing simple blink led for PI without OS (bare metal)

when setting the variable tim inside the kernel_main, the led still on and doesn't blink. but when setting variable tim global (outside kernel_main) the program run and the led blink

I think in the first case the variable is in the stack and second case in .bss, but why cant blink when this variable is in the stack ???

tim local:

void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags) {
    gpio[GPIO_GPFSEL1] |= (1 << 18);
    uint32_t tim;
   while(1)
    {
        for(tim = 0; tim < 500000; tim++) ;
        gpio[GPIO_GPCLR0] = (1 << 16);
        for(tim = 0; tim < 500000; tim++);
        gpio[GPIO_GPSET0] = (1 << 16);
    }
}

tim global:

uint32_t tim;
void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags) {
    gpio[GPIO_GPFSEL1] |= (1 << 18);
           while(1)
    {
        for(tim = 0; tim < 500000; tim++) ;
        gpio[GPIO_GPCLR0] = (1 << 16);
        for(tim = 0; tim < 500000; tim++);
        gpio[GPIO_GPSET0] = (1 << 16);
    }
}
1

If you are using gcc, try using the -O0 option to disable optimisation. It's possible that the compiler decides that the tim variable isn't really needed when it's declared locally, so it produces executable code that skips the loops.

When tim is declared globaly, the compiler uses different optimization rules, so the loop is included in the executable file.

6
  • i'm using cross compile, I tried with -O0 option, and it still not working with tim local. and I dont think that the compiler will make this really wrong optimisation !!!! – mikmik Jun 21 '14 at 18:31
  • 2
    Removing a loop like this is pretty basic optimization. I've had exactly the same problem when trying to create delay loops. When tim is local, it's easy for the compiler to see that the loop has no side effects. When tim is global, the compiler can't determine whether the loop has no side effects. Consult your compiler documentation to see if there is a specific option for disabling this optimization. You'd be amazed at how much compilers can mess with your code. – Steve Jun 22 '14 at 17:07
  • I disabled the optimization with -O0 option, but still not working, so I think no optimization is made??? – mikmik Jun 22 '14 at 17:17
  • 1
    Sometimes the -O0 option just turns off most optimizations, but not necessarily all of them. This varies between compilers, even between different implementations of gcc. Try using the volatile modifier when you declare tim locally. – Steve Jun 22 '14 at 19:37
  • even with tim volatile still not working, I think when variable is volatile the compiler will not make any optimization, that's weird !!!!!!! – mikmik Jun 22 '14 at 21:04
0

You need to initialize the stack before you can start using local variables. I boot my code to an assembly file first before my c code. In the assembly code, I initialize the stack pointer and then call main. I based my code off of the example here

Assembly file:

.section INTERRUPT_VECTOR, "x"
.global _Reset
_Reset:
  B Reset_Handler /* Reset */
  B . /* Undefined */
  B . /* SWI */
  B . /* Prefetch Abort */
  B . /* Data Abort */
  B . /* reserved */
  B . /* IRQ */
  B . /* FIQ */
Reset_Handler:
  LDR sp, =stack_top
  BL main
  B .

Linker file:

ENTRY(_Reset)

SECTIONS
{
 . = 0x8000;
 .text : {
 init.o (INTERRUPT_VECTOR)
 *(.text)
 }
 .data : { *(.data) }
 .bss : { *(.bss COMMON) }
 . = ALIGN(8);
 . = . + 0x1000; /* 4kB of stack memory */
 stack_top = .;
}
-1

Your delay loops are getting optimized away because they have no side effects.

You should use instead:

msleep(unsigned long msecs)
msleep_interruptible(unsigned long msecs)

Actually, the second one is preferred, especially if your delays are quite long, as I suspect.

And don't forget to use the appropriate include file:

#include <linux/delay.h>
3
  • 1
    the program work, and my question is why when tim variable is local it doesn't work, and also #include <linux/delay.h> doesnt exist because the program is running without OS (bare metal) – mikmik Jun 21 '14 at 21:52
  • no I see what u mean, the loop is optimized because it have no side affect, but do you think that even with -O0 option the optimization is done??? – mikmik Jun 22 '14 at 17:19
  • You need to implement your own sleep-function, then. – Bex Jul 19 '14 at 16:40

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.