This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Can't compile my code with arm-none-eabi-gcc to work, Beginner

I've only used AVR and Arduino before which really don't count as embed! so I have a little trouble compiling my blinky.

I'm mainly a PC programmer. I have an LPC1768 dev board!

Here's what I did:

I first installed arm-none-eabi-gcc on my Ubuntu virtual machine (I have a ubuntu dual boot but I wanted to try it here first to learn)

Secondly I wrote a small code which uses the lpc17xx.h header and does nothing but turn a GPIO on and high, I then compiled it with

arm-none-eabi-gcc -Wall -mcpu=cortex-m3 -mlittle-endian -mthumb  -DLPX17xx -Os -c main.c -o main.o

It worked! I repeated this for all of the files("core_cm3.h", "LPC17xx.h", "system_LPC17xx.c") and it worked too, but when I tried to compile "startup_lpc17xx.s" it gave me a bunch of errors saying "startup_LPC17xx.s:272: Error: bad instruction".

So I found an already compiled .o version of this file in keil folders and used it instead.


I googled and found an lpc1768 linker script and ran this:

arm-none-eabi-gcc -mcpu=cortex-m3 -mlittle-endian -mthumb -DLPC17xx -TLPC17xx.ld -Wl,--gc-sections system_LPC17xx.o main.o startup_LPC17xx.o -o main.elf

and I get this error: "startup_LPC17xx.o: file not recognized: File format not recognized

collect2: error: ld returned 1 exit status"

Can anyone help me I also edited the linker script, I changed "FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K" to "FLASH (rx) : ORIGIN = 0x2000 , LENGTH = 512K" because the board says the code should start from here as it has a bootloader and my pc recogonizes it as a USB storage

also the board manual says I should add "NO_CRP" to asm tab of keil project options. I don't know what this is so I've no idea what to do.

I did manage to create a file in windows with CrossStudios but my board didn't blink the leds the same code worked in keil but I rather fix my GCC toolchain

I'm a begginer and I don't know how to use makefile or write a linker script or a startup code! I don't know much on how the code runs either

Parents
  • While I don't have any recommendations for books on "how to create linker scripts", you might be interested by The Definitive Guide to ARM® CORTEX®-M3 and CORTEX®-M4 Processors (Third Edition).

    When it comes to ARM programming, what helped me the most was building my first "Hello world" assembler script, that ran on an Android device through adb shell.

    The Hello world script was :

    .data
    
    msg:
        .ascii      "Hello, ARM!\n"
    len = . - msg
    
    
    .text
    
    .globl _start
    _start:
        /* syscall write(int fd, const void *buf, size_t count) */
        mov    %r0, $1    /* fd -> stdout */
        ldr    %r1, =msg  /* buf -> msg */
        ldr    %r2, =len  /* count -> len(msg) */
        mov    %r7, $4    /* write is syscall #4 */
        svc    $0          /* invoke syscall */
    
        /* syscall exit(int status) */
        mov    %r0, $0    /* status -> 0 */
        mov    %r7, $1    /* exit is syscall #1 */
        svc    $0          /* invoke syscall */
    

    And compiled like this :

    armv7a-hardfloat-linux-gnueabi-as -o hello.o hello.s
    armv7a-hardfloat-linux-gnueabi-ld -o hello hello.o
    adb push hello /data/local/tmp
    adb shell /data/local/tmp/hello
    

    Hello, ARM!

    Then, I searched for a list of Linux system calls numbers for ARM and began playing with the code.

    I also learned how to execute ARM code directly on a virtual machine, using this tutorial : 3. Hello ARM . You're maybe searching for that kind of tutorials. QEMU allows you to use GDB to step on each instruction executed by the virtual machine, and check/change the registers between instructions.

    I learned the ELF structure and ARM machine code format by creating a small ELF linker myself in ruby, using :

    - ARM Architecture Reference Manual, from ARM. You can get it from the ARM website. The instruction encoding section is a gold mine to understand how the instructions can be encoded.

    - Executable and Linking Format (ELF) Specification, in order to understand the architecture of ELF files.

    - A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux

    I didn't go very far (Never implemented a Global Offset Table/Procedure Linkage Table), but I learned enough to understand the architecture of ELF objects (headers and sections) and how calling procedures from external libraries and dlopen() worked, which demystified a LOT of things.

Reply
  • While I don't have any recommendations for books on "how to create linker scripts", you might be interested by The Definitive Guide to ARM® CORTEX®-M3 and CORTEX®-M4 Processors (Third Edition).

    When it comes to ARM programming, what helped me the most was building my first "Hello world" assembler script, that ran on an Android device through adb shell.

    The Hello world script was :

    .data
    
    msg:
        .ascii      "Hello, ARM!\n"
    len = . - msg
    
    
    .text
    
    .globl _start
    _start:
        /* syscall write(int fd, const void *buf, size_t count) */
        mov    %r0, $1    /* fd -> stdout */
        ldr    %r1, =msg  /* buf -> msg */
        ldr    %r2, =len  /* count -> len(msg) */
        mov    %r7, $4    /* write is syscall #4 */
        svc    $0          /* invoke syscall */
    
        /* syscall exit(int status) */
        mov    %r0, $0    /* status -> 0 */
        mov    %r7, $1    /* exit is syscall #1 */
        svc    $0          /* invoke syscall */
    

    And compiled like this :

    armv7a-hardfloat-linux-gnueabi-as -o hello.o hello.s
    armv7a-hardfloat-linux-gnueabi-ld -o hello hello.o
    adb push hello /data/local/tmp
    adb shell /data/local/tmp/hello
    

    Hello, ARM!

    Then, I searched for a list of Linux system calls numbers for ARM and began playing with the code.

    I also learned how to execute ARM code directly on a virtual machine, using this tutorial : 3. Hello ARM . You're maybe searching for that kind of tutorials. QEMU allows you to use GDB to step on each instruction executed by the virtual machine, and check/change the registers between instructions.

    I learned the ELF structure and ARM machine code format by creating a small ELF linker myself in ruby, using :

    - ARM Architecture Reference Manual, from ARM. You can get it from the ARM website. The instruction encoding section is a gold mine to understand how the instructions can be encoded.

    - Executable and Linking Format (ELF) Specification, in order to understand the architecture of ELF files.

    - A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux

    I didn't go very far (Never implemented a Global Offset Table/Procedure Linkage Table), but I learned enough to understand the architecture of ELF objects (headers and sections) and how calling procedures from external libraries and dlopen() worked, which demystified a LOT of things.

Children