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.
- C basic
- Sorting Algorithm
- Network Programming
- Game
- Game: Bank Management System
- Game: Employee Management System
- Game: Library Management System
Compiler Installment
The compiler only needs to be aware the CPU architecture and not the platform architecture of the target embedded device
windows
- Mingw
- Msvc
-
Clang llvm
- Extract
D:\Downloads\winlibs-x86_64-posix-seh-gcc-12.3.0-llvm-16.0.4-mingw-w64msvcrt-11.0.0-r1.zip
toC:\mingw64
- Add path variable
C:\mingw64\bin
to system path - verify
g++ --version
atcmd
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
- gcc
- clang apple
- clang llvm
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)
gcc -I <header direcectory> -o <filename> sourcefile.c
gcc -E -o a.i tmp.c
gcc -o <filename> sourcefile.c
/usr/lib/gcc/i486-linux-gnu/4.4.3/cc1 -o a.s tmp.c
gcc -S
as - o a.o a.s
gcc -c
/usr/lib/gcc/i486-linux-gnu/4.4.3/collect2 -o build a.o+..o
gcc -o
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
sudo apt-get install libncurses5-dev libssl-dev build-essential openssl bison bcflex
sudo apt build-dep linux-image-generic
kernel config
tar -Jxf linux-5.15.tar.xz
cd linux-5.15
make menuconfig
use kylin internal config
cd linux-5.15
cp /boot/config-5.3.0-28-generic .config
make menuconfig
compile
make -j6
option j means use how many process in your pcsudo make modules_install
sudo make install
- restart
cat /proc/version
menuconfig modules
- general setup
- enable loadable module support
- enable the block layer
- Processor type and features
- Power management and ACPI options
- BUS options (PCI etc.)
- Executable file formats
- Networking support
- Device Drivers
- File systems
- Kernel hacking
- Security options
- Cryptographic API
- Virtualization
- Library routines
ARM cross compiler
sudo apt-get install libncurses5-dev gcc-arm-linux-gnueabi build-essential gcc-5-arm-linux-gnueabli git
- linux kernel
- busybox
sudo update-alternatives --install /usr/bin/arm-linux-gnueabi-gcc arm-linux-gnueabi-gcc /usr/bin/arm-linux-gnueabi-gcc-5 5
sudo update-alternatives --install /usr/bin/arm-linux-gnueabi-gcc arm-linux-gnueabi-gcc /usr/bin/arm-linux-gnueabi-gcc-7 7
sudo update-alternatives --config arm-linux-gnueabi-gcc
arm-linux-gnueabi-gcc -v
QEMU v4.1.0
tar xvJf qemu-4.1.0.tar.xz
cd qemu-4.1.0
sudo apt-get install pkg-config
sudo apt-get install libglib2.0-dev
sudo apt-get install libpixman-1-dev
./configure
make
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
- Libraries: Collections of software (precompiled or direct source)
- Modules: Software organization that each module has encapsulated certain functionality within a libray, used to create portable code!
Creating Modules
- Implementation files(*.c): Contains the function definitions or the actual implementation details
- Header files(*.h): Contains the function declearations, macros, & derived data type definitions (struts, enums)
- Header files are the interface, anything you want to give access to, put in header file
- use
#ifndef
as inclue guards, this protects against redundant includes #prama once
also works as include guards, however it’s not PORTABLE!
// 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
- Installed with the program image as part of the executable
- Create using archiver
Shared Libraries: Linked dynamically at runtime with your executable
- Pre-installed onto target device, i.e. stored spearte from the executable code int target machine
- Used for applications with an operating system
- Create with shared flag
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
- Linker files MUST be PLATFORM DEPENDENT!!!
- Linker must know name and path to libray to link with it
- Static libraries get linked at compiled time
- Dynamic libraries(Shared Libraries which is stored at target machine) get linked at runtime
- use
-l
flag to link the shared libraries - Entry and exit points from main function are included in a standard library that is automatically included by the linker
- can stop auto link of standard libs with
-nostdlib
flag - After linking, we have 1 object files, and the symbols between the two are resolved, Relocatable files(Variables and Functions are represented by symbols) are NOT human readable
- After locating, symbols are removed and direct addresses get assigned into the Exectuable file, which are NOT human readable
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
- Code sections to memeory regions map
- Start and Sizes of memory regions
- Access attributes of memory regions
- Report checking for over-allocation
- Entry points of the program
- Describe how the sections in the input files should be mapped into the output file
- Control the memory layout of the output file
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
GNU C Compiler / GNU Compiler Collection (gcc)
- Pre-Process > Compile > Assemble > Link
- Optimizations will alter the implementation of code
- Compilation tracks and maps memory from a program into segments => specified in the Linker file
$ 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
- Attributes can give specific details on how to compile code for Variables/Structures & Structure Members/Functions
- Attributes are NOT part of the C-standard => not portable across compilers
// 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
- Push/Pop - add extra option for compilation
- Optimize - Specify a certain level of optimization block of code
- Implementation/Compiler specific -> Unrecognized pragmas will be ignored
- Gives a specific instruction to the compiler, controls compilation from software instead of command line
#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
- Many GCC flags
- Many independent commands
- Many build targets
- Many supported architectures
- Many source files
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 |
- CFLAGS
-O0
# no optimization-g
# debug
#******************************************************************************
# 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
- 制作交叉的 binutils 二进制工具
- 制作不带库的 gcc 交叉编译器
- 用制作好的 gcc 交叉编译器,生成所需要的 C 库(glibc, newlib, uclibc)
- 重新编译带库的 gcc, 生成完整的交叉编译器
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
- Comments start with a
#
- Can include other makefiles
- Line conintuation is done with a
\
- Can create and use variables
- Can have multiple rules
- Command lines start with a tab
- Targets can depend on other targets
- Each rule in the makefile targets should start with a Tab(
\t
), usecat -e -t -v makefile_name
to verify $@
is an automatic variable that contains the target name.- Make will execute a particular target and recipe either provided at the command line or the default target
Special Variables used by make
CC
CompilerCPP
Preprocessor ProgramAS
Assembler ProgramLD
LinkerCFLAGS
C porgram flagsCPPFLAGS
C preprocessor flagsASFLAGS
Flags for AssemblerLDFLAGS
C program Linker flagsLDLIBS
Extra flags for Libraries
# 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