TI TMS320F28379D
Porting Paulus on TI TMS320F28379D
File structure
After installation of Paulus the source code is stored in the file structure shown in Table 1 describes the contents.
directory | description |
/paulus_tms320f28379d | project folder with all necessary code composer project files |
/bootloader | target independent CANopen sources for Paulus |
/eds | Design Tool project of Paulus with all generated files, e.g. the EDS file and documentation files |
/tms320f28379d/ | target-specific sources of Paulus, e.g. CAN-driver, low-level drivers and supporting services from TI Corporation (e.g. startup, clock, flash-service, usart) |
/tms320f28379d/tms320f28379d_flash.[ch] | target-specific flash routines |
/tms320f28379d/tms320f28379d_can.[ch] | CAN routines |
/tms320f28379d/tms320f28379d_init.c | CPU initialization |
/tms320f28379d/environ.h | header file for the environment includes |
/tms320f28379d/bl_config.h | Paulus configuration file |
/tms320f28379d/tidcs/.. | F28379 Support Library v210 and Flash-API lib from TI |
/examples | example applications for a CANopen slave and simple “hello World” examples with necessary project files |
/tools | checksum generator tool for Paulus |
main.c | main loop of Paulus |
Table 1: File structure
Paulus is implementet und tested on the Board “F2837x ControlCARD board” from TI which includes a TMS320F28379d target. The initialization of the CAN controller is done in the module tms320f28379d_can.c.
In the module tms320f28379d_init.c the I/O pins for the CAN interface are initialized.
Also in the module tms320f28379d_init.c there are the functions getBitRate() and getNodeId() available. Usually the these CANopen network parameters are provided by reading jumpers or by loading from flash memory.
Development environment
Paulus on the platform of TMS320F28379d was developed with the workbench TI CodeComposer v6.x
Paulus configuration
In general the initialization function initializes only the absolutely necessary peripherals like clock system, CAN controller, memory management as needed by Paulus and a timer for Heartbeat or LSS. Nevertheless, there might be situations where it makes sense that Paulus initializes other functionalities which are later used by the application as well. As an example consider the serial interface for debug messages.
CAN bit rate
The CAN bit rate is coded by the index of the CAN bit timing table according to /CiA-305/. The index of the default CAN bit rate is specified with the compiler-define BITRATE_INDEX_<bit_rate> in /tms320f28379d/bl_config.h:
#define BL_USED_BITRATE_INDEX BITRATE_INDEX_125K
The default CAN bit rate is 125 kbit/s and can be changed by LSS services. The LSS services are described in /Paulus_man/ and based on /CiA-305/. The supported CAN bit rates are depending on the clock of the CAN controller and are listed in /tms320f28379d/ tms320f28379d_can.c. The value FFh for segment 2 marks unsupported CAN bit rates. The clock for the activation of the CAN bit rate is generated by the hardware Timer0 with a period of 1 ms.
Heartbeat producer
Timer0 is also used for the generation of Heartbeat producer messages.
Debug output
With the compiler-define DEBUG a debug output can be activated about the serial interface usart. The compiler-define is set in file /tms320f28379d/bl_config.h: (This may additionally be controlled by project symbol settings.)
#define DEBUG 1
In general the initialization function will initialize only the absolutely necessary peripherals like clock system, CAN controller, memory management as needed by Paulus. Nevertheless, there might be situations where it makes sense that Paulus initializes other functionalities which are later used by the application as well. As an example consider the serial interface for debug messages.
Generating application software
The application software consists of an application header and an application program.
The application program has to be prepared for download by the following steps:
build the application program in binary format
calculate the CRC of the application program, build the application header and generate the application software to download
configure the start address of the application software in Paulus
Paulus checksum
The program paulus_cksum calculates the CRC checksum of the binary application program generates the application header and stores the application header and the application program in a new file. This file can be loaded into the device by Paulus. The application for download must be a binary file. They could e.g. use the CCS tool hex2000.exe to convert a created output file from CCS to hex file as an intermediate step.
Example: call the prepared script “postBuildStep_Debug.bat” from a windows console:
Z:\<..>\CANopenSlave1_tms320f28379\examples\s1>C:\ti\ccsv6\tools\compiler\ti-cgt-c2000_17.9.0.STS\bin\hex2000.exe -i Debug\s1_tms320f28379.out
Translating to Intel format...
"Debug\s1_tms320f28379.out" codestart ==> codestart
warning: Data is being written to auto-generated file s1_tms320f28379.i00
warning: Data is being written to auto-generated file s1_tms320f28379.i01
"Debug\s1_tms320f28379.out" .text ==> .text
"Debug\s1_tms320f28379.out" .econst ==> .econst
"Debug\s1_tms320f28379.out" ramfuncs ==> ramfuncs
"Debug\s1_tms320f28379.out" .cinit ==> .cinit
"Debug\s1_tms320f28379.out" .switch ==> .switch
"Debug\s1_tms320f28379.out" .reset ==> .reset
Unused bytes in the application header are set to 0x00 with the TMS320F28379. The length of the application header is 256 bytes.
Example: The download file for the application program s1_tms320f28379.download is generated with Windows console with the prepared script “create_image.bat”:
Z:\<..>\CANopenSlave1_tms320f28379\examples\s1>create_image.bat
Z:\<..>\CANopenSlave1_tms320f28379\examples\s1>REM
Z:\<..>\CANopenSlave1_tms320f28379\examples\s1>REM hex2000.exe -i debug\s1_tms320f28379.out
Z:\<..>\CANopenSlave1_tms320f28379\examples\s1>REM is called from the CCS post command / alternatively from windows console
Z:\<..>\CANopenSlave1_tms320f28379\examples\s1>set tools_dir=..\..\..\..\tools
Z:\<..>\CANopenSlave1_tms320f28379\examples\s1>..\..\..\..\tools\objcopy -I ihex -O binary --gap-fill=0xFF s1_tms320f28379.i00 s1_tms320f28379.b00
Z:\<..>\CANopenSlave1_tms320f28379\examples\s1>..\..\..\..\tools\objcopy -I ihex -O binary --gap-fill=0xFF s1_tms320f28379.i01 s1_tms320f28379.b01
Z:\<..>\CANopenSlave1_tms320f28379\examples\s1>..\..\..\..\tools\
paulus_cksum -C -l 256 -j -x 0x084080 -O s1_tms320f28379.download s1_tms320f28379.b00 s1_tms320f28379.b01
size: 0x000079fe, crc: 0x0b0b
Besides checking the CRC Paulus checks also the size of the application header. A size of 0 is invalid. An application may destroy the ’valid’ information by overwriting the size with 0. That is always possible on the TMS320F28379d FLASH, because the byte content is 0xFF after erasing.
More detailed information from this tool can find in /Paulus_CRC/.
Start address
It is important that the start address of the application software in the flash memory and the information in the Paulus configuration in tms320f28379d/tms320f28379d_flash.h are identical. The application software is stored as a separate program in the flash memory in addition to the bootloader program. Therefore the application software is flashed to:
#define FLASH_PROGRAM_START_ADR 0x00084000ul
The length of the application header is 256 byte. The program start of the application is at address (FLASH_PROGRAM_START_ADR + 256 bytes).
Memory
Shared RAM
The shared RAM for data exchange between bootloader and application starts at address 0x000300 in the NOINIT section from RAM block M0. The size of the shared RAM is specified in tms320f28379d/bl_interface.h by the compiler-define BL_JUMPCODE_SIZE.
The shared memory is installed in tms320f28379d/bl_interface.c as follow:
#pragma DATA_SECTION(jumpcode , ".noinit")
UNSIGNED8 jumpcode[BL_JUMPCODE_SIZE];
The keyword for the re-start of the application program is set in byte 0-3 of jumpcode. Paulus uses the keyword “APPL” or “BOOT” to start the application program, see /Paulus_man/.
Flash
The size of the respective flash is dependent on the CPU type. The total size of the TMS320F28379 flash is 512Kb (single Core). The current implementation of Paulus occupies a memory area of 16Kb (Sector A and B) from this. Therefor up to 496Kb (less 0x80 byte crc header) flash memory area is available for the application software (default state - without LSS service). The last sector N (8Kb) is excluded from Paulus Erase / Flash process (reserved for config/calibration data from the application).
Flash memory tms320f28379 device type:
The optionally CANopen service LSS from Paulus used just additional Flash Sector C for saving config data (nodeID and bitrate index). This is only a possible design example. Alternatively, it is possible to store this data in an eeprom to free the Sector C for the application software.
The flash area for configuration data of Paulus is located at address 0x00085F00. On this address and the following Paulus stores the node-ID and the CAN bit rate index during the execution of the LSS service “LSS store configuration“. The addresses are configurable in tms320f28379d/bl_interface.h:
Note:
The Lss store command takes some time to perform. When saving the data in the Flash, the entire Flash sector must be deleted. This can take longer than the default timeout of 500ms. The timeout error from the DeviceMonitor can be ignored, in fact the data is stored.
After the next re-start Paulus uses this node-ID and this CAN bit rate index for communication. The new CAN bit rate cannot be activated by NMT-Command Reset Application. If the LSS services are not used, Paulus uses the node-ID and CAN bit rate index configured in tms320f28379d/bl_config.h.
Example application
CANopen Slave1 is an example for an application program. The directory example/ CANopenSlave1_tms320f28379 contain the compiler project and the application-specific functions. For compilation the CANopen Library and a suitable driver package is necessary. The CANopen Library and the driver package belong not to the delivery scope of Paulus. The binary application software in example/ CANopenSlave1_tms320f28379/examples/s1/s1_tms320f28379.download can be used for a quick start.
From Paulus version 1.27 an additional SYS/BIOS example is available in example/ CANopenSlave1_tms320f28379/examples/s1/s1_sysbios. Created according to the same principles but with newer TI CodeComposer v8.3. The linker file of this example project is adapted to the Paulus memory requirements. See flash address settings in the example linker-file (2837xD_FLASH_lnk_cpu1.cmd):
This example has included source files bl_interface.c, bl_interface.h from bootloader. The application program can request an update by jumping back into Paulus by writing of the program control command start application program (value 1) on object 1F51h/1. The application program calls the macro BOOTLOADER_JUMP(APPL). This call is implemented in usr_301.c /sdoWrInd(). The application program stores the keyword “APPL” in the shared RAM and jumps into Paulus. Paulus is re-started and stays running until the application program is started by command.
If the example application program is running the CANopen slave starts with his bootup followed by heartbeat messages over the CAN-bus.
Dual Core variant
The Paulus dual core design is based of the requirements:
the bootloader (Master) will run on CPU1
the bootloader (Slave) will additional run on CPU2, this part is necessary because the flash of CPU2 is writable only from the RAM of CPU2
for the communication between the Paulus on CPU1 and CPU2 an additional IPC interface is necessary
while in bootloader mode, CPU2 is halted, so no application will run
writing an application to the bootloader will load this to either CPU1 or CPU2 flash, selective
going to application would mean that
both applications are CRC checked and started if they are available
or just the application on CPU1 if no CPU2 application is loaded
File structure
The structure for the dual core implementation corresponds in principle with the single core variant. For the dual core mode, the names of the used source folders were extended by the addition cpu1 / cpu2.
directory | description |
/paulus_tms320f28379d_cpu1 /paulus_tms320f28379d_cpu2 | project folders with all necessary code composer project files for CPU1 and CPU2 |
/bootloader | target independent CANopen sources for Paulus, Paulus on cpu2 used only the checksum calculation |
/eds | Design Tool project of Paulus with all generated files, e.g. the EDS file (paulus_dualcore.eds is relevant) |
/tms320f28379d_cpu1/ /tms320f28379d_cpu2/ | target-specific sources of Paulus, e.g. CAN-driver (only cpu1), low-level drivers and supporting services from TI Corporation (e.g. startup, clock, flash-service, usart), IPC communication sources |
/examples | example applications for a CANopen slave (cpu1) and simple “hello-World” example (cpu2) with necessary project files |
/tools | checksum generator tool for Paulus |
main_dualcore_cpu1.c main_dualcore_cpu2.c | Cpu core specific main loops of Paulus |
Table 2: File structure Dual core variant
Flash (dual Core)
The statements made in former chapter “Flash single core” also apply in the dual core version for the CPU1 core. The optionally CANopen service LSS from Paulus only plays a role on CPU1 with his CAN-interface, CPU2 is not affected by it. The total size of the TMS320F28379 flash is 512Kb (CPU1 and CPU2 Core). The current implementation of Paulus on CPU2 occupies a memory area of 16Kb (Sector A and B) from this. Therefor up to 496Kb (less 0x80 byte crc header) flash memory area is available for the application software on CPU2. The last sector N (8Kb) on both CPUs is excluded from Paulus Erase / Flash process (reserved for config/calibration data from the application).
Flash memory tms320f28379 (dual core) device type:
Dual core specifics
Paulus on CPU1 based on the existing Paulus single core variant with the CANopen functionality described in the standard Paulus User Manual
Additional is the selection of the CPU for the erase / flash process. Intended for this is an additional object (0x4F51) in the object dictionary of Paulus is created. This object can be read/write via SDO. (Value range: 1 = CPU1, 2 = CPU2). Depending on the value of this switch, the Erase/flash commands be valid for the respective CPU (CPU1 = default state)
The jump into application command via object (0x1F51/1) is always valid for both CPUs
Practice shows, that a clean jump from the application to the bootloader is only possible by triggering a SW reset as watchdog reset on CPU1. When this reset is triggered, CPU2 is also reset and it also jumps into his Paulus on CPU2. But this also means for a safe, orderly shutdown of the SW in CPU2 it might be necessary to send a signal from CPU1 to CPU2 before the reset is triggered.
This is exemplarily implemented in the dual core examples. The CPU2 example waits in his main loop (via IPC Flag31) for the setting of CPU1.
Generating application software:
The same descriptions and procedures apply to the generation of your own application binarys (on CPU1 and CPU2) as described in chapter 2 from the single core variant.
Examples (dual core)
For the dual core mode the same CANopen Slave1 single core example was used and has been extended. It runs on CPU1 as example application.
The compiler switch should be activated (bl_config.h):
/* dual core variant support */
#define BL_CPU_DUAL_CORE_MODE 1
For the CPU2 example application a simple “hello-World” project was created. The directory example/ hello_tms320f28379_cpu2 contain the compiler project and the application-specific functions. In his main loop only a LED blinking (GPIO34 - LED3 on TI controlCard) shows example application is active.
References
/CiA-305/ | CANopen Layer Setting Services and Protocols, CiA |
/Paulus_CRC/ | manual “Paulus Checksum Tool”, see file tools/manual_cksum.pdf |
/Paulus_man/ | manual “Paulus User Manual”, see file UserMan_Paulus_Bootloader_e.pdf |
Table 3: References