1 Introduction
Alessandro Rocchegiani released some interesting projects on STM32 series MCUs. This article introduces the adding support to be built and burned under Linux, with the project STM32F429 Discovery Sega Master System Emulator as an example.
2 ARM Toolchain, Cross Compiler
If the host is a Debian or Ubuntu distribution, the GNU ARM toolchain package is available. To install it:
(option) Hackers like you may also love the funniest way, to build your own toolchain:
% sudo apt-get install gcc-arm-none-eabiOr (option) please download the prebuilt package, unpack it to wherever you like, and configure the path accordingly.
% export PATH=$HOME/ARM-toolchain/gcc-arm-none-eabi-4_8-2013q4/bin;$PATHAlternately (option) you can also use toolchain that is preferred: Mentor Graphics Sourcery CodeBench , DENX ELDK.
(option) Hackers like you may also love the funniest way, to build your own toolchain:
3 Flash Tools
We are going to use either stlink or openocd to burn our images to STM32F4 flash. Actually they are not only just flash programming utilities, but also can be used as on-chip debuggers. This article covers the flash programming usage.
3.1 stlink
To install stlink utility.
% git clone https://github.com/texane/stlink.git % cd stlink % ./autogen.sh % ./configure % make % sudo make installTo write the file (hex or bin for example) to a specific address of flash.
% st-flash write <file path> <addr>GUI version is also available (GTK+ development library required). It works similarily to ST Utility.
% ./configure --with-gtk % make % sudo make install % stlink-guiConnect the Discovery board and you are able to choose file to flash to some address.
3.2 OpenOCD (option)
Install the OpenOCD either with APT.
% sudo apt-get install openocdOr (recommented) building from the latest GIT version:
% git clone git://git.code.sf.net/p/openocd/code openocd % cd openocd % ./bootstrap % ./configure --prefix=/usr/local --enable-stlink % make % sudo make installLoad the correct script files.
% openocd -f interface/stlink-v2.cfg -f board/stm32f429discovery.cfg Open On-Chip Debugger 0.8.0-dev-00350-g6c74255 (2014-02-21-16:59) Licensed under GNU GPL v2 For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html Warn : Interface already configured, ignoring Error: already specified hl_layout stlink srst_only separate srst_nogate srst_open_drain connect_deassert_srst Info : This adapter doesn't support configurable speed Info : STLINK v2 JTAG v17 API v2 SWIM v0 VID 0x0483 PID 0x3748 Info : using stlink api v2 Info : Target voltage: 2.864019 Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpointsThen on another terminal, telnet to port 4444, and enter commands in the interactive prompt.
% telnet localhost 4444 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger > init > reset init target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x08005b54 msp: 0x20030000 > flash write_image erase /home/winfred/STM32F429I-Disco_SMS_EMU/smsemu.elf auto erase enabled target state: halted target halted due to breakpoint, current mode: Thread xPSR: 0x61000000 pc: 0x20000042 msp: 0x20030000 wrote 49152 bytes from file /home/winfred/STM32F429I-Disco_SMS_EMU/smsemu.elf in 2.317470s (20.712 KiB/s) > reset runYou can also list down the openocd commands in order and execute them in one shot.
% openocd -f interface/stlink-v2.cfg -f board/stm32f429discovery.cfg -c "init" -c "reset init" -c "flash write_image erase smsemu.elf" -c "reset run" -c "exit"
4 Build the project
Download the project to the same directory of the STM32F429I discovery firmware package.
Click to choose a ROM. Press the user button to start.
% ls STM32F429I-Disco_SMS_EMU/ STM32F429I-Discovery_FW_V1.0.1/ % cd STM32F429-Disco_SMS_EMUModify the main.c:Cartridge according to your ROMs then make to build and program the flash.
% make % make flash % make flash-romThen you are good to play.
Click to choose a ROM. Press the user button to start.
5 Code Snippets
5.1 Makefile
Cortex-M4 implements the ARMv7E-M architecture and it supports Thumb mode only.
CFLAGS = -mcpu=cortex-m4 -march=armv7e-m -mtune=cortex-m4 CFLAGS += -mlittle-endian -mthumb
5.2 startup_stm32f429_439xx.s
Copy the startup file from STM32F429I discovery firmware package and mark the Cortex M3 and VFP out.
% diff -w -u ../STM32F429I-Discovery_FW_V1.0.1/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc_ride7/startup_stm32f429_439xx.s startup_stm32f429_439xx.S --- ../STM32F429I-Discovery_FW_V1.0.1/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc_ride7/startup_stm32f429_439xx.s 2013-11-11 16:21:22.000000000 +0800 +++ startup_stm32f429_439xx.S 2014-03-11 21:24:10.321587756 +0800 @@ -37,1 +37,1 @@ */ .syntax unified - .cpu cortex-m3 - .fpu softvfp + /*.cpu cortex-m3 + .fpu softvfp*/ .thumb .global g_pfnVectors
5.3 CPU_gcc.c
Besides converting CPU_exec() to GCC inline assembly, another option would be to create an assembly file defining the CPU_exec() function able to be called from C. Both work for me. Here the provided source code goes with the iline assembly option.
Modifications are done to be understood and compiled by GCC, including adding IT blocks for Thumb conditional instructions.
syntax adjustments such as not to omit Rd in instructions with logical shift immediate,
defining allocating datas in GAS style,
Register renaming and constant defining in GAS style.
and to correct the label syntax, etc.
Modifications are done to be understood and compiled by GCC, including adding IT blocks for Thumb conditional instructions.
diff --git a/CPU_gcc.c b/CPU_gcc.c index af62852..54ea83f 100644 --- a/CPU_gcc.c +++ b/CPU_gcc.c @@ -230,6 +230,7 @@ int32_t CPU_exec(int32_t cycle,void* cpu) " TST r_acc,#0x80 \n" // CPU Halt State " BEQ cpu_run \n" " ANDS r_acc,r_cyc,#3 \n" // se((cyc & 3)!=0) +" IT ne \n" " SUBNE r_acc,#4 \n" // cyc-=4 " POP {r1-r12,pc} \n" // exit " cpu_run: \n" @@ -543,6 +544,7 @@ int32_t CPU_exec(int32_t cycle,void* cpu) " MOVT r_pc,#0 \n" " LSR r_res,r_op,#3 \n" " CMP r_res,#8 \n" //opcode >= 0x40 ? +" ITT ge \n" " LSRGE r_res,#3 \n" " ORRGE r_res,#8 \n" //res=(opcode/8)|8 " AND r_acc,r_op,#7 \n" ...
diff --git a/CPU_gcc.c b/CPU_gcc.c index 9fdcafe..d0a474b 100644 --- a/CPU_gcc.c +++ b/CPU_gcc.c @@ -1076,5 +1076,5 @@ int32_t CPU_exec(int32_t cycle,void* cpu) " LDRB r_pnt,[r_pnt,r_pc] \n" " ADD r_pc,#1 \n" " MOVT r_pc,#0 \n" -" ORR r_ad,r_pnt,lsl#8 \n" +" ORR r_ad,r_ad,r_pnt,lsl#8 \n" " BX lr \n" // imposta r_acc con (r_ad) e (r_ad+1)
.byte ((MemReg0 - MempntSwitch)/2) .byte ((MemReg1 - MempntSwitch)/2) .byte ((MemReg2 - MempntSwitch)/2)
r_acc .req r0 r_jmp .req r1 r_ad .req r2 ... .equ ofsBC, 0x00 .equ ofsB, 0x00 .equ ofsC, 0x01 ...
diff --git a/CPU_gcc.c b/CPU_gcc.c index d74d679..b1058bb 100644 --- a/CPU_gcc.c +++ b/CPU_gcc.c @@ -588,7 +588,8 @@ int32_t CPU_exec(int32_t cycle,void* cpu) " .hword ((PAD_CB - CB_Prefix_Opcode)/2) \n" // " .hword ((PAD_CB - CB_Prefix_Opcode)/2) \n" // -" PAD_CB BX lr \n" //(DEBUG Safe) +" PAD_CB: \n" +" BX lr \n" //(DEBUG Safe) //*********** // xD Prefix
4 comments:
vinod@vinod:~/STM32F429I-Disco_SMS_EMU$ make
arm-none-eabi-gcc -mcpu=cortex-m4 -march=armv7e-m -mtune=cortex-m4 -mlittle-endian -mthumb -g -std=c99 -Wall -g -std=c99 -O3 -ffast-math -ffunction-sections -fdata-sections -Wl,--gc-sections -fno-common --param max-inline-insns-single=1000 -DSTM32F429_439xx -DVECT_TAB_FLASH -I. -I../STM32F429I-Discovery_FW_V1.0.1/Libraries/CMSIS/Device/ST/STM32F4xx/Include -I../STM32F429I-Discovery_FW_V1.0.1/Libraries/CMSIS/Include -DUSE_STDPERIPH_DRIVER -I../STM32F429I-Discovery_FW_V1.0.1/Libraries/STM32F4xx_StdPeriph_Driver/inc -I../STM32F429I-Discovery_FW_V1.0.1/Utilities/STM32F429I-Discovery -c main.c -o main.o
main.c:16:23: fatal error: stm32f4xx.h: No such file or directory
#include "stm32f4xx.h"
^
compilation terminated.
make: *** [main.o] Error 1
Hi Vinod,
Please download the STM32F429 discovery firmware package and put it under the same folder of the SMS emulator project.
Hi Winfred,
THanks, Now I can build and flash the binary. Also I can see the game selection menu in screen. But I couldn't find the cartridge rom in the folder, so the make flash-rom gives error..
vinod@vinod:~/STM32F429I-Disco_SMS_EMU$ make flash-rom
st-flash write ./SMS-ROM/"Alex Kidd in Miracle World.bin" 0x8080000
2014-07-27T16:30:08 INFO src/stlink-common.c: Loading device parameters....
2014-07-27T16:30:08 INFO src/stlink-common.c: Device connected is: F42x and F43x device, id 0x10036419
2014-07-27T16:30:08 INFO src/stlink-common.c: SRAM size: 0x30000 bytes (192 KiB), Flash: 0x200000 bytes (2048 KiB) in pages of 16384 bytes
open(./SMS-ROM/Alex Kidd in Miracle World.bin) == -1
2014-07-27T16:30:08 ERROR src/stlink-common.c: map_file() == -1
stlink_fwrite_flash() == -1
make: *** [flash-rom] Error 255
vinod@vinod:~/STM32F429I-Disco_SMS_EMU$
Hi Vinod,
The source code does't include any ROMs. Please try to download whatever you like from the internet.
FreeROMS
CoolROM
Post a Comment