4.7.6.1.4.1. Enet TSN Example

4.7.6.1.4.1.1. Makefile

For an example of the app makefile, please refer to <enet>/examples/enet_tsn_example/makefile. There are some important notes to consider:

  • To include TSN components, add the following macros:

    INCLUDE_INTERNAL_INTERFACES += tsn_gptp tsn_combase tsn_unibase
    COMP_LIST_COMMON += tsn_combase tsn_unibase tsn_gptp
    
  • Ensure that the tsninit.c file is included in the app’s source:

    SRCS_COMMON += main.c tsninit.c
    
  • If the log task is used, define the TSN_USE_LOG_BUFFER macro:

    CFLAGS_LOCAL_COMMON += -DTSN_USE_LOG_BUFFER=1
    
  • Include the tsn_tilld_include.h at the beginning to ensure the correct inclusion of combase headers:

    CFLAGS_LOCAL_COMMON += -include $(PDK_TSN_COMP_PATH)/tsn-stack/tsn_tilld_include.h
    

4.7.6.1.4.1.2. Build Enet TSN example

  • Navigate to the <pdk>/packages/ti/build directory:

    $ cd <pdk>/packages/ti/build
    
  • Build the TSN modules (tsn_unibase, tsn_combase, tsn_gptp):

    $ make tsn_unibase tsn_combase tsn_gptp
    
  • To clean the build and remove generated files:

    $ make tsn_unibase_clean tsn_combase_clean tsn_gptp_clean
    
  • You can specify the build mode as either release or debug. By default, the release mode is built. To build in debug mode, use the BUILD_PROFILE=debug option:

    $ make tsn_unibase tsn_combase tsn_gptp BUILD_PROFILE=debug
    
  • If you want to build with C++ compiling rules, use the CPLUSPLUS_BUILD=yes option:

    $ make tsn_unibase tsn_combase tsn_gptp CPLUSPLUS_BUILD=yes
    
  • To build the TSN example app in the PDK, use the following command:

    $ make enet_tsn_example_freertos CORE=mcu2_0
    

    The example app binary file can be found at the following location:

    <pdk>/packages/ti/binary/enet_tsn_example_freertos/bin/j7200_evm/enet_tsn_example_freertos_mcu2_0_release.xer5f
    

    This command will build the TSN example app (enet_tsn_example_freertos) using the FreeRTOS operating system and targeting the mcu2_0 core. Adjust the command according to your specific requirements, such as selecting a different operating system or core if needed.

4.7.6.1.4.1.3. Running Enet TSN example

  • Launch a CCS debug session, load and run enet_tsn_example_freertos_mcu2_0_release.xer5f binary file to the MAIN_Cortex_R5_0_0. Alternatively, the example application can be loaded using any other boot method such as MMC/SD.

  • Logs will be printed in Main UART port 0. Below is an example of the log when gPTP works in slave mode:

    ==========================
             TSN App
    ==========================
    EnetBoard_setupPorts: 2 of 2 ports configurations found
    main: EnetBoard_setupPorts() done
    main: EnetApp_init() done
    tsnapp_task:gptp start done!
    CPU Load: 2%
    gptp_task: started.
    EnetMcm: CPSW_9G on MAIN NAVSS
    Mdio_open: MDIO manual mode enabled
    PHY 0 is alive
    PHY 4 is alive
    EnetPhy_bindDriver: PHY 0: OUI:080028 Model:29 Ver:00 <-> 'Dp83tg721' : OK
    EnetPhy_bindDriver: PHY 4: OUI:080028 Model:29 Ver:00 <-> 'Dp83tg721' : OK
    log_task: started.
    unibase-1.1.4-46b7374
    INF:gptp:gptpnet_init:Open lldtsync OK!
    INF:gptp:000000-624234:domainIndex=0, GM changed old=00:00:00:00:00:00:00:00, new=70:FF:76:FF:FE:1D:9B:77
    INF:gptp:set_phase_offsetGM:domainNumber=0, New adjustment(New GM?)
    Cpsw_handleLinkUp: Port 1: Link up: 1-Gbps Full-Duplex
    Cpsw_handleLinkUp: Port 2: Link up: 1-Gbps Full-Duplex
    MAC Port 1: link up
    MAC Port 2: link up
    INF:gptp:index=1 speed=1000, duplex=full, ptpdev=tilld0
    INF:gptp:index=2 speed=1000, duplex=full, ptpdev=tilld1
    ...
    INF:gptp:set_phase_offsetGM:domainNumber=0, New adjustment(New GM?)
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment, diff=686848947
    WRN:gptp:gptpclock_setoffset64:clockIndex=1, domainNumber=0, can't set in the time. the result must be inaccurate
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=210489
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=212961
    INF:gptp:clock_master_sync_receive:computeGmRateRatio:domainNumber=0 unstable rate=19781ppb (timeleap_future)
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 232742ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=201161
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 339521ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=182536
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 373116ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=161714
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 368386ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=141167
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 345162ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=121872
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 314067ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=104701
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 280212ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=89613
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 249210ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=76477
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 220595ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=65129
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 194956ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=55384
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 172395ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=47051
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 152814ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=39952
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 135971ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=33854
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 121469ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=28696
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 108546ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=24363
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 98255ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=20682
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 89492ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=17551
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 81991ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=14889
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 75586ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=12627
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 70128ppb
    INF:gptp:set_phase_offsetGM:domainNumber=0, offset adjustment by Freq., diff=10710
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 65499ppb
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 61563ppb
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 58249ppb
    INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 55383ppb
    ...
    

4.7.6.1.4.1.4. Verification

Single port

Connect a port to a Linux PC and run gptp2d from the PC. The expected log from the slave side will be stable and reprinted like this:

INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 65499ppb
INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 61563ppb
INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 58249ppb
INF:gptp:domainNumber=0, clock_master_sync_receive:the master clock rate to 55383ppb
...

Instead of displaying the clock_master_sync_receive:... log, the following log will be printed in the case of the master log:

domain=0, offset=0nsec, hw-adjrate=0ppb
        gmsync=true, last_setts64=0nsec
domain=0, offset=0nsec, hw-adjrate=0ppb
        gmsync=true, last_setts64=0nsec
CPU Load: 2%
domain=0, offset=0nsec, hw-adjrate=0ppb
        gmsync=true, last_setts64=0nsec
CPU Load: 2%
domain=0, offset=0nsec, hw-adjrate=0ppb
        gmsync=true, last_setts64=0nsec
CPU Load: 2%
domain=0, offset=0nsec, hw-adjrate=0ppb
        gmsync=true, last_setts64=0nsec
...

Multiple ports

In this function, gPTP is operating as a switch. The availability of this feature is determined by the board configuration rather than the gPTP stack. If a board enables multiple MAC ports, the gPTP function should operate properly. To test this function, please connect two PCs to two ports of the EVM.

When the EVM board acts as the master, only the master log will be printed out, while the two PCs will print the slave log. On the other hand, if one of the PCs acts as the master, the slave log will be printed by the other PC and the EVM, while the master PC will print the master log.

To identify which machine is the master, please check the log:

INF:gptp:001809-750000:domainIndex=0, GM changed old=24:76:25:FF:FE:96:6C:41, new=70:FF:76:FF:FE:1D:9B:77

In this case, the machine with the source MAC address of 70:FF:76:FF:FE:1D:9B:77 is the master.