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
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 )
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.
User contributions licensed under CC BY-SA 3.0