From cf3f6dfa35af5411b5bc63b379549aa916f831bd Mon Sep 17 00:00:00 2001 From: Yuriy Kolerov Date: Fri, 2 Jun 2023 10:54:36 +0400 Subject: [PATCH] doc: Completely reworked EMSK section * Add links to useful extrenal resources. * Simplified guides. * Fixed a guide for building with support of UART. --- doc/baremetal/em-starter-kit.rst | 206 +++++++++++++++---------------- 1 file changed, 100 insertions(+), 106 deletions(-) diff --git a/doc/baremetal/em-starter-kit.rst b/doc/baremetal/em-starter-kit.rst index b7ad62db..e6e60e59 100644 --- a/doc/baremetal/em-starter-kit.rst +++ b/doc/baremetal/em-starter-kit.rst @@ -6,44 +6,64 @@ Using GNU Toolchain to Debug Applications on EM Starter Kit =========================================================== +To learn how to build and debug application using Eclipse IDE, please use +:doc:`../ide/index` manual. + +You can find all necessary information about configuring the board and +connecting to UART in a User Guide which is published in +`ARC EM Starter Kit section `_ +on ARC Development Systems Forum. + Prerequisites ------------- -Toolchain for Linux and Windows hosts can be downloaded from the `GNU Toolchain -Releases page -`_. -For Linux hosts there is a choice between complete tarballs that include -toolchain, IDE and OpenOCD (like installer for Windows), and tarballs that -include toolchain only. +A toolchain for Linux and Windows hosts can be downloaded from the `GNU Toolchain +Releases page `_. +OpenOCD for debugging applications on hardware boards is shipped with IDE bundle only. +OpenOCD binary (``openocd`` for Linux and ``openocd.exe`` for Windows) resides in ``bin`` directory of IDE. -In order to use OpenOCD on Windows it is required to install appropriate WinUSB drivers, -see :doc:`../ide/how-to-use-openocd-on-windows` for details. +Download and install Digilent Adept `runtime and utilities `_ +to be able to work with EM Starter Kit on Linux. In order to use OpenOCD on Windows it is required to install +appropriate WinUSB drivers, see :doc:`../ide/how-to-use-openocd-on-windows` for details. -Building an application ------------------------ +Building a Simple Application +----------------------------- -To learn how to build and debug application with Eclipse IDE, please use -:doc:`../ide/index` manual. +Consider this simple application (assume that it's saved in ``main.c``): + +.. code-block:: c + + int main() + { + return 0; + } + +Different core templates in EM Starter Kit use different memory maps. +It means that you need to use a special memory map file with ``.x`` extension +to be able to compile and run your application on EM Starter Kit. + +In first, clone `toolchain `_ +repository and look into ``extras/dev_systems`` directory. This directory contains +memory map files for different boards and cores. For example, ``sk2.3_em7d.x`` +is a memory map file for EM7D core of EM Starter Kit 2.3. You need to put that memory map +file to the current directory, rename it to ``memory.x`` and use ``-Wl,-marcv2elfx`` +option while compiling your application. Please refer to :doc:`linker` for more details +about ``memory.x`` files. -Different core templates in EM Starter Kit use different memory maps, so -different memory map files are required to compile applications that work -properly on those configurations. This "toolchain" repository includes memory -maps for all supported EM Starter Kit versions and configurations. They can be -found at -https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/tree/arc-staging/extras/dev_systems -Memory map files in that directory have ``.x`` extension and file to be used -should be renamed to ``memory.x``, because ``arcv2elfx`` linker emulation -doesn't support ability to override that file name. Please refer to -:doc:`linker` for more details about ``memory.x`` files. +That is how we compile the application for EM7D core of EM Starter Kit 2.3:: -For example for EM Starter Kit v2.3 EM7D to build an application:: + cp -a toolchain/extras/dev_systems/sk2.3_em7d.x memory.x + arc-elf32-gcc -g -Wl,-marcv2elfx -specs=nosys.specs -mcpu=em4_dmips main.c -o main.elf - $ cp -a toolchain/extras/dev_systems/sk2.3_em7d.x memory.x - $ arc-elf32-gcc -Wl,-marcv2elfx --specs=nosys.specs -mcpu=em4_dmips -O2 -g \ - test.c -o test.elf +We use ``libnosys`` (``--specs=nosys.specs``) her to force standard IO functions +to do nothing - they will set ``errno = ENOSYS`` and return -1 in most cases. -.. table:: List of compiler flags corresponding to particular CPUs +You need to use correct ``-mcpu`` and other additional options for building your +application for particular board and core. You can find all necessary options +for any EM Starter Kit configuration in this table: + +.. table:: +------+--------+------------------------------------------------------------+ |EM SK | CPU | Flags | @@ -78,41 +98,43 @@ For example for EM Starter Kit v2.3 EM7D to build an application:: | | EM11D | -mcpu=em4_fpuda -mfpu=fpuda_all | +------+--------+------------------------------------------------------------+ +Building an Application With Support of UART +-------------------------------------------- + +Consider this application (assume that it's saved in ``hello.c``): -C library for GNU Toolchain for ARC provides basic support for UART module of EM -Starter Kit, which allows to use standard C function for input and output: -``printf()``, ``scanf()``, etc. Memory map files are also provided for processor -configurations of EM Starter Kit. Both of those features are available via -special "specs" files: ``emsk_em9d.specs`` and ``emsk_em11d.specs`` (there is no -separate file for EM7D of EM Starter Kit, it is identical to EM9D). Usage -example is following:: +.. code-block:: c - $ cat hello_world.c - #include - int main() { - printf("hello world\n"); - return 0; - } + #include - $ arc-elf32-gcc --specs=emsk_em9d.specs -mcpu=em4_dmips hello_world.c + int main() + { + printf("Hello, World!\n"); + return 0; + } -Note that it is still required to specify valid ``-mcpu`` option value - it is -not set by the specs file. +You need to use ``emsk_em9d.specs`` (for EM7D or EM9D) or ``emsk_em11d.specs`` +(for EM11D) specs files instead of ``nosys.specs`` to enable support of UART. +It allows using standard C function for input and output: ``printf()``, ``scanf()``, +etc. +That is how we compile the application for EM7D core of EM Starter Kit 2.3:: + cp -a toolchain/extras/dev_systems/sk2.3_em7d.x memory.x + arc-elf32-gcc -g -Wl,-marcv2elfx -specs=emsk_em9d.specs -mcpu=em4_dmips main.c -o main.elf Running an application with OpenOCD ----------------------------------- +OpenOCD is used for connecting to development boards, running a GDB +server and loading programs to the boards using GDB. + Starting OpenOCD ^^^^^^^^^^^^^^^^ -Parameters of a particular target board are described in the OpenOCD -configuration files. OpenOCD repository from Synopsys already includes several -configuration files made specifically for Synopsys own development platforms: -ARC EM Starter Kit and ARC SDP. Due to differences between different versions -of ARC EM Starter Kit hardware, there are separate configuration files for -different ARC EM Starter Kit versions: +OpenOCD uses configuration files for describing different boards. OpenOCD +is shipped with different configuration files for different EM Starter Kit +versions: * ``snps_em_sk_v1.cfg`` - for ARC EM Starter Kit v1.x. * ``snps_em_sk_v2.1.cfg`` - for ARC EM Starter Kit versions 2.0 and 2.1. @@ -121,66 +143,52 @@ different ARC EM Starter Kit versions: * ``snps_em_sk.cfg`` - this is a configuration for ARC EM Starter Kit 2.0 and 2.1, preserved for compatibility. -Following documentation would assume the usage of the latest ARC EM Starter Kit -version 2.3 which is similar to 2.2. +Assume that EM Starter Kit 2.3 is used. If you've downloaded IDE bundle for +Linux then you can run OpenOCD this way (replace ```` by a path to +the directory of IDE bundle):: -Start OpenOCD:: + /bin/openocd -s /share/openocd/scripts -c 'gdb_port 49101' -f board/snps_em_sk_v2.3.cfg - # On Linux (for manually built OpenOCD): - $ openocd -c 'gdb_port 49101' -f board/snps_em_sk_v2.3.cfg +If you've built and installed OpenOCD manually then you can run OpenOCD this way:: - # On Linux (for prebuilt OpenOCD from IDE package): - $ $ide_dir/bin/openocd -s $ide_dir/share/openocd/scripts \ - -c 'gdb_port 49101' -f board/snps_em_sk_v2.3.cfg + openocd -c 'gdb_port 49101' -f board/snps_em_sk_v2.2.cfg - @rem on Windows: - > openocd -s C:\arc_gnu\share\openocd\scripts -c "gdb_port 49101" ^ - -f board\snps_em_sk_v2.3.cfg +If you've downloaded and installed IDE bundle for Windows then you can run OpenOCD this way: -OpenOCD will be waiting for GDB connections on TCP port specified as an -argument to ``gdb_port`` 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. +.. code-block:: winbatch + openocd -s C:\arc_gnu\share\openocd\scripts -c "gdb_port 49101" -f board\snps_em_sk_v2.3.cfg + +OpenOCD will be waiting for GDB connections on TCP port specified as an +argument to ``gdb_port`` command (49101 in our case). If ``gdb_port`` is not +passed then the default port 3333 is used. It's recommended not to use a default +port since it may be occupied by another application. OpenOCD can be closed by CTRL+C. Connecting GDB to OpenOCD ^^^^^^^^^^^^^^^^^^^^^^^^^ -Write a sample application: +Write a sample application and save it to ``simple.c``: .. code-block:: c - /* simple.c */ - int main(void) { - int a, b, c; - a = 1; - b = 2; - c = a + b; - return c; - } + int main() + { + int a = 1; + int b = 2; + int c = a + b; + return c; + } +Build the application for EM7D core of EM Starter Kit 2.3:: -Compile it - refer to "Building application" section for details, creation of -``memory.x`` is not shown in this example:: + cp -a toolchain/extras/dev_systems/sk2.3_em7d.x memory.x + arc-elf32-gcc -g -Wl,-marcv2elfx -specs=nosys.specs -mcpu=em4_dmips main.c -o main.elf - $ arc-elf32-gcc -Wl,-marcv2elfx --specs=nosys.specs -mcpu=em4_dmips -O2 -g \ - simple.c -o simple_sk2.3_em7d.elf +Start OpenOCD as it described earlier and start GDB, connect to target and run it: -Start GDB, connect to target and run it:: +.. code-block:: text - $ arc-elf32-gdb --quiet simple_sk2.1_em5d.elf + $ arc-elf32-gdb -quiet main.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 @@ -199,25 +207,11 @@ Start GDB, connect to target and run it:: # For example, check exit code of application (gdb) info reg r0 -Execution should stop at function ``exit``. Value of register ``r0`` should be -``3``. - +Execution should stop at function ``exit``. Value of register ``r0`` should be ``3``. Known issues and limitations ---------------------------- -* Out of the box it is impossible to perform any input/output operations, like - printf, scanf, file IO, etc. - - * When using an nSIM hostlink (GCC option ``--specs=nsim.specs``), calling - any of those function in application will result in a hang (unhandled - system call to be exact). - * When using libnosys (``--specs=nosys.specs``), standard IO functions will - simply do nothing - they will set ``errno = ENOSYS`` and return -1 at most. - * It is possible to use UART for text console I/O operations, but that is - not implemented by default in GNU toolchain. 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`` like in the example.