5.7.9.1.8.1. Enet LLDP Example

5.7.9.1.8.1.1. Makefile

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

  • To include TSN components, add the following macros:

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

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

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

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

5.7.9.1.8.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_lldp, tsn_uniconf):

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

    $ make tsn_unibase_clean tsn_combase_clean tsn_lldp_clean tsn_uniconf_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_lldp tsn_uniconf BUILD_PROFILE=debug
    
  • If you want to build with C++ compiling rules, use the CPLUSPLUS_BUILD=yes option:

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

    $ make enet_tsn_lldp_example_freertos CORE=mcu2_0
    

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

    <pdk>/packages/ti/binary/enet_tsn_lldp_example_freertos/bin/j7200_evm/enet_tsn_lldp_example_freertos_mcu2_0_release.xer5f
    

    This command will build the TSN example app (enet_tsn_lldp_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.

5.7.9.1.8.1.3. Running Enet TSN example

  • Launch a CCS debug session, load and run enet_tsn_lldp_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 Example App
    ==========================
    EnetBoard_setupPorts: 1 of 1 ports configurations found
    EnetApp_appInitTask: EnetBoard_setupPorts() done
    EnetAppUtils_reduceCoreMacAllocation: Reduced Mac Address Allocation for CoreId:0 From 1 To 0
    EnetApp_appInitTask: EnetApp_init() done
    Start: uniconf_task
    EnetApp_uniconfTask: dbname: NULL
    EnetMcm: CPSW_2G on MCU NAVSS
    Mdio_open: MDIO manual mode enabled
    PHY 0 is alive
    PHY 3 is alive
    PHY 23 is alive
    EnetPhy_bindDriver: PHY 0: OUI:080028 Model:23 Ver:01 <-> 'dp83867' : OK
    Logger_task: started
    [EnetApp_setLldpRtConfig] Initialized LLDP Local System data
    [EnetApp_setLldpRtConfig] Initialized LLDP Port tilld0
    Start: lldpd_task
    EnetApp_initTsn:gptp start done!
    CPU Load: 38%
    unibase-1.1.4-jacinto
    INF:cbase:tilld0: has mac: 00:00:00:00:00:00
    INF:lldp:simpledb_open:no data is imported
    INF:lldp:uc_hwal_open:
    INF:cbase:cb_rawsock_open:combase-1.1.3-jacinto
    INF:cbase:cb_rawsock_open:dmaTxChId=-1 numRxChannels=0 dmaRxChId=-1 nTxPkts=0 nRxPkts=0 pktSize=0
    INF:cbase:tilld0: alloc mac: 34:08:E1:77:EA:60
    INF:lldp:create_semname_with_dbname:null dbname is specified.
    INF:cbase:cb_lld_task_create:alloc stack size=16384
    INF:lldp:000001-091176:uniconf_main:uniconf started
    
    INF:cbase:cbl_query_response:tilld0 link DOWN !!!!
    INF:lldp:lldpd_init - DB [INF:lldp:create_semname_with_dbname:null dbname is specified.
    INF:lldp:initialize_cfg: loaded yang db
    INF:lldp:init_socket_utils:lldp_raw_sock_number 1  ndev_size 1
    INF:lldp:init_socket_utils:Openning tilld0
    INF:lldp:raw_sock_open [tilld0]
    INF:cbase:cb_rawsock_open:combase-1.1.3-jacinto
    INF:cbase:cb_rawsock_open:dmaTxChId=-1 numRxChannels=0 dmaRxChId=-1 nTxPkts=0 nRxPkts=0 pktSize=0
    INF:lldp:raw_sock_open:tilld0: Registered CB ret 0
    INF:lldp:raw_sock_open:tilld0 : Open raw socket OK fd 0
    INF:lldp:tilld0:01-80-C2-00-00-00 assigned to fd 0
    INF:lldp:tilld0:01-80-C2-00-00-03 assigned to fd 0
    INF:lldp:tilld0:01-80-C2-00-00-0E assigned to fd 0
    
    Cpsw_handleLinkUp: Port 1: Link up: 1-Gbps Full-Duplex
    MAC Port 1: link up
    INF:cbase:cbl_query_response:tilld0: link UP, speed=1000, duplex=1 !!!!
    
    INF:lldp:poll_link_state:tilld0 Detected Link State changed from 2 -> 1
    INF:lldp:ietf_get_actual_hw_port_info:tilld0 MAC: 34-08-E1-77-EA-60
    INF:lldp:on_link_state_up:tilld0
    INF:lldp:rxsm_on_port_enable tilld0
    INF:lldp:rxsm_on_admin_status_rx_enable:tilld0 RX_LLDP_INITIALIZE->RX_WAIT_FOR_FRAME
    INF:lldp:txInitializeLLDP:tilld0
    INF:lldp:reinitDelay: 2
    INF:lldp:msgTxHold: 4
    INF:lldp:msgTxInterval: 25
    INF:lldp:msgFastTx: 2
    INF:lldp:ttl: 101
    INF:lldp:on_port_tx_enable:tilld0 TX_LLDP_INITIALIZE->TX_IDLE
    INF:lldp:[txtimer_on_port_tx_enable] Starting TX Timer and TxTick Timer
    INF:lldp:lldp_start_txticktimer:tilld0: started txtick timer
    INF:lldp:txtimer_on_port_tx_enable:tilld0 TX_TIMER_INITIALIZE->TX_TIMER_IDLE
    INF:lldp:tilld0: Next TX cycle 1 s
    INF:lldp:poll_link_state:tilld0 Detected Link State changed from 2 -> 1
    INF:lldp:ietf_get_actual_hw_port_info:tilld0 MAC: 34-08-E1-77-EA-60
    INF:lldp:on_link_state_up:tilld0
    INF:lldp:rxsm_on_port_enable tilld0
    INF:lldp:rxsm_on_admin_status_rx_enable:tilld0 RX_LLDP_INITIALIZE->RX_WAIT_FOR_FRAME
    INF:lldp:txInitializeLLDP:tilld0
    INF:lldp:reinitDelay: 2
    INF:lldp:msgTxHold: 4
    INF:lldp:msgTxInterval: 20
    INF:lldp:msgFastTx: 2
    INF:lldp:ttl: 81
    INF:lldp:on_port_tx_enable:tilld0 TX_LLDP_INITIALIZE->TX_IDLE
    INF:lldp:[txtimer_on_port_tx_enable] Starting TX Timer and TxTick Timer
    INF:lldp:lldp_start_txticktimer:tilld0: started txtick timer
    INF:lldp:txtimer_on_port_tx_enable:tilld0 TX_TIMER_INITIALIZE->TX_TIMER_IDLE
    INF:lldp:tilld0: Next TX cycle 1 s
    INF:lldp:poll_link_state:tilld0 Detected Link State changed from 2 -> 1
    INF:lldp:ietf_get_actual_hw_port_info:tilld0 MAC: 34-08-E1-77-EA-60
    INF:lldp:on_link_state_up:tilld0
    INF:lldp:rxsm_on_port_enable tilld0
    INF:lldp:rxsm_on_admin_status_rx_enable:tilld0 RX_LLDP_INITIALIZE->RX_WAIT_FOR_FRAME
    INF:lldp:txInitializeLLDP:tilld0
    INF:lldp:reinitDelay: 2
    INF:lldp:msgTxHold: 4
    INF:lldp:msgTxInterval: 30
    INF:lldp:msgFastTx: 2
    INF:lldp:ttl: 121
    INF:lldp:on_port_tx_enable:tilld0 TX_LLDP_INITIALIZE->TX_IDLE
    INF:lldp:[txtimer_on_port_tx_enable] Starting TX Timer and TxTick Timer
    INF:lldp:lldp_start_txticktimer:tilld0: started txtick timer
    INF:lldp:txtimer_on_port_tx_enable:tilld0 TX_TIMER_INITIALIZE->TX_TIMER_IDLE
    INF:lldp:tilld0: Next TX cycle 1 s
    
    INF:lldp:tilld0: TX 62 bytes
    INF:lldp:tilld0: Next TX cycle 2 s
    INF:lldp:tilld0: TX 62 bytes
    INF:lldp:tilld0: Next TX cycle 2 s
    INF:lldp:tilld0: TX 62 bytes
    INF:lldp:tilld0: Next TX cycle 2 s
    
    INF:lldp:tilld0: TX 62 bytes
    INF:lldp:tilld0: Next TX cycle 25 s
    INF:lldp:tilld0: TX 62 bytes
    INF:lldp:tilld0: Next TX cycle 20 s
    INF:lldp:tilld0: TX 62 bytes
    INF:lldp:tilld0: Next TX cycle 30 s
    ...
    

5.7.9.1.8.1.4. Verification

Verification #1 LLDPDU Tx interval and LLDPDU content (per one dest-mac-address)

With default setting:

{"message-tx-interval" , "30"},

Capture LLDPDU via wireshark and confirm the TX interval is around 30s Capture LLDPDU via wireshark and confirm the LLDPDU content is match with configuration params in lldp_init.c

Verify via DUT log:

INF:lldp:tilld0: Next TX cycle 30 s

Verification #2 Fast TX in case of new neighbor exist (per one dest-mac-address)

On Linux PC, start opensource LLDP application by:

docker run --rm --net=host --uts=host \
     -v /etc/os-release:/etc/os-release \
     --cap-add=NET_RAW --cap-add=NET_ADMIN \
     --name lldpd \
     ghcr.io/lldpd/lldpd:latest

With default setting:

{"message-fast-tx" , "1"},
{"tx-fast-init" , "2"},

Verify via DUT log:

INF:lldp:tilld0: Got new neighbor [TTL=120]:
INF:lldp:chassis id: bc-5f-f4-73-e5-5a
INF:lldp:port id:    1c-fd-08-72-59-61
INF:lldp:tilld0: Triggering FAST TX
INF:lldp:tilld0: TX 62 bytes
INF:lldp:tilld0: Next TX cycle 2 s

INF:lldp:tilld0: TX 62 bytes
INF:lldp:tilld0: Next TX cycle 2 s

INF:lldp:tilld0: TX 62 bytes
INF:lldp:tilld0: Next TX cycle 30 s

Verification #3 Delete neighbor info in case of Receiving LLDP shutdown (per one dest-mac-address) Continue 2nd verification, then turn OFF LLDPDU by Ctrl + C in Linux PC docker command. Verify DUT can detect and delete correct neighbor info include Port and Chassis ID.

DUT log:

INF:lldp:collect_ttl_info: Recv SHUTDOWN LLDPDU TTL=[0]
INF:lldp:tilld0: Process shutdown for existed neighbor:
INF:lldp:chassis id: bc-5f-f4-73-e5-5a
INF:lldp:port id:    1c-fd-08-72-59-61

User can rerun 2nd verification and confirm Fast TX flow happen again.

Verification #4 Detected Neighbor info change (per one dest-mac-address)

On Linux PC side, change port description of corresponding port which is connect to DUT. In this example, enp3s0 is used:

docker exec lldpd lldpcli configure port enp3s0 lldp portdescription xxxxxxx

DUT log:

INF:lldp:is_remote_system_data_change: Detected port desc changed
INF:lldp:tilld0: Got updated for neighbor [TTL=120]:
INF:lldp:chassis id: bc-5f-f4-73-e5-5a
INF:lldp:port id:    1c-fd-08-72-59-61
INF:lldp:update_remote_system_data: changed port_desc [enp3s0-> xxxxxxx]

Verification #5 Multiple Destination MAC addresses Configure 3 message-tx-interval values differently each other, like below:

{
      .dest_mac = "01-80-c2-00-00-0e",
      {"message-tx-interval" , "30"},
}
{
      .dest_mac = "01-80-c2-00-00-03",
      {"message-tx-interval" , "20"},
}
{
      .dest_mac = "01-80-c2-00-00-00",
      {"message-tx-interval" , "25"},
}

Capture wireshark and verify the tx interval flow for:

  • Nearest bridge 01-80-C2-00-00-0E (LLDP Multicast) is 30s

  • Nearest non-TPMR bridge 01-80-C2-00-00-03 is 20s

  • Nearest Customer Bridge (Spanning-tree-(for-bridges)_00) 01-80-C2-00-00-00 is 25s

Repeat verification #1 -> #4 (The LLDP opensource is using Nearest bridge 01-80-C2-00-00-0E as destination MAC address) and confirm only Nearest bridge Dest MAC address in DUT takes effect.