docs

a slatepencil documentail site

View on GitHub

C

Source code and header files are pre-processed to produce an intermediate file. This is compiled to produce an assembly code file. The assembler takes this and produces object code which is combined with library files by the linker to produce executable code.

Compiler Installment

The compiler only needs to be aware the CPU architecture and not the platform architecture of the target embedded device

windows

linux

# gcc – Host machines cross Compiler. Used for testing architecture independent code. This should already be installed on your machine.
sudo apt-get install gcc-10

# clang llvm
sudo apt-get install clang-12

# To search for packages you can install you can search the linked repositories.
sudo apt-cache search arm-none-eabi 
sudo apt-get install gcc-arm-none-eabi

MaxOS

VS Code tasks config

.vscode/tasks.json

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "cppbuild",
      "label": "GCC 12.3.0",
      "command": "C:\\mingw64\\bin\\g++.exe",
      "args": [
        "-fdiagnostics-color=always",
        "-g",
        "-std=c++20",
        // "${file}",
        "${workspaceFolder}\\*.cpp",
        "-o",
        // "${workspaceFolder}\\root.exe",
        "${fileDirname}\\${fileBasenameNoExtension}.exe"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": ["$gcc"],
      "group": "build",
      "detail": "compiler: C:\\mingw64\\bin\\g++.exe"
    },
    {
      "type": "cppbuild",
      "label": "Clang++ 16.0.4",
      "command": "C:\\mingw64\\bin\\clang++.exe",
      "args": [
        "-g",
        "-std=c++20",
        // "${file}",
        "${workspaceFolder}\\*.cpp",
        "-o",
        "${fileDirname}\\${fileBasenameNoExtension}.exe"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": ["$gcc"],
      "group": "build",
      "detail": "compiler: C:\\mingw64\\bin\\clang++.exe"
    },
    {
      "type": "cppbuild",
      "label": "Build with MSVC",
      "command": "cl.exe",
      "args": [
        "/Zi",
        "/std:c++latest",
        "/EHsc",
        "/nologo",
        "/Fe:",
        "${fileDirname}\\${fileBasenameNoExtension}.exe",
        // "${file}",
        "${workspaceFolder}\\*.cpp"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": ["$msCompile"],
      "group": "build",
      "detail": "compiler: cl.exe"
    }
  ]
}

Ubuntu 10.04 (GCC v4.4.3)

MacOS Ventura 13.1

$ gcc -v -o tmp tmp.c
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple arm64-apple-macosx13.0.0 -Wundef-prefix=TARGET_OS_ -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -emit-obj -mrelax-all --mrelax-relocations -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name tmp.c -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -fno-strict-return -fno-rounding-math -funwind-tables=2 -fobjc-msgsend-selector-stubs -target-sdk-version=13.1 -fvisibility-inlines-hidden-static-local-var -target-cpu apple-m1 -target-feature +v8.5a -target-feature +fp-armv8 -target-feature +neon -target-feature +crc -target-feature +crypto -target-feature +dotprod -target-feature +fp16fml -target-feature +ras -target-feature +lse -target-feature +rdm -target-feature +rcpc -target-feature +zcm -target-feature +zcz -target-feature +fullfp16 -target-feature +sm4 -target-feature +sha3 -target-feature +sha2 -target-feature +aes -target-abi darwinpcs -fallow-half-arguments-and-returns -debugger-tuning=lldb -target-linker-version 820.1 -v -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -I/usr/local/include -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -Wno-elaborated-enum-base -Wno-reserved-identifier -Wno-gnu-folding-constant -Wno-cast-function-type -Wno-bitwise-instead-of-logical -fdebug-compilation-dir=/Users/username/slatepencil/docs/iot -ferror-limit 19 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fmax-type-align=16 -fcommon -fcolor-diagnostics -clang-vendor-feature=+messageToSelfInClassMethodIdReturnType -clang-vendor-feature=+disableInferNewAvailabilityFromInit -clang-vendor-feature=+disableNonDependentMemberExprInCurrentInstantiation -fno-odr-hash-protocols -clang-vendor-feature=+enableAggressiveVLAFolding -clang-vendor-feature=+revert09abecef7bbf -clang-vendor-feature=+thisNoAlignAttr -clang-vendor-feature=+thisNoNullAttr -mllvm -disable-aligned-alloc-awareness=1 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/folders/sy/zpxfq5gx4n72_9jkbbq0yl7c0000gp/T/tmp-6ae008.o -x c tmp.c
clang -cc1 version 14.0.0 (clang-1400.0.29.202) default target arm64-apple-darwin22.2.0
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include"
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -lto_library /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libLTO.dylib -no_deduplicate -dynamic -arch arm64 -platform_version macos 13.0.0 13.1 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -o tmp -L/usr/local/lib /var/folders/sy/zpxfq5gx4n72_9jkbbq0yl7c0000gp/T/tmp-6ae008.o -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/lib/darwin/libclang_rt.osx.a

Create Environments

Linux Kernel dependencies KERNEL v5.14.15

kernel config

use kylin internal config

compile

ARM cross compiler

QEMU v4.1.0

Headers

header.h common func common func common func common func common func common func
math.h pow sqrt fabs      
stdio.h printf scanf        
stdlib.h malloc free calloc realloc rand  
string.h strlen strcmp strlwr strupr strcat strcpy

Include directive

The GNU C Library (glibc) manual

aarch64-linux-gnu (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0

includes ├── aarch64-linux-gnu │   ├── asm │   ├── bits │   └── sys ├── asm-generic ├── gnu ├── linux │   ├── byteorder │   ├── can │   └── sched ├── net ├── dirent.h ├── endian.h ├── errno.h ├── error.h ├── fcntl.h ├── features.h ├── limits.h ├── malloc.h ├── paths.h ├── proc_service.h ├── pthread.h ├── sched.h ├── semaphore.h ├── signal.h ├── stdint.h ├── stdio.h ├── stdlib.h ├── string.h ├── strings.h ├── syslog.h ├── unistd.h └── wchar.h

ASim

ASim is an emulator. It interprets the assembly code instructions and executes them one at a time. This works in a similar way to an interpreter such as Python.

# repo: https://github.com/computation-structures/asim

        mov x0, #1
inc:    add x0, x0, #1
        cmp x0, #10
        b.eq end
        b inc
end:
        hlt

Software Modules and Libraries

Creating Modules

// memory.c
#include "memory.h"

char memzero(char * src, int length) {
    int i;
    for (i = 0; i < length; i++) {
        *src++ = 0;
    }
}
// memory.h
#ifndef __MEMORY_H__
#define __MEMORY_H__

/***********************************************
* memzero() - Takes a pointer to a location
*        in memory and sets the contents to zero
*        for a length bytes.
* char * src: Pointer starting byte
* int length: Number of bytes to zero
* char (return): Success or Failure of operation
************************************************/
char memzero(char * src, int length);
#endif /* __MEMORY_H__ */
// memory.h
#pragma once

char memzero(char * src, int length);

Portable Header interface

// main.c
#include "platform.h"

int main(void) {
    platform_intitialize();
    /* more code here */
    return 0;
}
// platform.h
#ifndef __PLATFORM_H__
#define __PLATFROM_H__

#if defined ( KL25_PLATFROM ) && !defined ( MSP_PLATFORM)
#include "kl25_platform.h"
#elif defined ( MSP_PLATFORM ) &&  !defined( KL25_PLATFROM )
#include "msp_platform.h"
#else
  #error "Plaese specify one platfrom target"
#endif

#endif /* __PLATFORM_H__ */
// msp_platform.h
#ifndef __MSP_PLATOFRM_H__
#define __MSP_PLATOFRM_H__

void platform_initialize();

#endif /* __MSP_PLATOFRM_H__ */
// kl25_platform.h
#ifndef __KL25_PLATOFRM_H__
#define __KL25_PLATOFRM_H__

void platform_initialize();

#endif /* __KL25_PLATOFRM_H__ */

Compiled Libraries

Static Libraries: Directly linked into your output executable

Shared Libraries: Linked dynamically at runtime with your executable

Linker

Combines all of objects files(NOT human readable) into a single executable, Object code uses symbols to reference other functions/variables, linker process can be invoided usin ld or indirectly using gcc

Linkers

gcc main.c -o main.out

gcc <other-options-here> -Xlinker -T Xlinker mkl25z_lnk.ld

gcc main.c -o main.out -Wl,-T,liker_file.lds

Linker Script Details

Linker flags

/******************************************************************************
*
* Copyright (C) 2012 - 2016 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*  Redistributions of source code must retain the above copyright
*  notice, this list of conditions and the following disclaimer.
*
*  Redistributions in binary form must reproduce the above copyright
*  notice, this list of conditions and the following disclaimer in the
*  documentation and/or other materials provided with the
*  distribution.
*
*  Neither the name of Texas Instruments Incorporated nor the names of
*  its contributors may be used to endorse or promote products derived
*  from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* GCC linker script for Texas Instruments MSP432P401R
*
* File creation date: 2016-05-09
*
******************************************************************************/

MEMORY
{
    MAIN_FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00040000
    INFO_FLASH (RX) : ORIGIN = 0x00200000, LENGTH = 0x00004000
    SRAM_CODE  (RWX): ORIGIN = 0x01000000, LENGTH = 0x00010000
    SRAM_DATA  (RW) : ORIGIN = 0x20000000, LENGTH = 0x00010000
}

REGION_ALIAS("REGION_TEXT", MAIN_FLASH);
REGION_ALIAS("REGION_INFO", INFO_FLASH);
REGION_ALIAS("REGION_BSS", SRAM_DATA);
REGION_ALIAS("REGION_DATA", SRAM_DATA);
REGION_ALIAS("REGION_STACK", SRAM_DATA);
REGION_ALIAS("REGION_HEAP", SRAM_DATA);
REGION_ALIAS("REGION_ARM_EXIDX", MAIN_FLASH);
REGION_ALIAS("REGION_ARM_EXTAB", MAIN_FLASH);

SECTIONS {

    /* section for the interrupt vector area                                 */
    PROVIDE (_intvecs_base_address =
        DEFINED(_intvecs_base_address) ? _intvecs_base_address : 0x0);

    .intvecs (_intvecs_base_address) : AT (_intvecs_base_address) {
        KEEP (*(.intvecs))
    } > REGION_TEXT

    /* The following three sections show the usage of the INFO flash memory  */
    /* INFO flash memory is intended to be used for the following            */
    /* device specific purposes:                                             */
    /* Flash mailbox for device security operations                          */
    PROVIDE (_mailbox_base_address = 0x200000);

    .flashMailbox (_mailbox_base_address) : AT (_mailbox_base_address) {
        KEEP (*(.flashMailbox))
    } > REGION_INFO

    /* TLV table for device identification and characterization              */
    PROVIDE (_tlv_base_address = 0x00201000);

    .tlvTable (_tlv_base_address) (NOLOAD) : AT (_tlv_base_address) {
        KEEP (*(.tlvTable))
    } > REGION_INFO

    /* BSL area for device bootstrap loader                                  */
    PROVIDE (_bsl_base_address = 0x00202000);

    .bslArea (_bsl_base_address) : AT (_bsl_base_address) {
        KEEP (*(.bslArea))
    } > REGION_INFO

    PROVIDE (_vtable_base_address =
        DEFINED(_vtable_base_address) ? _vtable_base_address : 0x20000000);

    .vtable (_vtable_base_address) : AT (_vtable_base_address) {
        KEEP (*(.vtable))
    } > REGION_DATA

    .text : {
        CREATE_OBJECT_SYMBOLS
        KEEP (*(.text))
        *(.text.*)
        . = ALIGN(0x4);
        KEEP (*(.ctors))
        . = ALIGN(0x4);
        KEEP (*(.dtors))
        . = ALIGN(0x4);
        __init_array_start = .;
        KEEP (*(.init_array*))
        __init_array_end = .;
        *(.init)
        *(.fini*)
    } > REGION_TEXT AT> REGION_TEXT

    .rodata : {
        *(.rodata)
        *(.rodata.*)
    } > REGION_TEXT AT> REGION_TEXT

    .ARM.exidx : {
        __exidx_start = .;
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        __exidx_end = .;
    } > REGION_ARM_EXIDX AT> REGION_ARM_EXIDX

    .ARM.extab : {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > REGION_ARM_EXTAB AT> REGION_ARM_EXTAB

    __etext = .;

    .data : {
        __data_load__ = LOADADDR (.data);
        __data_start__ = .;
        KEEP (*(.data))
        KEEP (*(.data*))
        . = ALIGN (4);
        __data_end__ = .;
    } > REGION_DATA AT> REGION_TEXT

    .bss : {
        __bss_start__ = .;
        *(.shbss)
        KEEP (*(.bss))
        *(.bss.*)
        *(COMMON)
        . = ALIGN (4);
        __bss_end__ = .;
    } > REGION_BSS AT> REGION_BSS

    .heap : {
        __heap_start__ = .;
        end = __heap_start__;
        _end = end;
        __end = end;
        KEEP (*(.heap))
    } > REGION_HEAP AT> REGION_HEAP



    .stack (NOLOAD) : ALIGN(0x8) {
        _stack = .;
        __stack = .;
        KEEP(*(.stack))
    } > REGION_STACK AT> REGION_STACK

}

Build

c example compilation & linking

GNU C Compiler / GNU Compiler Collection (gcc)

$ gcc -v
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
# Compile and Link with Optimizations
$ gcc main.c -o main.o -O2


# gcc [OPTIONS] -E [FILE-TO-PREPROCESS]
# gcc [OPTIONS] [FILE-TO-COMPILE]

# This will compile and link. Also specifies the output file to store as the
# executable file (using the -o <FILE> option. All warnings will be treated as
# errors and use the c99 c-standard.
gcc -std=c99 -Werror - main.c

# This will stop compilation after preprocessing has completed. Also specifies
# theoutput file to store as the preprocessed file (using the -o <FILE> option). All
# warnings will be treated as errors and use the c99 c-standard.
gcc -std=c99 -Werror -E main.c -o main.i

# This will compile and stop before link (-c option). All warnings will be
# enabled, use the c89 C-standard. Also use the -v verbose option to print lots
# of informaiton of what gcc is doing to the terminal.
gcc -std=c89 -Wall -v -c main.c

# This command will use the MSP compile time switch to call the msp platform
# print function. You define at the command line using the -D
gcc -o main.out main.c kl25z.c msp.c my_file.c -DMSP

Compiler Attributes

// Alignment attribues specify memory alignment for data
int8_t foo __attribute__ ((aligned(4)));

// at a minimum, structure requires 6 bytes
typedef struct {
  int8_t var1;
  int32_t var2;
  int8_t var3;
} str1;

typedef struct {
  int8_t var1 __attribute__ ((aligned(4)));
  int32_t var2 __attribute__ ((aligned(4)));
  int8_t var3 __attribute__ ((aligned(4)));
} str2;

sizeof(str2) // 12 bytes

// structure is algned, all members aligned
// Aligned structure members size would require 12 bytes, not power of 2
typedef struct {
  int8_t var1;
  int32_t var2;
  int8_t var3;
} str3 __attribute__ ((aligned));

sizeof(str3) // 16 bytes

// when structure is packed, members will be unaligned!!!
typedef struct {
  int8_t var1;
  int32_t var2;
  int8_t var3;
} str4 __attribute__ ((packed));

sizeof(str4) // 6 bytes

// Function Attributes
// `inline` keyword is a c99 Feature (not supported in c89)
// `inline` skips calling convention, copies function body into calling code
// `always_inline` is a GCC attribute (not supported in other compilers)
__attribute__ ((always_inline)) inline int32_t add(int32_t x, int32_t y)
{
  return (x+y);
}

Function pragmas provides special instructions to the compiler

#pragma GCC push
#pragma GCC optimize ("O0")
int32_t add(int32_t x, int32_t y)
{
  return (x+y);
}
#pragma GCC pop

// __attribute__(x) is only a GCC compiler keyword, throws error for other compilers
#ifndef (__GNUC__)
#define __attribute__ (x)
#endif

// Causes an error during compilation if code uses these functions
#pragma GCC poison printf sprint fprintf

// Compile a function with a specific architecture
#pragma GCC target ("arch=armv6") -or-
                   ("cpu=cortex-m0plus")

Memory Access Macros

Use preprocessor to define an access method without using hardcoded values

/* 8, 16, & 32 Bit Register Access Macros */
#define HWREG8(x) (*((volatile  uint8_t *)(x)))
#define HWREG16(x) (*((volatile  uint16_t *)(x)))
#define HWREG32(x) (*((volatile  uint32_t *)(x)))

#define TA0CTL (HWREG16(0x40000000))

// Example use of access macro:
TA0CTL = 0x0202;
// is equivalent to the following
volatile uint16_t * ta0_ctrl = (uint16_t*)0x40000000;
*ta0_ctrl = 0x0202;

Register Definition File (msp.h)

/* Timer Peripheral Device Structure Overlay */
typedef struct {
    __IO uint16_t   CTL;
    __IO uint16_t   CTTL[7];
    __IO uint16_t   R;
    __IO uint16_t   CCR[7];
    __IO uint16_t   EX0;
    uint16_t   RESERVED0[6];
    __I uint16_t   IV;
} Timer_A_Type;

/* Define the Base Address of Peripheral Regions */
#define PERIPH_BASE ((uint32_t)0x40000000)
#define TIMER_A0_BASE (PERIPH_BASE + 0x00000000)

/* Multiple Timer Modules, Differenct Addresses */
#define TIMER_A0 ((Timer_A_Type*)TIMER_A0_BASE)
// ...

Build manually can be tedious

Manually compiling each file and link is NOT scalable for large software proejcts or large teams

Cross Compiler toolchain

name   description
arm-none-eabi-as bin utils compile ARM VB program
arm-none-eabi-ar bin utils combine multiple .o file into one .o or .a file
arm-none-eabi-ranlib bin utils establish index for lib file
arm-none-eabi-ld bin utils Linker, link multiple .o file to lib file or exec file
arm-none-eabi-objdump bin utils view .o file or .a information
arm-none-eabi-objcopy bin utils tranform executable format
arm-none-eabi-strip bin utils remove elf info from exectuable file
arm-none-eabi-readelf bin utils read elf info
arm-none-eabi-gcc gcc compile C Program or VB Program start with .c or .S
arm-none-eabi-g++ gcc compile c++ program
#******************************************************************************
# Copyright (C) 2017 by Alex Fosdick - University of Colorado
#
# Redistribution, modification or use of this software in source or binary
# forms is permitted as long as the files maintain this copyright. Users are 
# permitted to modify this and use it to learn about the field of embedded
# software. Alex Fosdick and the University of Colorado are not liable for any
# misuse of this material. 
#
#*****************************************************************************

#------------------------------------------------------------------------------
# Simple makefile for the cortex-M0+ build system
#
# Use: make [TARGET] [OVERRIDES]
#
# Build Targets:
#      <FILE>.o - Builds <FILE>.o object file
#      build - Builds and links all source files
#      all - Same as build
#      clean - removes all generated files
#
# Overrides:
#      CPU - ARM Cortex Architecture (cortex-m0plus, cortex-m4)
#      ARCH - ARM Architecture (arm, thumb)
#      SPECS - Specs file to give the linker (nosys.specs, nano.specs)
#
#
#------------------------------------------------------------------------------
include sources.mk

# Architecture Specific Flags
CPU = cortex-m0plus
ARCH = thumb
SPECS = nosys.specs

# Platform Specific Flags
LINKER_FILE = MKL25Z128xxx4_flash.ld 

# Compile Defines
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
TARGET = demo
LDFLAGS = -Wl,-Map=$(TARGET).map -T $(LINKER_FILE)
CFLAGS = -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS) -Wall

OBJS = $(SRCS:.c=.o)

%.o : %.c
	$(CC) -c $< $(CFLAGS) -o $@

.PHONY: build
build: all

.PHONY: all
all: $(TARGET).out

$(TARGET).out: $(OBJS)
	$(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) -o $@

.PHONY: clean
clean:
	rm -f $(OBJS) $(TARGET).out $(TARGET).map
# Cross-Compiler Example Commands
# make [TARGET] [OVERRIDES]
arm-none-eabi-size -Btd demo.out main.o my_file.o
arm-none-eabi-size -Bx demo.out
arm-none-eabi-size -Ad demo.out
arm-none-eabi-size demo.out

# This will stop at the preprocessing step for the ARM Cortex-M4 processor
arm-none-eabi-gcc -mcpu=cortex-m4 -std=c99 -Werror -E main.c -o main.i

# This will compile but stop before linking and output the code in assembly in a
# file called "main.s".
arm-none-eabi-gcc -std=c99 -Wall -S main.c

# Compile but stop before linking and outputs main.s assembly code It will
# include debug symbols. Compare this main.s with the previous main.s
arm-none-eabi-gcc -g -std=c99 -Wall -S main.c

# This will compile and link main.c with specific architecture and libraries that
# are needed for the target processor to run.
arm-none-eabi-gcc --specs=nosys.specs -mcpu=cortex-m4 -mthumb -std=c99
             -Wall -march=armv7e-m main.c

# To compile in a linker file with the ARM cross compiler and generate a map file
arm-none-eabi-gcc -o main.out main.c my_file.c -Wl,-T msp432p401r.lds -Wl,-Map=main.map --specs=nosys.specs
# Dumping compiled object code back to assembly

#  Decoding the parts of the elf file, since the ELF format is not human readable, 
# we can use the readelf command to provide data on the compiled and linked executable file
arm-none-eabi-readelf demo.out -all

# Dumping compiled object code back to assembly
make my_file.o
arm-none-eabi-objdump --disassemble my_file.o > my_file.dump

# This will make for the target processor and then dump the compiled executable
# to assembly in the demo.dump file
make all
arm-none-eabi-objdump --disassemble demo > demo.dump

# Converting your executable to other formats (SREC and IHEX)

# This will dump the executable output from make (a elf little endian format) 
# into an intel hex record format
arm-none-eabi-objcopy -O ihex demo demo.hex

# This will dump the executable output from make (a elf little endian format) 
# into a Motorola S-record format
arm-none-eabi-objcopy -O srec demo demo.s19

Search Path

# the default search directory list for your version of CPP by invoking it with the -v option
cpp -v /dev/null -o /dev/null

### Header files install
#  install the kernel header files for the currently running kernel
sudo apt-get install linux-headers-$(uname -r)

# ubuntu specific
sudo apt-get install linux-headers-generic
Using built-in specs.
COLLECT_GCC=cpp
Target: aarch64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=aarch64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-checking=release --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu
Thread model: posix
gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 
COLLECT_GCC_OPTIONS='-E' '-v' '-o' '/dev/null' '-mlittle-endian' '-mabi=lp64'
 /usr/lib/gcc/aarch64-linux-gnu/7/cc1 -E -quiet -v -imultiarch aarch64-linux-gnu /dev/null -o /dev/null -mlittle-endian -mabi=lp64 -fstack-protector-strong -Wformat -Wformat-security
ignoring nonexistent directory "/usr/local/include/aarch64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/7/../../../../aarch64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/aarch64-linux-gnu/7/include
 /usr/local/include
 /usr/lib/gcc/aarch64-linux-gnu/7/include-fixed
 /usr/include/aarch64-linux-gnu
 /usr/include
End of search list.
COMPILER_PATH=/usr/lib/gcc/aarch64-linux-gnu/7/:/usr/lib/gcc/aarch64-linux-gnu/7/:/usr/lib/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/7/:/usr/lib/gcc/aarch64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/aarch64-linux-gnu/7/:/usr/lib/gcc/aarch64-linux-gnu/7/../../../aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/7/../../../../lib/:/lib/aarch64-linux-gnu/:/lib/../lib/:/usr/lib/aarch64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/aarch64-linux-gnu/7/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-E' '-v' '-o' '/dev/null' '-mlittle-endian' '-mabi=lp64'

GNU Binary Utilites

how to make cross compiler

GNU Compiler Collection and Make

Make is an executable generatin gapplication provided by GNU, it is spearate from the GCC toolchain

Name Symbol ARM executable
Assembler as arm-none-eabi-as
Compiler gcc arm-none-eabi-gcc
Linker ld arm-none-eabi-ld
Make make make

Makefile Syntax

Special Variables used by make
# This is a comment

# This includes another file
include sources.mk

# Variables & Line Continuance
FLAGS = -g    \
        -Werror \
        -std=c99

# Recursively Expanded variables, exapnds whenever used
CSTD=c89
CPU=cortex-m0plus
CC=arm-none-eabi-gcc
SPECS=nosys.specs

# Simply Expanded variables, expands once at the time of definition
ARCH:=$(shell arch)
CWD:=$(shell pwd)
OS:=$(shell uname)
PLATFORM_FLAGS:=-m$(ARCH)   \
                -mcpu=$(CPU) \
                --specs=$(SPECS)

# Compiler flags -> CFLAGS
CFLAGS= -g -std=$(CSTD) -mcpu=${CPU} -mthumb
# Linker flags -> LDFLAGS

# control what directories and source files are used for building
INCLUDES=     \
  -I ./libs   \
  -I ./modem  \
  -I ./uart   \
  -I ./arch

SRCS=         \
  ./main.c    \
  ./memroy.c  \
  ./uart.c    \
  ./data.c

# my_file.o target binary
My_file.o: myfile.h my_file.c
  gcc $(FLAGS) -c -o my_file.o my_file.c

# main.o target binary
main.o: my_file.h
  gcc $(FLAGS) -c -o main.o main.c

# Main Target executable
main.out: main.o my_file.o
  gcc -Wl,map=main.map -I ./inc -o main.out main.o my_file.o

$(TARGET): $(OBJS)
  $(CC) $(CFLAGS) $(INCLUDES) $(LDFLAGS) -o $(TARGET) $(OBJS)

# $@ - Target Rule name
# $^ - All prerequisites
$(TARGET): $(OBJS)
  $(CC) $(CFLAGS) $(INCLUDES) $(LDFLAGS) -o $@ $^

# % - Pattern matching operator
%.o: %.c
  $(CC) -c $< $(CFLAGS) -o $@

# Automatic variables - variables in a recipe with a scope, can use source variables(SRCS) to generate a list of object fiels varibles(OBJS)
OBJS:=$(SRCS:.c=.o) # -> for every *.c files, associate a *.o file with the same name

# Targets do NOT have to be a file, `.phony` protection required to make sure make does not confuse a taget anme with an actual file
# - all: builds final executable binary
# - clean: removes all generated and object files
# - debug: builds a debug image with debug symbols enabled
.PHONY: build
build: all
.PHONY: all
all: main.out
main.out: $(OBJS)
  gcc $(CFLAGS) -o main.out $(OBJS)
.PHONY: clean
clean:
  rm -f main.map $(OBJS) main.out