I was trying to upload a simple code to my board Tiva C EK-TM4C123GXL but it didn't work. I found out that when I turn the optimizer off, the code works fine. This is the code for blinking the on-board LED:
/* p2_3b.c: Toggling LEDs using special function registers by their names defined in
the TivaWare header file */
#include <stdint.h>
#include "inc/tm4c123gh6pm.h"
void delayMs(volatile int n);
int main(void)
{
/* enable clock to GPIOF at clock gating control register */
SYSCTL_RCGCGPIO_R |= SYSCTL_RCGCGPIO_R5;
/* enable the GPIO pins for the LED (PF3, 2 1) as output */
GPIO_PORTF_DIR_R = 0x0E;
/* enable the GPIO pins for digital function */
GPIO_PORTF_DEN_R = 0x0E;
while(1)
{
GPIO_PORTF_DATA_R = 0x0E; /* turn on all LEDs */
delayMs(500);
GPIO_PORTF_DATA_R = 0; /* turn off all LEDs */
delayMs(500);
}
}
/* delay n milliseconds (16 MHz CPU clock) */
void delayMs(volatile int n)
{
volatile int i, j;
for(i = 0; i < n; i++)
for(j = 0; j < 3180; j++)
{} /* do nothing for 1 ms */
}
/* This function is called by the startup assembly code to perform system specific
initialization tasks. */
void SystemInit(void)
{
/* Grant coprocessor access */
/* This is required since TM4C123G has a floating point coprocessor. */
NVIC_CPAC_R |= 0x00F00000;
}
Disassembly of the Non-optimized version:
9 {
main():
0000026c: B508 push {r3, lr}
11 SYSCTL_RCGCGPIO_R |= SYSCTL_RCGCGPIO_R5;
0000026e: 4920 ldr r1, [pc, #0x80]
00000270: 6808 ldr r0, [r1]
00000272: F0400020 orr r0, r0, #0x20
00000276: 6008 str r0, [r1]
13 GPIO_PORTF_DIR_R = 0x0E;
00000278: 491E ldr r1, [pc, #0x78]
0000027a: 200E movs r0, #0xe
0000027c: 6008 str r0, [r1]
15 GPIO_PORTF_DEN_R = 0x0E;
0000027e: 491E ldr r1, [pc, #0x78]
00000280: 200E movs r0, #0xe
00000282: 6008 str r0, [r1]
18 GPIO_PORTF_DATA_R = 0x0E; /* turn on all LEDs */
$C$L1:
00000284: 491D ldr r1, [pc, #0x74]
00000286: 200E movs r0, #0xe
00000288: 6008 str r0, [r1]
19 delayMs(500);
0000028a: F44F70FA mov.w r0, #0x1f4
0000028e: F000F808 bl #0x2a2
20 GPIO_PORTF_DATA_R = 0; /* turn off all LEDs */
00000292: 491A ldr r1, [pc, #0x68]
00000294: 2000 movs r0, #0
00000296: 6008 str r0, [r1]
21 delayMs(500);
00000298: F44F70FA mov.w r0, #0x1f4
0000029c: F000F801 bl #0x2a2
16 while(1)
000002a0: E7F0 b $C$L1
26 {
delayMs():
000002a2: F1AD0D10 sub.w sp, sp, #0x10
000002a6: 9000 str r0, [sp]
28 for(i = 0; i < n; i++)
000002a8: 2000 movs r0, #0
000002aa: 9001 str r0, [sp, #4]
000002ac: 9800 ldr r0, [sp]
000002ae: 9901 ldr r1, [sp, #4]
000002b0: 4288 cmp r0, r1
000002b2: DD15 ble $C$L5
29 for(j = 0; j < 3180; j++)
$C$L2:
000002b4: 2000 movs r0, #0
000002b6: 9002 str r0, [sp, #8]
000002b8: 9802 ldr r0, [sp, #8]
000002ba: F640416C movw r1, #0xc6c
000002be: 4281 cmp r1, r0
000002c0: DD07 ble $C$L4
$C$L3:
000002c2: 9802 ldr r0, [sp, #8]
000002c4: 1C40 adds r0, r0, #1
000002c6: 9002 str r0, [sp, #8]
000002c8: 9802 ldr r0, [sp, #8]
000002ca: F640416C movw r1, #0xc6c
000002ce: 4281 cmp r1, r0
000002d0: DCF7 bgt $C$L3
28 for(i = 0; i < n; i++)
$C$L4:
000002d2: 9801 ldr r0, [sp, #4]
000002d4: 1C40 adds r0, r0, #1
000002d6: 9001 str r0, [sp, #4]
000002d8: 9800 ldr r0, [sp]
000002da: 9901 ldr r1, [sp, #4]
000002dc: 4288 cmp r0, r1
000002de: DCE9 bgt $C$L2
31 }
$C$L5:
000002e0: B004 add sp, #0x10
000002e2: 4770 bx lr
38 NVIC_CPAC_R |= 0x00F00000;
SystemInit():
000002e4: 4906 ldr r1, [pc, #0x18]
000002e6: 6808 ldr r0, [r1]
000002e8: F4400070 orr r0, r0, #0xf00000
000002ec: 6008 str r0, [r1]
39 }
000002ee: 4770 bx lr
$C$CON1:
000002f0: E608 b #0xffffff04
000002f2: 400F ands r7, r1
$C$CON2:
000002f4: 5400 strb r0, [r0, r0]
000002f6: 4002 ands r2, r0
$C$CON3:
000002f8: 551C strb r4, [r3, r4]
000002fa: 4002 ands r2, r0
$C$CON4:
000002fc: 53FC strh r4, [r7, r7]
000002fe: 4002 ands r2, r0
$C$CON5:
00000300: ED88E000 stc p0, c14, [r8]
133 _c_int00_template(0, 0);
_c_int00_noinit_noargs():
00000304: 4808 ldr r0, [pc, #0x20]
00000306: F3808808 msr msp, r0
0000030a: 4908 ldr r1, [pc, #0x20]
0000030c: 6808 ldr r0, [r1]
0000030e: F4400070 orr r0, r0, #0xf00000
00000312: 6008 str r0, [r1]
00000314: BF00 nop
00000316: BF00 nop
00000318: F000F810 bl #0x33c
0000031c: 2000 movs r0, #0
0000031e: F7FFFFA5 bl #0x26c
00000322: 2001 movs r0, #1
00000324: F000F80C bl #0x340
$C$CON1:
00000328: 0200 lsls r0, r0, #8
0000032a: 2000 movs r0, #0
$C$CON2:
0000032c: ED88E000 stc p0, c14, [r8]
244 __asm(" .global _c_int00\n"
ResetISR():
00000330: F7FFBFE8 b.w _c_int00_noinit_noargs
246 }
00000334: 4770 bx lr
261 while(1)
$C$L1, NmiSR():
00000336: E7FE b NmiSR
279 while(1)
$C$L2, FaultISR():
00000338: E7FE b FaultISR
297 while(1)
$C$L3, IntDefaultHandler():
0000033a: E7FE b IntDefaultHandler
58 return 1;
_system_pre_init():
0000033c: 2001 movs r0, #1
0000033e: 4770 bx lr
105 {
C$$EXIT(), abort():
00000340: BF00 nop
124 for (;;); /* SPINS FOREVER */
Disassembly of the Optimized version:
26 {
delayMs():
0000026c: F1AD0D10 sub.w sp, sp, #0x10
28 for(i = 0; i < n; i++)
00000270: 2100 movs r1, #0
26 {
00000272: 9000 str r0, [sp]
29 for(j = 0; j < 3180; j++)
00000274: F640426C movw r2, #0xc6c
28 for(i = 0; i < n; i++)
00000278: 9101 str r1, [sp, #4]
0000027a: E002 b $C$L2
$C$L1:
0000027c: 9801 ldr r0, [sp, #4]
0000027e: 1C40 adds r0, r0, #1
00000280: 9001 str r0, [sp, #4]
$C$L2:
00000282: 9800 ldr r0, [sp]
00000284: 9B01 ldr r3, [sp, #4]
00000286: 4298 cmp r0, r3
00000288: DD07 ble $C$L4
29 for(j = 0; j < 3180; j++)
0000028a: 9102 str r1, [sp, #8]
$C$L3:
0000028c: 9802 ldr r0, [sp, #8]
0000028e: 4282 cmp r2, r0
00000290: DDF4 ble $C$L1
00000292: 9802 ldr r0, [sp, #8]
00000294: 1C40 adds r0, r0, #1
00000296: 9002 str r0, [sp, #8]
00000298: E7F8 b $C$L3
$C$L4:
0000029a: B004 add sp, #0x10
0000029c: 4770 bx lr
9 {
main():
0000029e: B570 push {r4, r5, r6, lr}
11 SYSCTL_RCGCGPIO_R |= SYSCTL_RCGCGPIO_R5;
000002a0: 490D ldr r1, [pc, #0x34]
13 GPIO_PORTF_DIR_R = 0x0E;
000002a2: 4C0E ldr r4, [pc, #0x38]
11 SYSCTL_RCGCGPIO_R |= SYSCTL_RCGCGPIO_R5;
000002a4: 6808 ldr r0, [r1]
000002a6: F0400020 orr r0, r0, #0x20
000002aa: 6008 str r0, [r1]
13 GPIO_PORTF_DIR_R = 0x0E;
000002ac: 250E movs r5, #0xe
000002ae: 6065 str r5, [r4, #4]
15 GPIO_PORTF_DEN_R = 0x0E;
000002b0: F8C45120 str.w r5, [r4, #0x120]
000002b4: 2600 movs r6, #0
18 GPIO_PORTF_DATA_R = 0x0E; /* turn on all LEDs */
$C$L5:
000002b6: 6025 str r5, [r4]
19 delayMs(500);
000002b8: F44F70FA mov.w r0, #0x1f4
000002bc: F7FFFFD6 bl #0x26c
20 GPIO_PORTF_DATA_R = 0; /* turn off all LEDs */
000002c0: 6026 str r6, [r4]
21 delayMs(500);
000002c2: F44F70FA mov.w r0, #0x1f4
000002c6: F7FFFFD1 bl #0x26c
16 while(1)
000002ca: E7F4 b $C$L5
38 NVIC_CPAC_R |= 0x00F00000;
SystemInit():
000002cc: 4904 ldr r1, [pc, #0x10]
000002ce: 6808 ldr r0, [r1]
000002d0: F4400070 orr r0, r0, #0xf00000
000002d4: 6008 str r0, [r1]
000002d6: 4770 bx lr
$C$CON1:
000002d8: E608 b #0xfffffeec
000002da: 400F ands r7, r1
$C$CON2:
000002dc: 53FC strh r4, [r7, r7]
000002de: 4002 ands r2, r0
$C$CON3:
000002e0: ED88E000 stc p0, c14, [r8]
133 _c_int00_template(0, 0);
_c_int00_noinit_noargs():
000002e4: 4808 ldr r0, [pc, #0x20]
000002e6: F3808808 msr msp, r0
000002ea: 4908 ldr r1, [pc, #0x20]
000002ec: 6808 ldr r0, [r1]
000002ee: F4400070 orr r0, r0, #0xf00000
000002f2: 6008 str r0, [r1]
000002f4: BF00 nop
000002f6: BF00 nop
000002f8: F000F810 bl #0x31c
000002fc: 2000 movs r0, #0
000002fe: F7FFFFCE bl #0x29e
00000302: 2001 movs r0, #1
00000304: F000F80C bl #0x320
$C$CON1:
00000308: 0200 lsls r0, r0, #8
0000030a: 2000 movs r0, #0
$C$CON2:
0000030c: ED88E000 stc p0, c14, [r8]
239 {
ResetISR():
00000310: F7FFBFE8 b.w _c_int00_noinit_noargs
00000314: 4770 bx lr
261 while(1)
$C$L1, NmiSR():
00000316: E7FE b NmiSR
297 while(1)
$C$L2, IntDefaultHandler():
00000318: E7FE b IntDefaultHandler
279 while(1)
$C$L3, FaultISR():
0000031a: E7FE b FaultISR
58 return 1;
_system_pre_init():
0000031c: 2001 movs r0, #1
0000031e: 4770 bx lr
105 {
C$$EXIT(), abort():
00000320: BF00 nop
124 for (;;); /* SPINS FOREVER */
$C$L1:
00000322: E7FE b $C$L1
This code is an example in Mazidi book. I also changed the variables in delayMs
function to volatile
(although it is not global) but this had no effect. The code still works only when optimization is off.
I tried debugging the code and the program seems to work fine for both cases (optimization on and off). In debugging, the led blinks, then the control transfers to delayMs
with no problem and it counts 500 * 3180
times and returns to main
then the code continues with no problem. The Assembly code generated in both cases is different but it works.
The problem is: When trying to load the code through CCS (Code Composer Studio) or through lm4flash tool (it loads the .bin file to the board), the code works only when optimization is off.
I use Code Composer Studio version 9 (latest) with compiler TI v18.12.2.LTS.
OS: Ubuntu Bionic 18.04.2 LTS
Thank you in advance!
__asm(" NOP");
inside your inner for loop in your delay routine, or possibly__nop();
if it is defined. \$\endgroup\$i
andj
outside of any function (making them static by default) and use thevolatile
attribute. \$\endgroup\$