====== Hako Firmware ====== ===== ESX 3XL ===== ==== Hallo World Example ==== Download this as pfd: {{:robots:hako:firmware:hello_world.pdf|Hello World Example}} (29 KB) **Step 1: Install the GNU toolchain**\\ Install the STW TriCore Software Tools by following the wizards instructions. This will install among other things the GNU compiler for TriCore and the Code::Blocks IDE. **Step 2: Open the ESX-3XL "Hello world!" project**\\ Start Code::Blocks and open the ESX-3XL demo project "esx3xl_demo.cbp". This project consists of only one source file whose main program look like this: int main(void) { T_x_sys_system_information tSys; sint32 s32_Error; s32_Error = x_sys_init(&tSys); // init ESX-3XL hardware, this function call is mandatory if (s32_Error == C_NO_ERR) // system init OK? { // init serial interface X_SER_01 (19200, 8N1) s32_Error = x_ser_init(X_SER_01, 19200, X_SER_MODE_8DB_NO_PARITY, 1u, 0u, NULL); // init X_SER_01 TX buffer s32_Error |= x_ser_init_tx_buf(X_SER_01, 100u, 0u, NULL); } if (s32_Error == C_NO_ERR) { x_ser_write_string(X_SER_01, "Hello world!"); x_sys_set_beeper(1000); // set beeper 1000Hz x_sys_delay_us(200000); // do a short beep (0.2 seconds) } else { x_sys_set_beeper(200); // on error: set beeper 200Hz x_sys_delay_us(1000000); // do a long beep (1 second) } x_sys_set_beeper(X_OFF); // switch beeper off while (true) { // main loop... led1_change_color(); // setup LED1 color x_sys_delay_us(10000); // delay 10 milliseconds } } The program starts with a call of x_sys_init, the hardware initialization of the ESX-3XL main board. Each ESX-3XL application should start with this function call. Further hardware initialization may follow when a ESX-3XL controller is equipped with expansion boards. This example program use the serial interface as output and therefore the interface must be initialized and a TX buffer must be prepared. If anything is OK it writes the "Hello world!" string to the interface and beeps a short time. If something wents wrong it does a long beep with a low frequency. Afterwards it changes the color of LED1 in the main infinite loop. **Step 3: Build the project for RAM debugging**\\ To link the application into RAM space we have to use the '**Debug**' build target. Check the setting for the linker command inside "**Project→Build options→Linker tab**" from Code::Blocks main menu: Be sure that the 'Debug' build target project settings are active. It must be selected in the left of the build options dialog. The linker option **-Wl,--script=..\libs\esx3xl_link_debug.ld** should be set in order that the executable output code will be linked into RAM for debugging. This linker command file sets the program start address to **0xA4000000** that is external RAM space. Select the build target '**Debug**' at the botton bar and then build the program with "**Build→Rebuild**" from the Code::Blocks main menu. If all goes well then the ELF file "esx3xl_demo_debug.elf" will be generated inside of the 'output' folder.\\ **Debugging the executable in RAM:**\\ Be sure the debugger hardware is connected and the power supply for the debugger as well as for the ESX-3XL is switched on. Make sure that the **Debug** build target is active in Code::Blocks. Start the TRACE32 debugger from the Code::Blocks 'Tools' menu (see also: chapter "Starting up with TRACE32 debugger"). The TRACE32 program will now be started, the debugger hardware will be initialized, the executable output file will be loaded into the RAM and the program execution will be started until the main function. Now you can step through your program, set breakpoints, watch variables and registers and so on... You can reload the executable output file by typing "**run ram**" in the TRACE32 command line. **Step 4: Build the project to be stored permanently into flash ROM**\\ To link the application into flash ROM space we have to use the '**Release**' build target. Check the setting for the linker command inside "**Project→Build options→Linker tab**" from Code::Blocks main menu: Be sure that the 'Release' build target project settings are active. It must be selected in the left of the build options dialog. The linker option **-Wl,--script=..\libs\esx3xl_link_extflash.ld** should be set in order that the executable output code will be linked into flash ROM for storing permanently. This linker command file sets the program start address to **0xA1040000** that is external flash ROM space. Select the build target '**Release**' at the botton bar and then build the program with "**Build→Rebuild**" from the Code::Blocks main menu. If all goes well then the **ELF file** "esx3xl_demo.elf" will be generated inside of the 'output' folder. Additionally the application will be converted to a so-called **HEX file** "esx3xl_demo.hex". With using the HEX file the application could be loaded into the ESX-3XL controller via CAN bus by using the **WinFlash** tool.\\ **Debugging the executable in flash ROM:**\\ Be sure the debugger hardware is still connected and the power supply for the debugger as well as for the ESX-3XL is switched on. Make sure that the **Release** build target is active in Code::Blocks. Start the TRACE32 debugger from the Code::Blocks tools menu (see also chapter "Starting up with TRACE32 debugger"). The TRACE32 Program will now be started and the debugger script 'flash.cmm' automatically initializes the debugger hardware, enables the debugger for programming flash memories, unlocks and erase flash sectors from address 0xA1040000 up to 0xA107FFFF, loads the executable output file into this flash area and starts program execution until the main function. Now you can step through your program, set breakpoints, watch variables and registers and so on. But debugging inside the flash memory limits the usage of breakpoints. Only two hardware breakpoints are available. You can reload the executable output file by typing "**run flash**" in the TRACE32 command line. **See also:** |Quick start: "Hello world!"| |Floating point arithmetic | |Interrupt handler and callback functions | |Hardware traps | |Stack size analysis| ==== Mainboard - Software - Notation - Types and prefixes ==== * [[robots:hako:firmware:welcome#Recommended unambiguous type definitions and prefixes|Unordered List ItemTypes/prefixes]] * [[robots:hako:firmware:welcome#Type definition (typedef) prefixes|Typedef prefixes]] * [[robots:hako:firmware:welcome#Definition prefixes|Definition prefixes]] * [[robots:hako:firmware:welcome#Modifier prefixes|Modifier refixes]] * [[robots:hako:firmware:welcome#Area of validity prefixes|Validity prefixes]] * [[robots:hako:firmware:welcome#Examples|Examples]] Header file: "xll_stwtypes.h" In the past used type names like 'word', 'long' or 'dword' are mistakeable. They can have a different meaning dependent to the platform where they are used. E.g. 'word' means 16 bits at a 16-bit controller like the Infineon C167 or a 16/32-bit controller as the Freescale 68k. At a 32-bit controller like the used TriCore TC1796 it would mean 32 bits. There 16 bits are called a 'halfword' instead. That is why STW introduced unambiguous types like 'uint16' to avoid confusions in future. == Recommended unambiguous type definitions and prefixes == ^STW type^Prefix^Size^Range (hexadecimal - HEX)^Range (decimal - DEC)^C equivalent^ |uint8 |u8_ |8 bit |0x00 .. 0xFF|0 .. 255|unsigned char| |sint8 |s8_ |8 bit |0x80 .. 0x7F|-128 .. +127|signed char| |uint16|u16_|16 bit|0x0000 .. 0xFFFF|0 .. 65535|unsigned short int| |sint16|s16_|16 bit|0x8000 .. 0x7FFF|-32768 .. +32767|signed short int| |uint32|u32_|32 bit|0x00000000 .. 0xFFFFFFFF|0 .. 4294967295|unsigned long int| |sint32|s32_|32 bit|0x80000000 .. 0x7FFFFFFF|-2147483648 .. +2147483647|signed long int| |uint64|u64_|64 bit|0x0000000000000000 .. 0xFFFFFFFFFFFFFFFF|0 .. 18446744073709551615|unsigned long long int| |sint64|s64_|64 bit|0x8000000000000000 .. 0x7FFFFFFFFFFFFFFF|-9223372036854775808 .. +9223372036854775807|signed long long int| |float32|f32_|32 bit|[ ≈ ±2-126 .. ±2127 ]|0, ≈ ±1.18E-38 .. ±3.4E38 (decimal places 6..7)|float (FPU: IEEE-754) single precision| |float64|f64_|64 bit|[ ≈ ±2-1022 .. ±21023 ]|0, ≈ ±2.225E-308 .. ±1.798E+308 (decimal places 15..16)|double (SW: IEEE- 754)| |float80|f80_|80 bit|[ ≈ ±2-16382 .. ±216383 ]|0, ≈ ±3.362E-4932 .. ±1.190E+4932 (decimal places 18..19)|long double (SW: IEEE-754) double extended precision| Not recommended mistakable NATIVE type definitions (PLATFORM DEPENDENT!) ^STW type^Prefix^Size^Range (hexadecimal - HEX)^Range (decimal - DEC)^C equivalent^ |charn|cn_|8 bit |0x80 .. 0x7F|-128 .. +127|char| |uintn|un_|32 bit| 0x00000000 .. 0xFFFFFFFF|0 .. 4294967295|unsigned int| |sintn|sn_|32 bit| 0x80000000 .. 0x7FFFFFFF|-2147483648 .. +2147483647| signed int| Not recommended mistakeable COMPATIBILTY type definitions ^STW type^Prefix^Size^Range (hexadecimal - HEX)^Range (decimal - DEC)^C equivalent^ |boolean|q_|C: 1 bit, C++: 8 |0x00:FALSE / (!=0x00):TRUE|0:FALSE / (!=0):TRUE|C: _bit (TC1796), C++: bool| |int8 |i8_ |8 bit |0x80 .. 0x7F | -128 .. +127|(signed) char| |int16|i16_|16 bit|0x8000 .. 0x7FFF|-32768 .. +32767|(signed) short int| |int32|i32_|32 bit|0x80000000 .. 0x7FFFFFFF|-2147483648 .. +2147483647|(signed) long int| |int64|i64_|64 bit|0x8000000000000000 .. 0x7FFFFFFFFFFFFFFF|-9223372036854775808 .. +9223372036854775807|(signed) long long int| == Type definition (typedef) prefixes == ^Prefix^Example^Description^ |T_|typedef struct { ... } T_Struct;|type definition for structure (or bitfield) | |U_|typedef union { ... } U_Union;|type definition for union| |E_|typedef enum { ... } E_Enum;|type definition for enum | |PR_|typedef void (*PR_Function)( const uint8 ou8_Parameter );| type definition for function pointer| == Definition prefixes == ^Prefix^Example^Description^ |t_|T_Struct t_Struct;| structure (or bitfield)| |u_|U_Union u_Union;| union | |e_|E_Enum e_Enum;| enum | |pr_|PR_Function pr_FunctionPointer;| function pointer| |pv_|void *pv_VoidPointer;|void pointer| |s_|charn s_Text[3]="12";|zero ('\0') terminated string| == Modifier prefixes == ^Prefix^Example^Description^ |p|uint8 *pu8_Example; |pointer of type| |a|uint8 au8_Example[4];| array of type| == Area of validity prefixes == ^Prefix^Example^Description^ |g| uint8 gu8_Global; |global| |m| static uint8 mu8_ModuleGlobal; |module global (static inside file)| |h| static uint8 hu8_Example; |local static (static inside function - hold)| |o| void Callback( const uint8 ou8_Parameter ); |function parameter (operand)| == Examples == //Prefix examples /* local variable sint16 */ sint16 s16_VariableName; /* function internal array of pointers to uint8 with MAX_MESSAGES elements */ uint8 *apu8_Messages[MAX_MESSAGES]; /* Module global variable of type uint32 */ static uint32 mu32_Index; /* typedef for structure */ typedef struct { uint8 u8_Element1; uint32 *pu32_Element2; } T_StructType; /* modul globale pointer to structure defined by typdedef */ static T_StructType *mpt_PointerToMyStructType; /* function internal used structure */ T_StructType t_MyStructObject; /* module global structure variable */ static T_StructType mt_MyStruct; /* typedef for function pointer for a module 'DigIN' */ typedef void (*PR_DIN_CallBack)(const uint8 ou8_Parameter); /* global function pointer in module 'DigIN' */ PR_DIN_CallBack gpr_DIN_CallBack;