-
Notifications
You must be signed in to change notification settings - Fork 49
EM Starter Kit
This document describes how to use GNU tools for ARC with EM Starter Kit v2. Almost all of the same comments apply to v1 and v1.1, with only different CPU configurations involved.
Different core templates in EM Starter Kit use different memory maps, and custom linker scripts are required to compile applications that work properly on those templates.
EM5D template has ICCM starting at 0x200 and DCCM at 0x80000000. Linker script and custom crt0.s file can be found in this "toolchain" repository in extras/em_starter_kit directory and can be downloaded directly here. To compile the application use the following command:
$ arc-elf-gcc -mEM -Wl,-Tem5d.lds -nostartfiles crt0.S test.c
EM7 template has ICCM starting at 0x200 address and 128 MiB RAM starting at 0x10000000. Code is loaded into ICCM, while RAM is left for the data sections. Linker script and custom crt0.s file can be found in this "toolchain" repository in extras/em_starter_kit directory and can be downloaded directly here. To compile the application use the following command:
$ arc-elf-gcc -mEM -Wl,-Tem7d.lds -nostartfiles crt0.S test.c
Software installer for Windows can be downloaded here. It includes GNU tools, OpenOCD and Eclipse IDE with required ARC GNU plugins pre-installed.
Toolchain for Linux hosts can be downloaded from the GNU Toolchain Releases page as a prebuilt package.
Starting from 2015.06 release there is a complete tarball for Linux that, like its Windows counterpart includes toolchain, IDE and OpenOCD. Before 2015.06 release there was only a pure toolchain distributable, which included GNU tools only. OpenOCD should be built separately. Documentation is available in OpenOCD GitHub repository.
Start OpenOCD:
# On Linux:
$ openocd -c 'gdb_port 49101' -f /usr/local/share/openocd/scripts/board/snps_em_sk.cfg
@rem on Windows:
> openocd -s C:\arc_gnu\share\openocd\scripts -c 'gdb_server 49101' ^
-f C:\arc_gnu\share\openocd\scripts\board\snps_em_sk.cfg
OpenOCD will be waiting for GDB connections on TCP port specified as an
argument to gdb_server command, in this example it is 49101. When gdb_port
command hasn't been specified, OpenOCD will use its default port, which is
3333, however this port might be already occupied by some other software. In
our experience we had a case, where port 3333 has been occupied, however
no error messages has been printed but OpenOCD and GDB wasn't printing anything
useful as well, instead it was just printing some ambiguous error messages
after timeout. In that case another application was occupying TCP port only on
localhost address, thus OpenOCD was able to start listening on other IP
addresses of system, and it was possible to connect GDB to it using that
another IP address. Thus it is recommended to use TCP ports which are unlikely
to be used by anything, like 49001-49150, which are not assigned to any
application.
OpenOCD can be closed by CTRL+C. It is also possible to start OpenOCD from Eclipse as an external application.
Write a sample application:
/* simple.c */
int main(void) {
int a, b, c;
a = 1;
b = 2;
c = a + b;
return c;
}Compile it (refer to "Building application" section for details):
$ arc-elf-gcc -marcem -Wl,-Tem5d.lds -nostartfiles crt0.S simple.c -o simple.elf
Run GDB, connect to target and run it:
$ arc-elf32-gdb --quiet simple.elf
# connect. Replace 3333 with port of your choice if you changed it when starting OpenOCD
(gdb) target remote :3333
# Increase timeout, because OpenOCD sometimes can be slow
(gdb) set remotetimeout 15
# load application into target
(gdb) load
# Go to start of main function
(gdb) break main
(gdb) continue
# Resume with usual GDB commands
(gdb) step
(gdb) next
# Go to end of the application
(gdb) break _exit_halt
(gdb) continue
(gdb) info reg r0
Execution should stop at function _exit_halt(). Value of register r0 should be 3.
- Out of the box it is impossible to perform any input/output operations, like printf, scanf, file IO, etc. Calling any of those function in application will result in a hang (unhandled system call to be exact). It is possible to use UART for text console I/O operations, consult EM Starter Kit documentation and examples for details.
- Bare metal applications has nowhere to exit, and default implementation of exit is an infinite loop. To catch exit from application you should set breakpoint at function
_exit_halt()like in the example. Note that_exit_halt()is defined incrt0.s.
Both OpenOCD and GDB support big-endian applications and target. No special build of those applications is required to support big-endian, however other parts of toolchain must be build for big-endian. Refer to toolchain readme for details on building big-endian toolchain.
EM Starter Kit doesn't have built-in big-endian configuration, however it is possible to program its FPGA with big-endian image. Consult EM Starter Kit databook for details on FPGA programming. Following steps assume that your FPGA system (either EM Starter Kit, or another) is already flashed with big-endian image.
Build target application:
$ arceb-elf-gcc -mEM -Wl,-Tem5d.lds -nostartfiles crt0.s simple.c
Edit OpenOCD configuration script (EM Starter Kit is assumed):
diff --git a/tcl/target/snps_em_sk_fpga.cfg b/tcl/target/snps_em_sk_fpga.cfg
index 5250e15..e9e9924 100644
--- a/tcl/target/snps_em_sk_fpga.cfg
+++ b/tcl/target/snps_em_sk_fpga.cfg
@@ -17,7 +17,7 @@ set _coreid 0
set _dbgbase [expr 0x00000000 | ($_coreid << 13)]
target create $_TARGETNAME arc32 -chain-position $_TARGETNAME \
- -coreid 0 -dbgbase $_dbgbase -endian little
+ -coreid 0 -dbgbase $_dbgbase -endian big
# There is no SRST, so do a software reset
$_TARGETNAME configure -event reset-assert arc_common_resetSubsequent steps are same as for little-endian targets. Note that there is no real difference between arc-elf32-gdb and arceb-elf32-gdb GDB executables - both can be used for target of any endianness, names differ only for consistency with other toolchain components.