This repository includes some sub-repositories, therefore don't forget the option "--recursive" if you'll clone this repository.
git clone --recursive https://github.com/UlrichBecker/gsi_scu.git
If you works on the ASL-cluster then add following to the environment variable LD_LIBRARY_PATH if not already done:
export LD_LIBRARY_PATH=/common/usr/cscofe/lib:/common/usr/fesa/lib:$LD_LIBRARY_PATH
/common/usr/cscofe/opt/compiler/lm32Add follows to your environment variable PATH if you works on ASL:
export PATH=/common/usr/cscofe/opt/compiler/lm32/bin:$PATH
REPOSITORY_DIR := $(shell git rev-parse --show-toplevel) include $(REPOSITORY_DIR)/makefiles/makefile.scuAnd for linux applications:
REPOSITORY_DIR := $(shell git rev-parse --show-toplevel) include $(REPOSITORY_DIR)/makefiles/makefile.scunThe pre-build makefiles can be found here.
Prerequisite is that you has changed in a directory which includes a "Makefile".
make
Builds the corresponding binary file.make clean
Deletes the binary file and all build artifacts.make rebuild
Compiles the entire project new doesn't matter a source-file has changed or not.make ldep
Prints the dependencies, that means all source and headder files which are involved at the corresponding project.make lsrc
Prints all source code files belonging to the current project.make incdirs
Prints all include directories belonging to the current project.make devargs
Prints all definitions of the preprocessor which had been made in the makefile.make doc
Generates a doxygen documentation in HTML of the corresponding project. Don't care about the doxygen configuration file "Doxyfile" this becomes generated automatically by the makefile.make showdoc
Generates a doxygen documentation in HTML of the corresponding project and invokes the firefox-browser.make deldoc
Cleans the complete documentation.make asm
Translates all source code modules in assembler.make objdump
Builds the corresponding .elf
- file and disassemble it.make check
Makes C/C++ code analysis of the current project by the tool cppcheck which is more accuracy as the compilers code analysis.make V=1
Builds the project in the verbosity mode.<your preferred editor> $(make ldep)
Prerequisite is that the environment variable SCU_URL
exist which includes the name of the target-SCU. E.g.: export SCU_URL=scuxl4711
make load
Builds the LM32 binary file and loads it up to the corresponding SCU specified in SCU_URL
.make reset
Makes a CPU-reset of the LM32.make info
Prints the build-ID.For test and debug purposes the variable CALL_ARGS
can set with commandline parameters.
make run
Builds the binary-file and invoke it.make dbg
Builds a debugable binary-file and invokes the KDE-debugger frontend kdbg
if the makefile-variable DEBUG=1
. Yes KDE! That isn't exotic!make public
Builds the binary-file and copy it in the directory /common/usr/cscofe/bin/
REPOSITORY_DIR
This variable is the most important which shall contain the path who this GIT-repository is installed.REPOSITORY_DIR := $(shell git rev-parse --show-toplevel)
include $(REPOSITORY_DIR)/makefiles/makefile.scu
REPOSITORY_DIR := $(shell git rev-parse --show-toplevel)
include $(REPOSITORY_DIR)/makefiles/makefile.scun
MIAN_MODULE
By default the name of the sourcefile which contains the function main()
this is also the name of the binary file. E.g.:MIAN_MODULE = scu_control_os.c
SOURCE
List of additional source files, which can be C-, cplusplus- or assembler- files. E.g.:SOURCE += mprintf.c
SOURCE +
scu_task_daq.c
DEFINES += CONFIG_USE_TEMPERATURE_WATCHER
DEFINES +
MAX_LM32_INTERRUPTS=2INCLUDE_DIRS
List of additional directories of header files. E.g.:INCLUDE_DIRS +
$(RTOS_SRC_DIR)/includeCFLAGS
Compiler flags. E.g.:CFLAGS += -Wall
CFLAGS +
-Wfatal-errorsLD_FLAGS
Linker flags. E.g.:LD_FLAGS +
-Wl,--gc-sectionsCODE_OPTIMIZATION
Code optimization level. E.g.:CODE_OPTIMIZATION = s
NO_LTO
By default the link time optimizer is active. If this is not desired then this variable has to be initialized by one. E.g.:NO_LTO = 1
SCU_URL
Name of the developer-SCU. E.g.:SCU_URL = scuxl4711.acc.gsi.de
USRCPUCLK
CPU-clock in kHz. by default its 125000.RAM_SIZE
Size of LM32-RAM in bytes. By default on SCU3: 147456 bytes.USE_RTOS
The base source files of FreeRTOS will added to the project.RTOS_USING_HEAP
Number of heap-model for FreeRTOS, this can be 1, 2, 3, 4 or 5. By default the heap-model 1 will used.LIBS
List of additional libraries. E.g.:LIBS +
stdc++LIB_DIRS
Path to additional libraries.IS_LIBRARY
Binary will build as library if its value is 1.STATIC_LIBRARY
Binary will build as static-library if its value is 1.FOR_SCU
Binary shall run on SCU only.FOR_SCU_AND_ACC
Binary can run on SCU and ASL-cluster.DEBUG
Binary will build with debug-infos. In this case the code optimization is 0, doesn't matter how the value of CODE_OPTIMIZATION
is. And the target make dbg
becomes active.CALL_ARGS
List of command line parameters for binary to test. This variable will used by the target make run
and make dbg
.In this example you can see how the makefile has to look for a simple LM32 application.
Makefile:
MIAN_MODULE := hello_lm32_world.c SOURCE += $(SCU_LIB_SRC_LM32_DIR)/scu_std_init.c # Initializes the most important wishbone devices, this will be done by the startup code before the function main() is called. # NO_LTO := 1 CODE_OPTIMIZATION = s REPOSITORY_DIR := $(shell git rev-parse --show-toplevel) include $(REPOSITORY_DIR)/makefiles/makefile.scu
Sourcecode "hello_lm32_world.c" will print the text Hello world!" on the eb-console:
#include <mprintf.h> #include <stdbool.h> void main( void ) { mprintf( "Hello world!\n" ); while( true ); }
gsi_scu/demo-and-test/lm32/non-os/Hello_World
make
.gsi_scu/demo-and-test/lm32/non-os/Hello_World/deploy_lm32/result/Hello_World.bin
SCU_URL
specified so you can upload the binary-file by typing make load
. Of course it is possible to define the variable SCU_URL
in the makefile as well, this will overwrite a possible environment variable. In the directory gsi_scu/demo-and-test/lm32/
you can find further examples for LM32 with and without using FreeRTOS. Note: For LM32-applications using FreeRTOS the variable USE_RTOS
has to be defined in the makefile. In this manner the source files of FreeRTOS will added automatically to the project and the startup code crt0ScuLm32.S
becomes correct customized: USE_RTOS = 1.
Further the heap-model using by FreeRTOS has to be choose by the makefile variable RTOS_USING_HEAP
. E.g.: RTOS_USING_HEAP = 4. For more information about FreeRTOS read the topic "FreeRTOS especially for the LM32 of the GSI-SCU".lm32-logd -B scuxl4711(Note: The SCU-name can be omitted when the log-daemon becomes invoked on the concerning SCU, e.g. login via sss, and not on the ASL-cluster.) leads to following output:
UserLM32 Project : scu3_control_os Version : 4.6.3 * +MIL-DDR3 +LOG +DAQ +DIOB-DAQ +AFGT +MMU Git-revision: e176c65 (2023-12-14 15:39:16 +0100) Platform : SCU 3 Build Date : Mo Dez 18 16:05:48 CET 2023 Prepared by : ulrich <> Prepared on : sadpc029 OS Version : Linux 5.14.21-150500.55.39-default x86_64 Embedded OS : FreeRTOS Kernel: V10.4.6 Tick-frequ. : 10000 Hz GCC Version : lm32-elf-gcc (GSI) 13.1.0 Opt. level : s, LTO: Yes Log param : 8 IntAdrOffs : 0x10000000 SharedOffs : 0x500 SharedSize : 24832 StackSize : 512
Name (Key) | Meaning (Value) | Comment |
---|---|---|
Project | Name of the LM32 firmware binary file which has been uploaded. (firmware name) | |
Version | Version number of the firmware | |
Git-revision | Git commit ID and commit date | |
Platform | Device name where the LM32 is implemented e.g. SCU 3 or SCU 4 | |
Build Date | Build date of this firmware | |
Prepared by | Username which has built this firmware | |
Prepsred on | PC name on which has build this firmware | |
OS Version | Version of the OS-kernel in the build PC. | |
Embedded OS | Version of the FreeRTOS kernel | Only if FreeRTOS implemented. |
Tick-frequ. | Task change frequency in Hz. | Only if FreeRTOS implemented. |
GCC Version | Version of the LM32 cross compiler | |
Opt. level | Optimization level in which has the crosscompiler built the firmware. | |
Log param | Number of optional log parameters, e.g.: "%d, %s" and so on... | |
IntAdrOffs | Offset of the LM32 working memory. | |
SharedOffs | Relative offset of the shared memory in the working memory. | |
SharedSize | Length of the shared memory section. | |
StackSize | Length of te stack section. |
lm32-logd -B scuxl4711 | grep "Version :" | awk '{print $3}'Or its also possible to read the version number of the firmware directly from the binary file by typing that:
strings <filename of LM32-firmware>.bin | grep "Version :" | awk '{print $3}'
Makefile command (target) | Meaning |
---|---|
make doc | Creates the whole source code documentation of the concerned project. |
make showdoc | Creates the whole source code documentation of the concerned project and invokes the Firefox browser. |
make deldoc | Deletes all by doxygen created files. |
DOX_OUTPUT_DIRECTORY ?= $(HOME)/Documents/scr_doc/$(TARGET)Whereby the makefile variable TARGET includes the project name. As shown it's possible to overwrite this makefile variable with your desired target folder. Each Doxygen configuration variable which are defined in the Doxyfile has its equivalent in the Makefile with the prefix "DOX_" and can be overwritten. By default they are predefined with a meningful value. An additional older documentation about using of Doxygen written in german by Ludwig Hechler can be found here.
void lm32Log( const unsigned int filter, const char* format, ... ); void vLm32log( const unsigned int filter, const char* format, va_list ap );The source file lm32_syslog.c has to be added to the LM32 project. The syntax of the function "lm32Log()" is similar like the known C-function "printf()" with the different that the first parameter is a filter-value defined in lm32_syslog_common.h which identifies the type of log-message. In contrast to printf() is the number of the optional paraneters (e.g.: %d) limited by 8, further parameters will ignored. Following filter values are already reserved:
Name | Value | Meaning |
---|---|---|
LM32_LOG_ERROR | 0 | Error message |
LM32_LOG_WARNING | 1 | Warning message |
LM32_LOG_INFO | 2 | General information message |
LM32_LOG_CMD | 3 | Command from linux host received |
LM32_LOG_DEBUG | 4 | Debug message respectively trace information |
#include <stdbool.h> #include <lm32_syslog.h> #include <scu_wr_time.h> void main( void ) { /* * Allocates memory in the DDR3 or SRAM for a maximum of * 20 messages. */ lm32LogInit( 20 ); uint64_t triggerTime = 0; unsigned int c = 0; while( true ) { const uint64_t time = getWrSysTime(); if( time < triggerTime ) continue; triggerTime = time + 100000000000; /* * Every second appears a new log-message. */ lm32Log( LM32_LOG_INFO, "Count = %u -> %s", c, (c%2 == 0)? "even": "odd" ); c++; } }A bit more complex example can be found here. The LM32- application allocates memory in the DDR3-RAM on SCU3 or in future in SRAM on SCU4 by the memory-tag TAG_LM32_LOG, definned in
scu_mmu_tag.h
of the SCU- memory management unit (MMU).
The function ln32Log()
copies the WR-timestamp (64-bit), the first parameter (32-bit filter value), the second parameter (32-bit pointer to the control string) and a maximum of 8 additional 32-bit parameters (depending on the control string) into the SCU-RAM, which is organized as fifo.
So a single message item, residing in the SCU-RAM, has a fixed size of twelve 32-bit values respectively a size of six 64-bit values. The following figure shows how a single log-message is organized in the DDR3-RAM of SCU 3 respectively in the future in SRAM of SCU 4:
lm32-logd -hThe sourcefiles of lm32-logd can be found here. Proposal how the LM32-log daemon can be used to write messages in a log-file:
/opt/nfsinit/global/tools/lm32-logd -Habd=/var/log/lm32.log
tail -n100 -f /var/log/lm32.logmakes the log-messages visible in "realtime" similar like the development of linux- kernel drivers.