Bare metal C Function not working

2

I have been writing a kernel for the Raspberry Pi 2 using C. To do so I have been following the Valvers and Baking Pi (written in Assembly) tutorials to do so. But each time I try to port the function to set a pin to output from the Baking Pi OK03 tutorial to C the led stops blinking (but the code compiles just fine). I have rewritten the function several times but I cannot get it to work. Here is my code:

main.c:

#include "gpio.h"

int main(void) __attribute__((naked));
int main(void)
{
    gpio = (unsigned int*)GPIO_BASE;

    /* Write 1 to the GPIO16 init nibble in the Function Select 1 GPIO
       peripheral register to enable GPIO16 as an output */
    // gpio[LED_GPFSEL] |= (1 << LED_GPFBIT);
    pinMode(47, 1);

    // Never return from here
    while(1)
    {
        for(tim = 0; tim < 500000; tim++)
            ;

        /* Set the LED GPIO pin low ( Turn OK LED on for original Pi, and off
           for plus models )*/
        gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);

        for(tim = 0; tim < 500000; tim++)
            ;

        /* Set the LED GPIO pin high ( Turn OK LED off for original Pi, and on
           for plus models )*/
        gpio[LED_GPSET] = (1 << LED_GPIO_BIT);
    }
}

gpio.h:

#ifndef GPIO_H
#define GPIO_H

#ifdef RPI2
    #define GPIO_BASE       0x3F200000UL
#else
    #define GPIO_BASE       0x20200000UL
#endif

#if defined( RPIBPLUS ) || defined( RPI2 )
    #define LED_GPFSEL      GPIO_GPFSEL4
    #define LED_GPFBIT      21
    #define LED_GPSET       GPIO_GPSET1
    #define LED_GPCLR       GPIO_GPCLR1
    #define LED_GPIO_BIT    15
#else
    #define LED_GPFSEL      GPIO_GPFSEL1
    #define LED_GPFBIT      18
    #define LED_GPSET       GPIO_GPSET0
    #define LED_GPCLR       GPIO_GPCLR0
    #define LED_GPIO_BIT    16
#endif

#define GPIO_GPFSEL0    0
#define GPIO_GPFSEL1    1
#define GPIO_GPFSEL2    2
#define GPIO_GPFSEL3    3
#define GPIO_GPFSEL4    4
#define GPIO_GPFSEL5    5

#define GPIO_GPSET0     7
#define GPIO_GPSET1     8

#define GPIO_GPCLR0     10
#define GPIO_GPCLR1     11

#define GPIO_GPLEV0     13
#define GPIO_GPLEV1     14

#define GPIO_GPEDS0     16
#define GPIO_GPEDS1     17

#define GPIO_GPREN0     19
#define GPIO_GPREN1     20

#define GPIO_GPFEN0     22
#define GPIO_GPFEN1     23

#define GPIO_GPHEN0     25
#define GPIO_GPHEN1     26

#define GPIO_GPLEN0     28
#define GPIO_GPLEN1     29

#define GPIO_GPAREN0    31
#define GPIO_GPAREN1    32

#define GPIO_GPAFEN0    34
#define GPIO_GPAFEN1    35

#define GPIO_GPPUD      37
#define GPIO_GPPUDCLK0  38
#define GPIO_GPPUDCLK1  39

/** GPIO Register set */
volatile unsigned int* gpio;

/** Simple loop variable */
volatile unsigned int tim;

// Function to change a pin's mode
int pinMode(int pinnum, int mode);

#endif

gpio.c:

#include "gpio.h"
/* Docs: The Pi has 54 GPIO pins and 6 Function Selec Registers (FSR). Each FSR
controls 10 GPIO pins and each FSR is made of 33 bits (each pin is controlled by
3 bits of the FSR). To know which pins of the FSR control each GPIO pin the formula
3n is used (where n is the pin number). In order for this to work, the pin number must be minor or equal to 9. Therefore if the pin is higher than 9, 10 units are subtracted from the pin number and one unit is added to the fsr variable. This loops until the pin number is lower or equal to 9. */


int pinMode(int pinnum, int mode) {
    // Variable declaration and initialization
    int fsr = 0;
    int fsrbit;
    // Let's check the pin does exist
    if (pinnum < 0 || pinnum > 53) {
        // Abort, there is no such pin.
        return 1;
    }
    else if (mode < 0 || mode > 1) {
        // Abort, invalid mode (Actually there are 7 modes but we will only use 2)
        return 1;
    }
    // Create a pointer to the GPIO perhiperal register so we can speak to it
    gpio = (unsigned int*)GPIO_BASE;
    // And calculate wich FSR we should use
    /* do {
        if (pinnum > 9) {
            pinnum -= 10;
            fsr++;
        }
    } while (pinnum > 9); */
    if (pinnum > 9) {
        while (pinnum > 9) {
            pinnum -= 10;
            fsr++;
        }
    }
        // Then we calculate the bytes of the fsreg to use
        fsrbit = pinnum * 3;
        // Finally let's set the pin to the desired mode
        gpio[fsr] |= (mode << fsrbit);

        return 0;
}

Please help, I have been stuck with this problem for weeks.

PS: In case you want the kernel disassembly:

kernel_disassembly.asm:

./kernel.elf:     file format elf32-littlearm


Disassembly of section .text:

00008000 <main>:
    8000:   e3082200    movw    r2, #33280  ; 0x8200
    8004:   e3402001    movt    r2, #1
    8008:   e3a03000    mov r3, #0
    800c:   e3433f20    movt    r3, #16160  ; 0x3f20
    8010:   e5823000    str r3, [r2]
    8014:   e3a01001    mov r1, #1
    8018:   e3a0002f    mov r0, #47 ; 0x2f
    801c:   eb000032    bl  80ec <pinMode>
    8020:   e30831fc    movw    r3, #33276  ; 0x81fc
    8024:   e3403001    movt    r3, #1
    8028:   e3a02000    mov r2, #0
    802c:   e5832000    str r2, [r3]
    8030:   ea000006    b   8050 <main+0x50>
    8034:   e30831fc    movw    r3, #33276  ; 0x81fc
    8038:   e3403001    movt    r3, #1
    803c:   e5933000    ldr r3, [r3]
    8040:   e2832001    add r2, r3, #1
    8044:   e30831fc    movw    r3, #33276  ; 0x81fc
    8048:   e3403001    movt    r3, #1
    804c:   e5832000    str r2, [r3]
    8050:   e30831fc    movw    r3, #33276  ; 0x81fc
    8054:   e3403001    movt    r3, #1
    8058:   e5932000    ldr r2, [r3]
    805c:   e30a311f    movw    r3, #41247  ; 0xa11f
    8060:   e3403007    movt    r3, #7
    8064:   e1520003    cmp r2, r3
    8068:   9afffff1    bls 8034 <main+0x34>
    806c:   e3083200    movw    r3, #33280  ; 0x8200
    8070:   e3403001    movt    r3, #1
    8074:   e5933000    ldr r3, [r3]
    8078:   e283302c    add r3, r3, #44 ; 0x2c
    807c:   e3a02902    mov r2, #32768  ; 0x8000
    8080:   e5832000    str r2, [r3]
    8084:   e30831fc    movw    r3, #33276  ; 0x81fc
    8088:   e3403001    movt    r3, #1
    808c:   e3a02000    mov r2, #0
    8090:   e5832000    str r2, [r3]
    8094:   ea000006    b   80b4 <main+0xb4>
    8098:   e30831fc    movw    r3, #33276  ; 0x81fc
    809c:   e3403001    movt    r3, #1
    80a0:   e5933000    ldr r3, [r3]
    80a4:   e2832001    add r2, r3, #1
    80a8:   e30831fc    movw    r3, #33276  ; 0x81fc
    80ac:   e3403001    movt    r3, #1
    80b0:   e5832000    str r2, [r3]
    80b4:   e30831fc    movw    r3, #33276  ; 0x81fc
    80b8:   e3403001    movt    r3, #1
    80bc:   e5932000    ldr r2, [r3]
    80c0:   e30a311f    movw    r3, #41247  ; 0xa11f
    80c4:   e3403007    movt    r3, #7
    80c8:   e1520003    cmp r2, r3
    80cc:   9afffff1    bls 8098 <main+0x98>
    80d0:   e3083200    movw    r3, #33280  ; 0x8200
    80d4:   e3403001    movt    r3, #1
    80d8:   e5933000    ldr r3, [r3]
    80dc:   e2833020    add r3, r3, #32
    80e0:   e3a02902    mov r2, #32768  ; 0x8000
    80e4:   e5832000    str r2, [r3]
    80e8:   eaffffcc    b   8020 <main+0x20>

000080ec <pinMode>:
    80ec:   e52db004    push    {fp}        ; (str fp, [sp, #-4]!)
    80f0:   e28db000    add fp, sp, #0
    80f4:   e24dd014    sub sp, sp, #20
    80f8:   e50b0010    str r0, [fp, #-16]
    80fc:   e50b1014    str r1, [fp, #-20]  ; 0xffffffec
    8100:   e3a03000    mov r3, #0
    8104:   e50b3008    str r3, [fp, #-8]
    8108:   e51b3010    ldr r3, [fp, #-16]
    810c:   e3530000    cmp r3, #0
    8110:   ba000002    blt 8120 <pinMode+0x34>
    8114:   e51b3010    ldr r3, [fp, #-16]
    8118:   e3530035    cmp r3, #53 ; 0x35
    811c:   da000001    ble 8128 <pinMode+0x3c>
    8120:   e3a03001    mov r3, #1
    8124:   ea000030    b   81ec <pinMode+0x100>
    8128:   e51b3014    ldr r3, [fp, #-20]  ; 0xffffffec
    812c:   e3530000    cmp r3, #0
    8130:   ba000002    blt 8140 <pinMode+0x54>
    8134:   e51b3014    ldr r3, [fp, #-20]  ; 0xffffffec
    8138:   e3530001    cmp r3, #1
    813c:   da000001    ble 8148 <pinMode+0x5c>
    8140:   e3a03001    mov r3, #1
    8144:   ea000028    b   81ec <pinMode+0x100>
    8148:   e3082200    movw    r2, #33280  ; 0x8200
    814c:   e3402001    movt    r2, #1
    8150:   e3a03000    mov r3, #0
    8154:   e3433f20    movt    r3, #16160  ; 0x3f20
    8158:   e5823000    str r3, [r2]
    815c:   e51b3010    ldr r3, [fp, #-16]
    8160:   e3530009    cmp r3, #9
    8164:   da000009    ble 8190 <pinMode+0xa4>
    8168:   ea000005    b   8184 <pinMode+0x98>
    816c:   e51b3010    ldr r3, [fp, #-16]
    8170:   e243300a    sub r3, r3, #10
    8174:   e50b3010    str r3, [fp, #-16]
    8178:   e51b3008    ldr r3, [fp, #-8]
    817c:   e2833001    add r3, r3, #1
    8180:   e50b3008    str r3, [fp, #-8]
    8184:   e51b3010    ldr r3, [fp, #-16]
    8188:   e3530009    cmp r3, #9
    818c:   cafffff6    bgt 816c <pinMode+0x80>
    8190:   e51b3010    ldr r3, [fp, #-16]
    8194:   e3a02003    mov r2, #3
    8198:   e0030392    mul r3, r2, r3
    819c:   e50b300c    str r3, [fp, #-12]
    81a0:   e3083200    movw    r3, #33280  ; 0x8200
    81a4:   e3403001    movt    r3, #1
    81a8:   e5932000    ldr r2, [r3]
    81ac:   e51b3008    ldr r3, [fp, #-8]
    81b0:   e1a03103    lsl r3, r3, #2
    81b4:   e0822003    add r2, r2, r3
    81b8:   e3083200    movw    r3, #33280  ; 0x8200
    81bc:   e3403001    movt    r3, #1
    81c0:   e5931000    ldr r1, [r3]
    81c4:   e51b3008    ldr r3, [fp, #-8]
    81c8:   e1a03103    lsl r3, r3, #2
    81cc:   e0813003    add r3, r1, r3
    81d0:   e5933000    ldr r3, [r3]
    81d4:   e51b0014    ldr r0, [fp, #-20]  ; 0xffffffec
    81d8:   e51b100c    ldr r1, [fp, #-12]
    81dc:   e1a01110    lsl r1, r0, r1
    81e0:   e1833001    orr r3, r3, r1
    81e4:   e5823000    str r3, [r2]
    81e8:   e3a03000    mov r3, #0
    81ec:   e1a00003    mov r0, r3
    81f0:   e24bd000    sub sp, fp, #0
    81f4:   e49db004    pop {fp}        ; (ldr fp, [sp], #4)
    81f8:   e12fff1e    bx  lr

Disassembly of section .bss:

000181fc <__bss_start>:
   181fc:   00000000    andeq   r0, r0, r0

00018200 <gpio>:
   18200:   00000000    andeq   r0, r0, r0

Disassembly of section .comment:

00000000 <.comment>:
   0:   3a434347    bcc 10d0d24 <_stack+0x1050d24>
   4:   4e472820    cdpmi   8, 4, cr2, cr7, cr0, {1}
   8:   6f542055    svcvs   0x00542055
   c:   20736c6f    rsbscs  r6, r3, pc, ror #24
  10:   20726f66    rsbscs  r6, r2, r6, ror #30
  14:   204d5241    subcs   r5, sp, r1, asr #4
  18:   65626d45    strbvs  r6, [r2, #-3397]!   ; 0xfffff2bb
  1c:   64656464    strbtvs r6, [r5], #-1124    ; 0xfffffb9c
  20:   6f725020    svcvs   0x00725020
  24:   73736563    cmnvc   r3, #415236096  ; 0x18c00000
  28:   2973726f    ldmdbcs r3!, {r0, r1, r2, r3, r5, r6, r9, ip, sp, lr}^
  2c:   342e3520    strtcc  r3, [lr], #-1312    ; 0xfffffae0
  30:   3220312e    eorcc   r3, r0, #-2147483637    ; 0x8000000b
  34:   30363130    eorscc  r3, r6, r0, lsr r1
  38:   20393139    eorscs  r3, r9, r9, lsr r1
  3c:   6c657228    sfmvs   f7, 2, [r5], #-160  ; 0xffffff60
  40:   65736165    ldrbvs  r6, [r3, #-357]!    ; 0xfffffe9b
  44:   415b2029    cmpmi   fp, r9, lsr #32
  48:   652f4d52    strvs   r4, [pc, #-3410]!   ; fffff2fe <_stack+0xfff7f2fe>
  4c:   6465626d    strbtvs r6, [r5], #-621 ; 0xfffffd93
  50:   2d646564    cfstr64cs   mvdx6, [r4, #-400]! ; 0xfffffe70
  54:   72622d35    rsbvc   r2, r2, #3392   ; 0xd40
  58:   68636e61    stmdavs r3!, {r0, r5, r6, r9, sl, fp, sp, lr}^
  5c:   76657220    strbtvc r7, [r5], -r0, lsr #4
  60:   6f697369    svcvs   0x00697369
  64:   3432206e    ldrtcc  r2, [r2], #-110 ; 0xffffff92
  68:   36393430            ; <UNDEFINED> instruction: 0x36393430
  6c:   Address 0x000000000000006c is out of bounds.


Disassembly of section .debug_aranges:

00000000 <.debug_aranges>:
   0:   0000001c    andeq   r0, r0, ip, lsl r0
   4:   00000002    andeq   r0, r0, r2
   8:   00040000    andeq   r0, r4, r0
   c:   00000000    andeq   r0, r0, r0
  10:   00008000    andeq   r8, r0, r0
  14:   000000ec    andeq   r0, r0, ip, ror #1
    ...
  20:   0000001c    andeq   r0, r0, ip, lsl r0
  24:   00760002    rsbseq  r0, r6, r2
  28:   00040000    andeq   r0, r4, r0
  2c:   00000000    andeq   r0, r0, r0
  30:   000080ec    andeq   r8, r0, ip, ror #1
  34:   00000110    andeq   r0, r0, r0, lsl r1
    ...

Disassembly of section .debug_info:

00000000 <.debug_info>:
   0:   00000072    andeq   r0, r0, r2, ror r0
   4:   00000004    andeq   r0, r0, r4
   8:   01040000    mrseq   r0, (UNDEF: 4)
   c:   0000003f    andeq   r0, r0, pc, lsr r0
  10:   0000340c    andeq   r3, r0, ip, lsl #8
  14:   00000d00    andeq   r0, r0, r0, lsl #26
  18:   00800000    addeq   r0, r0, r0
  1c:   0000ec00    andeq   lr, r0, r0, lsl #24
  20:   00000000    andeq   r0, r0, r0
  24:   00d10200    sbcseq  r0, r1, r0, lsl #4
  28:   04010000    streq   r0, [r1], #-0
  2c:   0000003a    andeq   r0, r0, sl, lsr r0
  30:   00008000    andeq   r8, r0, r0
  34:   000000ec    andeq   r0, r0, ip, ror #1
  38:   04039c01    streq   r9, [r3], #-3073    ; 0xfffff3ff
  3c:   746e6905    strbtvc r6, [lr], #-2309    ; 0xfffff6fb
  40:   002f0400    eoreq   r0, pc, r0, lsl #8
  44:   42020000    andmi   r0, r2, #0
  48:   00000052    andeq   r0, r0, r2, asr r0
  4c:   82000305    andhi   r0, r0, #335544320  ; 0x14000000
  50:   04050001    streq   r0, [r5], #-1
  54:   0000005f    andeq   r0, r0, pc, asr r0
  58:   00070406    andeq   r0, r7, r6, lsl #8
  5c:   07000000    streq   r0, [r0, -r0]
  60:   00000058    andeq   r0, r0, r8, asr r0
  64:   6d697408    cfstrdvs    mvd7, [r9, #-32]!   ; 0xffffffe0
  68:   5f450200    svcpl   0x00450200
  6c:   05000000    streq   r0, [r0, #-0]
  70:   0181fc03    orreq   pc, r1, r3, lsl #24
  74:   00af0000    adceq   r0, pc, r0
  78:   00040000    andeq   r0, r4, r0
  7c:   00000076    andeq   r0, r0, r6, ror r0
  80:   003f0104    eorseq  r0, pc, r4, lsl #2
  84:   dd0c0000    stcle   0, cr0, [ip, #-0]
  88:   0d000000    stceq   0, cr0, [r0, #-0]
  8c:   ec000000    stc 0, cr0, [r0], {-0}
  90:   10000080    andne   r0, r0, r0, lsl #1
  94:   61000001    tstvs   r0, r1
  98:   02000000    andeq   r0, r0, #0
  9c:   000000ef    andeq   r0, r0, pc, ror #1
  a0:   00770b01    rsbseq  r0, r7, r1, lsl #22
  a4:   80ec0000    rschi   r0, ip, r0
  a8:   01100000    tsteq   r0, r0
  ac:   9c010000    stcls   0, cr0, [r1], {-0}
  b0:   00000077    andeq   r0, r0, r7, ror r0
  b4:   0000d603    andeq   sp, r0, r3, lsl #12
  b8:   770b0100    strvc   r0, [fp, -r0, lsl #2]
  bc:   02000000    andeq   r0, r0, #0
  c0:   f7036c91            ; <UNDEFINED> instruction: 0xf7036c91
  c4:   01000000    mrseq   r0, (UNDEF: 0)
  c8:   0000770b    andeq   r7, r0, fp, lsl #14
  cc:   68910200    ldmvs   r1, {r9}
  d0:   72736604    rsbsvc  r6, r3, #4, 12  ; 0x400000
  d4:   770d0100    strvc   r0, [sp, -r0, lsl #2]
  d8:   02000000    andeq   r0, r0, #0
  dc:   e8057491    stmda   r5, {r0, r4, r7, sl, ip, sp, lr}
  e0:   01000000    mrseq   r0, (UNDEF: 0)
  e4:   0000770e    andeq   r7, r0, lr, lsl #14
  e8:   70910200    addsvc  r0, r1, r0, lsl #4
  ec:   05040600    streq   r0, [r4, #-1536]    ; 0xfffffa00
  f0:   00746e69    rsbseq  r6, r4, r9, ror #28
  f4:   00002f07    andeq   r2, r0, r7, lsl #30
  f8:   8f420200    svchi   0x00420200
  fc:   05000000    streq   r0, [r0, #-0]
 100:   01820003    orreq   r0, r2, r3
 104:   9c040800    stcls   8, cr0, [r4], {-0}
 108:   09000000    stmdbeq r0, {}  ; <UNPREDICTABLE>
 10c:   00000704    andeq   r0, r0, r4, lsl #14
 110:   950a0000    strls   r0, [sl, #-0]
 114:   0b000000    bleq    11c <main-0x7ee4>
 118:   006d6974    rsbeq   r6, sp, r4, ror r9
 11c:   009c4502    addseq  r4, ip, r2, lsl #10
 120:   03050000    movweq  r0, #20480  ; 0x5000
 124:   000181fc    strdeq  r8, [r1], -ip
    ...

Disassembly of section .debug_abbrev:

00000000 <.debug_abbrev>:
   0:   25011101    strcs   r1, [r1, #-257] ; 0xfffffeff
   4:   030b130e    movweq  r1, #45838  ; 0xb30e
   8:   110e1b0e    tstne   lr, lr, lsl #22
   c:   10061201    andne   r1, r6, r1, lsl #4
  10:   02000017    andeq   r0, r0, #23
  14:   193f002e    ldmdbne pc!, {r1, r2, r3, r5}   ; <UNPREDICTABLE>
  18:   0b3a0e03    bleq    e8382c <_stack+0xe0382c>
  1c:   19270b3b    stmdbne r7!, {r0, r1, r3, r4, r5, r8, r9, fp}
  20:   01111349    tsteq   r1, r9, asr #6
  24:   18400612    stmdane r0, {r1, r4, r9, sl}^
  28:   00194296    mulseq  r9, r6, r2
  2c:   00240300    eoreq   r0, r4, r0, lsl #6
  30:   0b3e0b0b    bleq    f82c64 <_stack+0xf02c64>
  34:   00000803    andeq   r0, r0, r3, lsl #16
  38:   03003404    movweq  r3, #1028   ; 0x404
  3c:   3b0b3a0e    blcc    2ce87c <_stack+0x24e87c>
  40:   3f13490b    svccc   0x0013490b
  44:   00180219    andseq  r0, r8, r9, lsl r2
  48:   000f0500    andeq   r0, pc, r0, lsl #10
  4c:   13490b0b    movtne  r0, #39691  ; 0x9b0b
  50:   24060000    strcs   r0, [r6], #-0
  54:   3e0b0b00    vmlacc.f64  d0, d11, d0
  58:   000e030b    andeq   r0, lr, fp, lsl #6
  5c:   00350700    eorseq  r0, r5, r0, lsl #14
  60:   00001349    andeq   r1, r0, r9, asr #6
  64:   03003408    movweq  r3, #1032   ; 0x408
  68:   3b0b3a08    blcc    2ce890 <_stack+0x24e890>
  6c:   3f13490b    svccc   0x0013490b
  70:   00180219    andseq  r0, r8, r9, lsl r2
  74:   11010000    mrsne   r0, (UNDEF: 1)
  78:   130e2501    movwne  r2, #58625  ; 0xe501
  7c:   1b0e030b    blne    380cb0 <_stack+0x300cb0>
  80:   1201110e    andne   r1, r1, #-2147483645    ; 0x80000003
  84:   00171006    andseq  r1, r7, r6
  88:   012e0200            ; <UNDEFINED> instruction: 0x012e0200
  8c:   0e03193f    mcreq   9, 0, r1, cr3, cr15, {1}
  90:   0b3b0b3a    bleq    ec2d80 <_stack+0xe42d80>
  94:   13491927    movtne  r1, #39207  ; 0x9927
  98:   06120111            ; <UNDEFINED> instruction: 0x06120111
  9c:   42971840    addsmi  r1, r7, #64, 16 ; 0x400000
  a0:   00130119    andseq  r0, r3, r9, lsl r1
  a4:   00050300    andeq   r0, r5, r0, lsl #6
  a8:   0b3a0e03    bleq    e838bc <_stack+0xe038bc>
  ac:   13490b3b    movtne  r0, #39739  ; 0x9b3b
  b0:   00001802    andeq   r1, r0, r2, lsl #16
  b4:   03003404    movweq  r3, #1028   ; 0x404
  b8:   3b0b3a08    blcc    2ce8e0 <_stack+0x24e8e0>
  bc:   0213490b    andseq  r4, r3, #180224 ; 0x2c000
  c0:   05000018    streq   r0, [r0, #-24]  ; 0xffffffe8
  c4:   0e030034    mcreq   0, 0, r0, cr3, cr4, {1}
  c8:   0b3b0b3a    bleq    ec2db8 <_stack+0xe42db8>
  cc:   18021349    stmdane r2, {r0, r3, r6, r8, r9, ip}
  d0:   24060000    strcs   r0, [r6], #-0
  d4:   3e0b0b00    vmlacc.f64  d0, d11, d0
  d8:   0008030b    andeq   r0, r8, fp, lsl #6
  dc:   00340700    eorseq  r0, r4, r0, lsl #14
  e0:   0b3a0e03    bleq    e838f4 <_stack+0xe038f4>
  e4:   13490b3b    movtne  r0, #39739  ; 0x9b3b
  e8:   1802193f    stmdane r2, {r0, r1, r2, r3, r4, r5, r8, fp, ip}
  ec:   0f080000    svceq   0x00080000
  f0:   490b0b00    stmdbmi fp, {r8, r9, fp}
  f4:   09000013    stmdbeq r0, {r0, r1, r4}
  f8:   0b0b0024    bleq    2c0190 <_stack+0x240190>
  fc:   0e030b3e    vmoveq.16   d3[0], r0
 100:   350a0000    strcc   r0, [sl, #-0]
 104:   00134900    andseq  r4, r3, r0, lsl #18
 108:   00340b00    eorseq  r0, r4, r0, lsl #22
 10c:   0b3a0803    bleq    e82120 <_stack+0xe02120>
 110:   13490b3b    movtne  r0, #39739  ; 0x9b3b
 114:   1802193f    stmdane r2, {r0, r1, r2, r3, r4, r5, r8, fp, ip}
 118:   Address 0x0000000000000118 is out of bounds.


Disassembly of section .debug_line:

00000000 <.debug_line>:
   0:   0000005d    andeq   r0, r0, sp, asr r0
   4:   002b0002    eoreq   r0, fp, r2
   8:   01020000    mrseq   r0, (UNDEF: 2)
   c:   000d0efb    strdeq  r0, [sp], -fp
  10:   01010101    tsteq   r1, r1, lsl #2
  14:   01000000    mrseq   r0, (UNDEF: 0)
  18:   73010000    movwvc  r0, #4096   ; 0x1000
  1c:   00006372    andeq   r6, r0, r2, ror r3
  20:   6e69616d    powvsez f6, f1, #5.0
  24:   0100632e    tsteq   r0, lr, lsr #6
  28:   70670000    rsbvc   r0, r7, r0
  2c:   682e6f69    stmdavs lr!, {r0, r3, r5, r6, r8, r9, sl, fp, sp, lr}
  30:   00000100    andeq   r0, r0, r0, lsl #2
  34:   02050000    andeq   r0, r5, #0
  38:   00008000    andeq   r8, r0, r0
  3c:   6ba31316    blvs    fe8c4c9c <_stack+0xfe844c9c>
  40:   03040200    movweq  r0, #16896  ; 0x4200
  44:   02009e06    andeq   r9, r0, #6, 28  ; 0x60
  48:   06d60104    ldrbeq  r0, [r6], r4, lsl #2
  4c:   0200bcdb    andeq   fp, r0, #56064  ; 0xdb00
  50:   9e060304    cdpls   3, 0, cr0, cr6, cr4, {0}
  54:   01040200    mrseq   r0, R12_usr
  58:   bbdb06d6    bllt    ff6c1bb8 <_stack+0xff641bb8>
  5c:   01000202    tsteq   r0, r2, lsl #4
  60:   00005f01    andeq   r5, r0, r1, lsl #30
  64:   2b000200    blcs    86c <main-0x7794>
  68:   02000000    andeq   r0, r0, #0
  6c:   0d0efb01    vstreq  d15, [lr, #-4]
  70:   01010100    mrseq   r0, (UNDEF: 17)
  74:   00000001    andeq   r0, r0, r1
  78:   01000001    tsteq   r0, r1
  7c:   00637273    rsbeq   r7, r3, r3, ror r2
  80:   69706700    ldmdbvs r0!, {r8, r9, sl, sp, lr}^
  84:   00632e6f    rsbeq   r2, r3, pc, ror #28
  88:   67000001    strvs   r0, [r0, -r1]
  8c:   2e6f6970    mcrcs   9, 3, r6, cr15, cr0, {3}
  90:   00010068    andeq   r0, r1, r8, rrx
  94:   05000000    streq   r0, [r0, #-0]
  98:   0080ec02    addeq   lr, r0, r2, lsl #24
  9c:   010a0300    mrseq   r0, (UNDEF: 58)
  a0:   02004da0    andeq   r4, r0, #160, 26    ; 0x2800
  a4:   66060104    strvs   r0, [r6], -r4, lsl #2
  a8:   004c6806    subeq   r6, ip, r6, lsl #16
  ac:   06010402    streq   r0, [r1], -r2, lsl #8
  b0:   4d680666    stclmi  6, cr0, [r8, #-408]!    ; 0xfffffe68
  b4:   672f67a6    strvs   r6, [pc, -r6, lsr #15]!
  b8:   02846c64    addeq   r6, r4, #100, 24    ; 0x6400
  bc:   022f1424    eoreq   r1, pc, #36, 8  ; 0x24000000
  c0:   01010008    tsteq   r1, r8

Disassembly of section .debug_frame:

00000000 <.debug_frame>:
   0:   0000000c    andeq   r0, r0, ip
   4:   ffffffff            ; <UNDEFINED> instruction: 0xffffffff
   8:   7c020001    stcvc   0, cr0, [r2], {1}
   c:   000d0c0e    andeq   r0, sp, lr, lsl #24
  10:   0000000c    andeq   r0, r0, ip
  14:   00000000    andeq   r0, r0, r0
  18:   00008000    andeq   r8, r0, r0
  1c:   000000ec    andeq   r0, r0, ip, ror #1
  20:   0000000c    andeq   r0, r0, ip
  24:   ffffffff            ; <UNDEFINED> instruction: 0xffffffff
  28:   7c020001    stcvc   0, cr0, [r2], {1}
  2c:   000d0c0e    andeq   r0, sp, lr, lsl #24
  30:   0000001c    andeq   r0, r0, ip, lsl r0
  34:   00000020    andeq   r0, r0, r0, lsr #32
  38:   000080ec    andeq   r8, r0, ip, ror #1
  3c:   00000110    andeq   r0, r0, r0, lsl r1
  40:   8b040e42    blhi    103950 <_stack+0x83950>
  44:   0b0d4201    bleq    350850 <_stack+0x2d0850>
  48:   0d0d8002    stceq   0, cr8, [sp, #-8]
  4c:   000ecb42    andeq   ip, lr, r2, asr #22

Disassembly of section .debug_str:

00000000 <.debug_str>:
   0:   69736e75    ldmdbvs r3!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^
   4:   64656e67    strbtvs r6, [r5], #-3687    ; 0xfffff199
   8:   746e6920    strbtvc r6, [lr], #-2336    ; 0xfffff6e0
   c:   73552f00    cmpvc   r5, #0, 30
  10:   2f737265    svccs   0x00737265
  14:   6f63614a    svcvs   0x0063614a
  18:   66666f53    uqsaxvs r6, r6, r3
  1c:   7365442f    cmnvc   r5, #788529152  ; 0x2f000000
  20:   706f746b    rsbvc   r7, pc, fp, ror #8
  24:   6964452f    stmdbvs r4!, {r0, r1, r2, r3, r5, r8, sl, lr}^
  28:   2d6e6f73    stclcs  15, cr6, [lr, #-460]!   ; 0xfffffe34
  2c:   67005452    smlsdvs r0, r2, r4, r5
  30:   006f6970    rsbeq   r6, pc, r0, ror r9  ; <UNPREDICTABLE>
  34:   2f637273    svccs   0x00637273
  38:   6e69616d    powvsez f6, f1, #5.0
  3c:   4700632e    strmi   r6, [r0, -lr, lsr #6]
  40:   4320554e            ; <UNDEFINED> instruction: 0x4320554e
  44:   35203131    strcc   r3, [r0, #-305]!    ; 0xfffffecf
  48:   312e342e            ; <UNDEFINED> instruction: 0x312e342e
  4c:   31303220    teqcc   r0, r0, lsr #4
  50:   31393036    teqcc   r9, r6, lsr r0
  54:   72282039    eorvc   r2, r8, #57 ; 0x39
  58:   61656c65    cmnvs   r5, r5, ror #24
  5c:   20296573    eorcs   r6, r9, r3, ror r5
  60:   4d52415b    ldfmie  f4, [r2, #-364] ; 0xfffffe94
  64:   626d652f    rsbvs   r6, sp, #197132288  ; 0xbc00000
  68:   65646465    strbvs  r6, [r4, #-1125]!   ; 0xfffffb9b
  6c:   2d352d64    ldccs   13, cr2, [r5, #-400]!   ; 0xfffffe70
  70:   6e617262    cdpvs   2, 6, cr7, cr1, cr2, {3}
  74:   72206863    eorvc   r6, r0, #6488064    ; 0x630000
  78:   73697665    cmnvc   r9, #105906176  ; 0x6500000
  7c:   206e6f69    rsbcs   r6, lr, r9, ror #30
  80:   34303432    ldrtcc  r3, [r0], #-1074    ; 0xfffffbce
  84:   205d3639    subscs  r3, sp, r9, lsr r6
  88:   70666d2d    rsbvc   r6, r6, sp, lsr #26
  8c:   656e3d75    strbvs  r3, [lr, #-3445]!   ; 0xfffff28b
  90:   762d6e6f    strtvc  r6, [sp], -pc, ror #28
  94:   34767066    ldrbtcc r7, [r6], #-102 ; 0xffffff9a
  98:   666d2d20    strbtvs r2, [sp], -r0, lsr #26
  9c:   74616f6c    strbtvc r6, [r1], #-3948    ; 0xfffff094
  a0:   6962612d    stmdbvs r2!, {r0, r2, r3, r5, r8, sp, lr}^
  a4:   7261683d    rsbvc   r6, r1, #3997696    ; 0x3d0000
  a8:   6d2d2064    stcvs   0, cr2, [sp, #-400]!    ; 0xfffffe70
  ac:   68637261    stmdavs r3!, {r0, r5, r6, r9, ip, sp, lr}^
  b0:   6d72613d    ldfvse  f6, [r2, #-244]!    ; 0xffffff0c
  b4:   612d3776            ; <UNDEFINED> instruction: 0x612d3776
  b8:   746d2d20    strbtvc r2, [sp], #-3360    ; 0xfffff2e0
  bc:   3d656e75    stclcc  14, cr6, [r5, #-468]!   ; 0xfffffe2c
  c0:   74726f63    ldrbtvc r6, [r2], #-3939    ; 0xfffff09d
  c4:   612d7865            ; <UNDEFINED> instruction: 0x612d7865
  c8:   672d2037            ; <UNDEFINED> instruction: 0x672d2037
  cc:   304f2d20    subcc   r2, pc, r0, lsr #26
  d0:   69616d00    stmdbvs r1!, {r8, sl, fp, sp, lr}^
  d4:   6970006e    ldmdbvs r0!, {r1, r2, r3, r5, r6}^
  d8:   6d756e6e    ldclvs  14, cr6, [r5, #-440]!   ; 0xfffffe48
  dc:   63727300    cmnvs   r2, #0, 6
  e0:   6970672f    ldmdbvs r0!, {r0, r1, r2, r3, r5, r8, r9, sl, sp, lr}^
  e4:   00632e6f    rsbeq   r2, r3, pc, ror #28
  e8:   62727366    rsbsvs  r7, r2, #-1744830463    ; 0x98000001
  ec:   70007469    andvc   r7, r0, r9, ror #8
  f0:   6f4d6e69    svcvs   0x004d6e69
  f4:   6d006564    cfstr32vs   mvfx6, [r0, #-400]  ; 0xfffffe70
  f8:   0065646f    rsbeq   r6, r5, pc, ror #8

Disassembly of section .ARM.attributes:

00000000 <_stack-0x80000>:
   0:   00003441    andeq   r3, r0, r1, asr #8
   4:   61656100    cmnvs   r5, r0, lsl #2
   8:   01006962    tsteq   r0, r2, ror #18
   c:   0000002a    andeq   r0, r0, sl, lsr #32
  10:   412d3705            ; <UNDEFINED> instruction: 0x412d3705
  14:   070a0600    streq   r0, [sl, -r0, lsl #12]
  18:   09010841    stmdbeq r1, {r0, r6, fp}
  1c:   0c050a02    stceq   10, cr0, [r5], {2}
  20:   14041202    strne   r1, [r4], #-514 ; 0xfffffdfe
  24:   17011501    strne   r1, [r1, -r1, lsl #10]
  28:   19011803    stmdbne r1, {r0, r1, fp, ip}
  2c:   1c011a01    stcne   10, cr1, [r1], {1}
  30:   22061e01    andcs   r1, r6, #1, 28
  34:   Address 0x0000000000000034 is out of bounds.

Thanks in advance

c
assembly
raspberry-pi
kernel
asked on Stack Overflow Jun 24, 2017 by Jacob Soffer

2 Answers

1

i think the tim=500000 can cause problems because the LED is switched on too short to be recognizable by human eye. RPi's processor has a speed around 1 GHz ( https://en.wikipedia.org/wiki/Raspberry_Pi ) what is 1.000.000.000 Hz

so the switched-on time of the LED is approx 0.5 ms. maybe try tim=5000000000 to try approx. 5s visibility or try other timings like delay(), sleep(),... ( implement time delay in c )

answered on Stack Overflow Jun 24, 2017 by ralf htp • edited Jun 24, 2017 by ralf htp
0

very slight modifications, the naked attributes are not required (what tools are you using?)

asm(".globl _start; _start: nop\n");

#ifndef GPIO_H
#define GPIO_H

#ifdef RPI2
    #define GPIO_BASE       0x3F200000UL
#else
    #define GPIO_BASE       0x20200000UL
#endif

#if defined( RPIBPLUS ) || defined( RPI2 )
    #define LED_GPFSEL      GPIO_GPFSEL4
    #define LED_GPFBIT      21
    #define LED_GPSET       GPIO_GPSET1
    #define LED_GPCLR       GPIO_GPCLR1
    #define LED_GPIO_BIT    15
#else
    #define LED_GPFSEL      GPIO_GPFSEL1
    #define LED_GPFBIT      18
    #define LED_GPSET       GPIO_GPSET0
    #define LED_GPCLR       GPIO_GPCLR0
    #define LED_GPIO_BIT    16
#endif

#define GPIO_GPFSEL0    0
#define GPIO_GPFSEL1    1
#define GPIO_GPFSEL2    2
#define GPIO_GPFSEL3    3
#define GPIO_GPFSEL4    4
#define GPIO_GPFSEL5    5

#define GPIO_GPSET0     7
#define GPIO_GPSET1     8

#define GPIO_GPCLR0     10
#define GPIO_GPCLR1     11

#define GPIO_GPLEV0     13
#define GPIO_GPLEV1     14

#define GPIO_GPEDS0     16
#define GPIO_GPEDS1     17

#define GPIO_GPREN0     19
#define GPIO_GPREN1     20

#define GPIO_GPFEN0     22
#define GPIO_GPFEN1     23

#define GPIO_GPHEN0     25
#define GPIO_GPHEN1     26

#define GPIO_GPLEN0     28
#define GPIO_GPLEN1     29

#define GPIO_GPAREN0    31
#define GPIO_GPAREN1    32

#define GPIO_GPAFEN0    34
#define GPIO_GPAFEN1    35

#define GPIO_GPPUD      37
#define GPIO_GPPUDCLK0  38
#define GPIO_GPPUDCLK1  39

/** GPIO Register set */
volatile unsigned int* gpio;

/** Simple loop variable */
volatile unsigned int tim;

// Function to change a pin's mode
static int pinMode(int pinnum, int mode);

#endif


static int pinMode(int pinnum, int mode) {
    // Variable declaration and initialization
    int fsr = 0;
    int fsrbit;
    // Let's check the pin does exist
    if (pinnum < 0 || pinnum > 53) {
        // Abort, there is no such pin.
        return 1;
    }
    else if (mode < 0 || mode > 1) {
        // Abort, invalid mode (Actually there are 7 modes but we will only use 2)
        return 1;
    }
    // Create a pointer to the GPIO perhiperal register so we can speak to it
    gpio = (unsigned int*)GPIO_BASE;
    // And calculate wich FSR we should use
    /* do {
        if (pinnum > 9) {
            pinnum -= 10;
            fsr++;
        }
    } while (pinnum > 9); */
    if (pinnum > 9) {
        while (pinnum > 9) {
            pinnum -= 10;
            fsr++;
        }
    }
        // Then we calculate the bytes of the fsreg to use
        fsrbit = pinnum * 3;
        // Finally let's set the pin to the desired mode
        gpio[fsr] |= (mode << fsrbit);

        return 0;
}

int main(void)
{
    gpio = (unsigned int*)GPIO_BASE;

    /* Write 1 to the GPIO16 init nibble in the Function Select 1 GPIO
       peripheral register to enable GPIO16 as an output */
    // gpio[LED_GPFSEL] |= (1 << LED_GPFBIT);
    pinMode(47, 1);

    // Never return from here
    while(1)
    {
        for(tim = 0; tim < 500000; tim++)
            ;

        /* Set the LED GPIO pin low ( Turn OK LED on for original Pi, and off
           for plus models )*/
        gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);

        for(tim = 0; tim < 500000; tim++)
            ;

        /* Set the LED GPIO pin high ( Turn OK LED off for original Pi, and on
           for plus models )*/
        gpio[LED_GPSET] = (1 << LED_GPIO_BIT);
    }
}

along with some hackery to get it to link, not something you can use directly but main wont need to change, just bootstrap and linking.

00001000 <main>:
    1000:   e52de004    push    {lr}        ; (str lr, [sp, #-4]!)
    1004:   e3a00801    mov r0, #65536  ; 0x10000
    1008:   e3a0e000    mov lr, #0
    100c:   e59f3078    ldr r3, [pc, #120]  ; 108c <main+0x8c>
    1010:   e59f2078    ldr r2, [pc, #120]  ; 1090 <main+0x90>
    1014:   e5823000    str r3, [r2]
    1018:   e5932010    ldr r2, [r3, #16]
    101c:   e3822602    orr r2, r2, #2097152    ; 0x200000
    1020:   e1a0c003    mov r12, r3
    1024:   e5832010    str r2, [r3, #16]
    1028:   e59f1064    ldr r1, [pc, #100]  ; 1094 <main+0x94>
    102c:   e59f3064    ldr r3, [pc, #100]  ; 1098 <main+0x98>
    1030:   e583e000    str lr, [r3]
    1034:   e5932000    ldr r2, [r3]
    1038:   e1520001    cmp r2, r1
    103c:   8a000005    bhi 1058 <main+0x58>
    1040:   e5932000    ldr r2, [r3]
    1044:   e2822001    add r2, r2, #1
    1048:   e5832000    str r2, [r3]
    104c:   e5932000    ldr r2, [r3]
    1050:   e1520001    cmp r2, r1
    1054:   9afffff9    bls 1040 <main+0x40>
    1058:   e58c0028    str r0, [r12, #40]  ; 0x28
    105c:   e583e000    str lr, [r3]
    1060:   e5932000    ldr r2, [r3]
    1064:   e1520001    cmp r2, r1
    1068:   8a000005    bhi 1084 <main+0x84>
    106c:   e5932000    ldr r2, [r3]
    1070:   e2822001    add r2, r2, #1
    1074:   e5832000    str r2, [r3]
    1078:   e5932000    ldr r2, [r3]
    107c:   e1520001    cmp r2, r1
    1080:   9afffff9    bls 106c <main+0x6c>
    1084:   e58c001c    str r0, [r12, #28]
    1088:   eaffffe8    b   1030 <main+0x30>
    108c:   20200000    eorcs   r0, r0, r0
    1090:   000110a4    andeq   r1, r1, r4, lsr #1
    1094:   0007a11f    andeq   r10, r7, pc, lsl r1
    1098:   000110a0    andeq   r1, r1, r0, lsr #1

0000109c <_start>:
    109c:   e1a00000    nop         ; (mov r0, r0)

Disassembly of section .bss:

000110a0 <tim>:
   110a0:   00000000    andeq   r0, r0, r0

000110a4 <gpio>:
   110a4:   00000000    andeq   r0, r0, r0

so the first problem is here which comes straight from your code

    fsrbit = pinnum * 3;
    gpio[fsr] |= (mode << fsrbit);

    100c:   e59f3078    ldr r3, [pc, #120]  ; 108c <main+0x8c>

    1018:   e5932010    ldr r2, [r3, #16]
    101c:   e3822602    orr r2, r2, #2097152    ; 0x200000
    1024:   e5832010    str r2, [r3, #16]

doing a read-modify-write is correct, but unless you knew the bits were zeros to start with it is best to zero them first

gpio[fsr] &= (~(7<<fsrbit));
gpio[fsr] |= (mode<<fsrbit);

by declaring tim as volatile the code as you can see actually counts takes a few instructions, yes it might be a 1GHZ processor but you are not running that fast, you are fetching from dram (slow), even with the cache, and you have pipe hazards, etc.

As pointed out though maybe make your loop count number larger. Another thing to try is to swap things around on/off state.

first this:

while(1)
{
    gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);
    for(tim = 0; tim < 500000; tim++) continue;

    gpio[LED_GPSET] = (1 << LED_GPIO_BIT);
    for(tim = 0; tim < 500000; tim++) continue;
}

is it on, does it glow? then try this

while(1)
{
    gpio[LED_GPSET] = (1 << LED_GPIO_BIT);
    for(tim = 0; tim < 500000; tim++) continue;

    gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);
    for(tim = 0; tim < 500000; tim++) continue;
}

if the led looks the same then your count may be too small, make it larger, control the bit then do the delay not the other way around. If it still glows and doesnt blink with set first then clear or clear first then set? then maybe too fast still, just do this

    gpio[LED_GPSET] = (1 << LED_GPIO_BIT);

with no loop

or

    gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);

with no loop.

can you make it go on and stay on? can you make it go off and stay off? If not then there is something wrong in the code you use to make it go on and off, if so then there maybe something wrong with your delay. but examination of optimized code shown above the volatile is taking care of that and burning cycles.

your I solved with a naked answer, was deleted, so does that mean you didnt solve it? The baking pi tutorials are nice, glad they are there, but the baremetal forum at raspberry pi has over time been littered with it (baking pi) doesnt work questions, mostly makefile/directory issues, but perhaps others. Looks like though you get the gist of it, your gpio pointer/array style is interesting, I wouldnt go that way but so far it is working for you.

Ahh, wait and another bug...you didnt define RPI2 but clearly you had on the command line perhaps?

800c:   e3433f20    movt    r3, #16160  ; 0x3f20

so lets try my smaller build again

1034:   e5804020    str r4, [r0, #32]  ; 0x20
1048:   e580e02c    str lr, [r0, #44]   ; 0x2c

much better GPSET1 and GPCLR1 where 47 is found...so no bug there.

actually instead of hardcoding 47 you should have finished out your header file and used some LED_GPIO_BIT in the pinMode() call insuring you matched the LED_otherstuff to the gpio pin.

answered on Stack Overflow Jun 26, 2017 by old_timer

User contributions licensed under CC BY-SA 3.0