Commit f005b5c7 authored by Mikaël BRIDAY's avatar Mikaël BRIDAY

init

parents
# Makefile related stuff
lab?/build
lab?/*.elf
lab?/*.elf.bin
lab?/*.elf.map
# CMake+QtCreator related stuff
lab?/CMakeLists.txt.user
build-lab*
#pdfpc tmp file.
lecture/micro.pdfpc
# LaTeX
*.aux
*.log
*.fdb_latexmk
*.fls
*.out
# Vim
.*.swp
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# Setting up programming environment
This project contains the practical work for the MICRO course.
This file contains important information about the configuration of the host computer,
and some basics on the C compiler suite usage.
The target is a ST Nucleo32 board STM32F303K8. We assume that the host computer is either a Linux (tested with Ubuntu 18.04) or a Mac computer.
## Required tools
We do not use any IDE, but a C code editor (Vim, Emacs, Gedit, …).
The compilation and flash phases are based on a provided Makefile
The compiler suite is arm-none-eabi-gcc. The debugging is done using directly arm-none-eabi-gdb (or ddd for a GUI).
### Linux
On Linux (Debian/Ubuntu flavor), you should install:
* `build-essential`
* `gcc-arm-none-eabi`
* `gdb-arm-none-eabi` (to debug)
* [st-link](https://github.com/texane/stlink)
First the essential build tools:
```sh
sudo apt-get install build-essential
```
Ubuntu provides a compiler version, but no more the associated debugger! The best way is to use [the one provided by ARM](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads).
The archive may be decompressed, and the environment variable PATH should be updated (here if the archive has been decompressed to `/path/to/gcc-arm`):
```sh
export PATH=/path/to/gcc-arm/bin:$PATH
```
This environment variable should be defined each time a terminal is opened, so you can add it in the file `~/.bashrc`, which is a script that is executed each time a terminal is opened on Linux.
### Mac OS
On Mac, XCode should be installed, with the command line tools. You should agree the license in terminal (it has already been done on computers of the lab):
```sh
sudo xcodebuild -license
```
You can [download the compiler here.](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads).
The ST-Link tool (communication between the debugger gdb and the target) [can be found here](https://github.com/texane/stlink).
The archive of both the compiler and stlink may be decompressed, and the environment variable PATH should be updated (here if the archive has been decompressed to `/path/to/gcc-arm`):
```sh
export PATH=/path/to/gcc-arm/bin:$PATH
export PATH=/path/to/stlink/bin:$PATH
```
This environment variable should be defined each time a terminal is opened, so you can add it in the file `~/.profile`, which is a script that is executed each time a terminal is opened on Mac.
## Compile/Run
### Compile
To compile, just use the makefile:
```sh
make
```
### Flash
To flash the application (st-link should be installed first):
```sh
make flash
```
### Debug
to debug the application (using gdb), first run `st-util` in another terminal, and run:
```sh
arm-none-eabi-gdb -tui test.elf
```
a gdb script is provided to initiate communication with target, load the application and run until main. You just hae to call the init script inside gdb:
```gdb
source init.gdb
```
see file [gdb.md](./gdb.md) to have basic command to start debug your application!
### Clean
To remove generated files (obj/exec):
```sh
make flash
```
# Start debugging with GDB
## Introduction
The [GNU GDB debugger](https://www.gnu.org/software/gdb/) is the tool used to interact with the micro-controller on the board.
For low-level operations, it uses the ST-Link tool, dedicated to ST microcontrollers.
You can easily find documentation for GDB, from simple [cheat sheets](https://darkdust.net/files/GDB%20Cheat%20Sheet.pdf), [more extended doc](http://www.yolinux.com/TUTORIALS/GDB-Commands.html), and obviously the [official documentation](https://sourceware.org/gdb/current/onlinedocs/gdb/).
You have to plug your development board, and start in a terminal `st-util`
```sh
$ st-util
st-util 1.4.0
2018-11-23T17:08:25 INFO src/common.c: Loading device parameters....
2018-11-23T17:08:25 INFO src/common.c: Device connected is: F334 device, id 0x10016438
2018-11-23T17:08:25 INFO src/common.c: SRAM size: 0x3000 bytes (12 KiB), Flash: 0x10000 bytes (64 KiB) in pages of 2048 bytes
2018-11-23T17:08:25 INFO src/gdbserver/gdb-server.c: Chip ID is 00000438, Core ID is 2ba01477.
2018-11-23T17:08:25 INFO src/gdbserver/gdb-server.c: Listening at *:4242...
```
The `st-util` tool communicates with the GDB debugger through a socket (port 4242 in this case).
## Basic usage
### Start GDB
To start with the `text user interface` (tui), which is easier to start, with the binary file `test.elf`:
```sh
arm-none-eabi-gdb -tui test.elf
```
#### Startup
A gdb script is provided to initiate communication with the target, load the binary file and run until main. The content of the script is:
```
#start st-util from another terminal before running gdb:
#arm-none-eabi-gdb -tui test.elf
tar extended-remote :4242
load
break main
#continue (until main)
c
```
To execute this script, we just use the command in the gdb prompt:
```
source init.gdb
```
#### Layout
* `layout src`: same as the `-tui` CLI argument. Display src
* `layout asm`: display assembly
The text window is split in 2 parts, the source code file, and the command file. Most useful shortcuts are:
* Ctrl+X O //toggle focus between the 2 windows.
* Ctrl+X 2 //layout with 3 parts, including asm
### Run/stop
Basic commands are:
* `c` (continue) resumes the execution.
* `s` (step) - execute one instruction, **step into** function
* `n` (next) - execute one line, **step over** functions.
The execution can be stopped with `Ctrl+C`.
### Breakpoints
#### declare breakpoint
You can insert a breakpoint using the source code location, or the memory address:
```
b *0x8000502
```
insert a breakpoint at line 26 in file `test.c`:
```
b test.c:26
```
Insert a breakpoint at line 6 of the current C file:
```
b 6
```
#### list breakpoints
```
info breakpoints
```
#### Remove breakpoint
Remove breakpoint 1 (the id is given from the previous command)
```
delete 1
```
delete all breakpoints
```
delete
```
### Variables
#### View
Following commands can be used either with `print` (show one time) or `display` (show each time the program is stopped):
Print a variable one time (`/x` => hexadecimal display)
```
print/x i
```
Or from an address:
```
print/x *0x80004d8
```
Access to a structure (as in C):
```
print/x tim->CNT
```
Examine memory: `4` units, `x` => hexa, `w` => unit is word (4 bytes)
```
x/4xw *0x20002ff8
```
or (get the 4 words above the stack pointer)
```
x/4xw $sp
```
Get the value of the General Purpose Registers (GPR)
```
info registers
```
### Special case for the STM32 peripherals
the peripheral address is computed by the preprocessor from different `#define` commands. To get an access with gdb, we have to declare it in the C file:
```c
volatile GPIO_TypeDef * __attribute__((unused)) gpioa=GPIOA;
```
then, the access is easy in GDB:
```
print/x gpioa->MODER
```
### Update
We use the `set` keyword, example:
```
set gpioa->MODER = gpioa->MODER | 0xa0
```
#to compile the project:
# mkdir _build
# cd _build
# cmake -D CMAKE_TOOLCHAIN_FILE=../../sys/cmake/arm-none-eabi.cmake ..
# make
# make flash
cmake_minimum_required(VERSION 3.5)
#project name
project(lab1)
#application sources
set(SRCS
${CMAKE_SOURCE_DIR}/main.c
)
include("../sys/cmake/coroLabs.cmake")
EXEC=test.elf
C_SRCS = main.c
CPP_SRCS =
ASM_SRCS =
SYSTEM_SRCS += ../sys/startup_ARMCM4.c
SYSTEM_SRCS += ../sys/startup_clock.c
C_SRCS += $(SYSTEM_SRCS)
#particular config:
OPTIM=0 #set to 1 to enable C compiler optimizations
USE_TFT=0 #set to 1 to compile tft related files
CFLAGS= #flags to the C compiler
CPPFLAGS= #flags to the C++ compiler
COMMONFLAGS= #common flags to C (CFLAGS) and C++ (CPPFLAGS)
LDFLAGS = #flags to the linker
EXTRA_FILES_CLEAN= $(EXEC) $(EXEC).bin $(EXEC).map
########################################################
#system files
########################################################
#C++ cross compiler
CXX=arm-none-eabi-g++
#C cross compiler
CC=arm-none-eabi-gcc
########################################################
#TFT lib
########################################################
TFT_LIB_DIR = ../lib/tft/
TFT_CPP_SRCS = Print.cpp Adafruit_GFX.cpp Adafruit_SPITFT.cpp Adafruit_ST7735.cpp Adafruit_ST77xx.cpp tft.cpp
TFT_INC += -I$(TFT_LIB_DIR)
TFT_INC += -I$(TFT_LIB_DIR)/Adafruit-GFX-Library
TFT_INC += -I$(TFT_LIB_DIR)/Adafruit-GFX-Library/Fonts
TFT_INC += -I$(TFT_LIB_DIR)/Adafruit-ST7735-Library
TFT_INC += -I$(TFT_LIB_DIR)/arduinoCore
#also requires lib dir for spi.c/h
TFT_C_SRCS += spi.c
ifeq ($(strip $(USE_TFT)),1)
C_SRCS += $(TFT_C_SRCS)
CPP_SRCS += $(TFT_CPP_SRCS)
COMMONFLAGS += $(TFT_INC)
endif
########################################################
# STM32F303 specific flags
########################################################
CMSIS_DIR = ../sys/CMSIS
LIB_DIR = ../lib
COMMONFLAGS += -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DSTM32F303x8 -DARMCM4
COMMONFLAGS += -I$(CMSIS_DIR)/Device/ST/STM32F3xx/Include
COMMONFLAGS += -I$(CMSIS_DIR)/Include
COMMONFLAGS += -I$(LIB_DIR)
CFLAGS += -fstack-usage -ffunction-sections #TODO: a regarder plus en detail.
CFLAGS += -std=gnu99
CFLAGS += $(COMMONFLAGS)
CPPFLAGS += $(COMMONFLAGS)
LDFLAGS += -mthumb -mcpu=cortex-m4 -T../sys/stm32f303K8.ld -mfloat-abi=hard -mfpu=fpv4-sp-d16 --specs=nosys.specs -lm
LDFLAGS += -Wl,--start-group -lm -Wl,--end-group -Wl,--gc-sections
LDFLAGS += -Lsys
LDFLAGS += -Xlinker -Map=$(EXEC).map
ALL: OBJ_DIR_CREATE $(EXEC)
#########################################################
## flash
#########################################################
##extra rules (flash)
$(EXEC).bin: $(EXEC)
arm-none-eabi-objcopy -O binary $(EXEC) $(EXEC).bin
flash: OBJ_DIR_CREATE $(EXEC).bin
@st-flash --reset write $(EXEC).bin 0x8000000
########################################################
# compiler optimisation
########################################################
COMMONFLAGS_DEBUG = -O0 -g -Wall -fexceptions -Wno-deprecated -DDEBUG
COMMONFLAGS_OPTIM = -O3 -funroll-loops -fomit-frame-pointer -fno-strict-aliasing -pipe -ffast-math -fexceptions
ifeq ($(strip $(OPTIM)),1)
CFLAGS += $(COMMONFLAGS_OPTIM)
CPPFLAGS += $(COMMONFLAGS_OPTIM)
msg += "with optimizations "
else
CFLAGS += $(COMMONFLAGS_DEBUG)
CPPFLAGS += $(COMMONFLAGS_DEBUG)
msg += "without optimizations "
endif
########################################################
OBJ_DIR = build
C_SRCS_NODIR = $(notdir $(C_SRCS))
CPP_SRCS_NODIR = $(notdir $(CPP_SRCS))
ASM_SRCS_NODIR = $(notdir $(ASM_SRCS))
OBJ = $(addprefix $(OBJ_DIR)/,$(CPP_SRCS_NODIR:.cpp=.o))
OBJ += $(addprefix $(OBJ_DIR)/,$(C_SRCS_NODIR:.c=.o))
OBJ += $(addprefix $(OBJ_DIR)/,$(ASM_SRCS_NODIR:.S=.o))
DEPFILES = $(addprefix $(OBJ_DIR)/,$(CPP_SRCS_NODIR:.cpp=.dep))
DEPFILES += $(addprefix $(OBJ_DIR)/,$(C_SRCS_NODIR:.c=.dep))
.PHONY: ALL
#ALL: OBJ_DIR_CREATE $(EXEC)
########################################################
.PHONY: clean OBJ_DIR_CREATE
clean:
@rm -rf $(OBJ_DIR) *~ $(EXTRA_FILES_CLEAN)
$(EXEC): $(OBJ)
@echo linking.. $(EXEC)
@$(CXX) -o $@ $(OBJ) $(LDFLAGS)
$(OBJ_DIR)/%.o: ../sys/%.c
@echo c compiling $(msg)$< ...
@$(CC) -MD -MF $(OBJ_DIR)/$(notdir $<).dep -c $(CFLAGS) $< -o $@
$(OBJ_DIR)/%.o: $(TFT_LIB_DIR)/Adafruit-ST7735-Library/%.cpp
@echo c++ compiling $(msg)$< ...
@$(CXX) -MD -MF $(OBJ_DIR)/$(notdir $<).dep -c $(CPPFLAGS) $< -o $@
$(OBJ_DIR)/%.o: $(TFT_LIB_DIR)/Adafruit-GFX-Library/%.cpp
@echo c++ compiling $(msg)$< ...
@$(CXX) -MD -MF $(OBJ_DIR)/$(notdir $<).dep -c $(CPPFLAGS) $< -o $@
$(OBJ_DIR)/%.o: $(TFT_LIB_DIR)/arduinoCore/%.cpp
@echo c++ compiling $(msg)$< ...
@$(CXX) -MD -MF $(OBJ_DIR)/$(notdir $<).dep -c $(CPPFLAGS) $< -o $@
$(OBJ_DIR)/%.o: $(TFT_LIB_DIR)/%.cpp
@echo c++ compiling $(msg)$< ...
@$(CXX) -MD -MF $(OBJ_DIR)/$(notdir $<).dep -c $(CPPFLAGS) $< -o $@
$(OBJ_DIR)/%.o: $(LIB_DIR)/%.c
@echo c compiling $(msg)$< ...
@$(CC) -MD -MF $(OBJ_DIR)/$(notdir $<).dep -c $(CFLAGS) $< -o $@
$(OBJ_DIR)/%.o: %.c
@echo c compiling $(msg)$< ...
@$(CC) -MD -MF $(OBJ_DIR)/$<.dep -c $(CFLAGS) $< -o $@
$(OBJ_DIR)/%.o: %.cpp
@echo c++ compiling $(msg)$< ...
@$(CXX) -MD -MF $(OBJ_DIR)/$<.dep -c $(CPPFLAGS) $< -o $@
OBJ_DIR_CREATE:
@if [ ! -d $(OBJ_DIR) ]; then mkdir $(OBJ_DIR); fi;
#include dependancy files.
$(foreach source,$(SRC_NODIR),$(eval -include $(OBJ_DIR)/${source}.dep))
# vim:ft=make
#start st-util from another terminal before running gdb:
#arm-none-eabi-gdb -tui test.elf
tar extended-remote :4242
load
break main
#include "stm32f3xx.h"
void wait() {
volatile int i = 0;
for (i = 0; i < 200; i++)
;
}
void setup() {
RCC->AHBENR |= RCC_AHBENR_GPIOCEN_Msk; // clock for GPIOB
__asm("nop"); // wait until GPIOB clock is Ok.
GPIOC->MODER = 1 << (3 * 2); // PB3 output
}
/* main function */
int main(void) {
setup();
/* Infinite loop */
while (1) {
/* Add application code here */
GPIOC->ODR |= 1 << 3;
// GPIOC->BSRR = 1 << 3; // bit set
// wait();
// GPIOC->BSRR = 1 << (3 + 16); // bit reset
GPIOC->ODR &= ~(1 << 3); // bit reset
// wait();
}
}
#to compile the project:
# mkdir _build
# cd _build
# cmake -D CMAKE_TOOLCHAIN_FILE=../../sys/cmake/arm-none-eabi.cmake ..
# make
# make flash
cmake_minimum_required(VERSION 3.5)
#project name
project(lab2)
#application sources
set(SRCS
${CMAKE_SOURCE_DIR}/main.c
)
include("../sys/cmake/coroLabs.cmake")
EXEC=test.elf
C_SRCS = main.c pinAccess.c
CPP_SRCS =
ASM_SRCS =
SYSTEM_SRCS += ../sys/startup_ARMCM4.c
SYSTEM_SRCS += ../sys/startup_clock.c
C_SRCS += $(SYSTEM_SRCS)
#particular config:
OPTIM=0 #set to 1 to enable C compiler optimizations
USE_TFT=0 #set to 1 to compile tft related files
CFLAGS= #flags to the C compiler
CPPFLAGS= #flags to the C++ compiler
COMMONFLAGS= #common flags to C (CFLAGS) and C++ (CPPFLAGS)
LDFLAGS = #flags to the linker
EXTRA_FILES_CLEAN= $(EXEC) $(EXEC).bin $(EXEC).map
########################################################
#system files
########################################################
#C++ cross compiler