cc2538-bsl

repository·main·Indexed 20 days ago

https://github.com/jelmert/cc2538-bsl

A Python-based tool for communicating with the serial bootloaders of Texas Instruments CC13xx, CC2538, and CC26xx SoCs. It enables erasing, programming, verifying, and reading flash memory via a USB-to-UART converter. The tool supports raw binary and Intel Hex files, provides specific support for Sonoff Zigbee 3.0 USB Dongle Plus, and includes a CLI for managing memory operations and IEEE address configuration.

Tokens
2.9K
Snippets
8
Records
12
Agent score
20%

What's inside cc2538-bsl

  1. Avoid getting locked out of CC2538 bootloader

    main

    On the CC2538, once a valid image is flashed, the "Image Valid" bits are set to 0, and the bootloader will not start automatically on reset. To prevent being "locked out" (unable to communicate via serial), you must enable the bootloader backdoor in your firmware.

    Enabling the Backdoor

    Enable the backdoor by configuring the 8-bit boot loader backdoor field in the CCA area in flash.

    Example Configuration: Set the field to 0xF3FFFFFF. This configures the bootloader to start when pin PA3 is pulled low during boot. On a SmartRF06 board, this is achieved by holding the select button while pushing the EM reset button.

    Recovery: If you are locked out, you must use a JTAG programmer to erase the image. This resets the image valid bits and re-enables the bootloader on the next reset.

  2. Configure CC13xx and CC26xx ROM bootloader

    main

    For the CC13xx and CC26xx families, the ROM bootloader is configured via the BL_CONFIG register in the CCFG.

    Required Settings

    To ensure the bootloader can be triggered, the following must be configured (typically in startup_files/ccfg.c if using CC13xx/CC26xxware):

    1. Enable Bootloader: BOOTLOADER_ENABLE must be set to 0xC5.
    2. Select Pin: BL_PIN_NUMBER (e.g., 0x0B for DIO 11).
    3. Select Level: BL_LEVEL (e.g., 0x00 for Active Low).
    4. Enable Failure Analysis: BL_ENABLE must be set to 0xC5.
    5. Enable Bank Erase: The BANK_ERASE_DIS_N bit in the ERASE_CONF register must be set (enabled by default).

    Security Warning: Enabling failure analysis allows the bootloader to be triggered via a DIO pin, but it may also allow a malicious user to read or erase your device's flash. Do not enable this in production deployments unless you understand the security implications.

  3. Install required Python dependencies

    main

    The script requires several packages to function correctly. Install them using pip:

    • pyserial: Required for serial port communication.
    • intelhex: Required if you want to program devices using Intel Hex files.
    • python-magic: Used to auto-detect if firmware is a raw binary or Intel Hex. If not installed, the script falls back to checking file extensions (.hex, .ihx, .ihex).
    pip install pyserial intelhex python-magic
    pip install pyserial intelhex python-magic
  4. Use cc2538-bsl to flash firmware

    main

    The script can erase, program, verify, and read flash on TI CC13xx, CC2538, and CC26xx SoCs.

    Important: Before uploading, you must manually start the bootloader on the SoC (e.g., by holding select + reset on a CC2538DK).

    Common Commands

    • Write raw binary: Use -e to erase the flash before writing and -w to write. Use -v to verify.
    • Write Intel Hex: The script auto-detects .hex files, but you must still include the erase flag.
    • Sonoff Zigbee 3.0 USB Dongle Plus: Use the --bootloader-sonoff-usb flag to activate the bootloader without opening the enclosure.
    • Manual Port Selection: If the script selects the wrong port (common on Linux with SmartRF06 boards), use the -p flag to specify the correct serial port.

    To see all available options, run cc2538-bsl -h.

    # Write a raw binary firmware
    cc2538-bsl -e -w -v example/main.bin
    
    # Write firmware to a Sonoff Zigbee 3.0 USB Dongle Plus
    cc2538-bsl --bootloader-sonoff-usb -e -w -v CC1352P2_CC2652P_launchpad_coordinator.hex
  5. Install cc2538-bsl

    main

    You can install the tool and its cc2538-bsl command directly from a local checkout using pip. Alternatively, you can run the script in place using the Python module syntax.

    Prerequisites

    • A Python interpreter (Linux and Mac are supported; Windows users may need to download Python manually).
    • A USB to serial converter (ensure it uses 3.3v voltage levels).
    • If using a SmartRF06 board with an Evaluation Module (EM), ensure the "Enable UART" jumper is set.

    Installation Commands

    # Install the command globally from a local checkout
    pip install .
    
    # Run in place without installing
    python -m cc2538_bsl.cc2538_bsl
    pip install .
  6. Parse page or address ranges for erasing

    main

    When using the --erase-page (-E) flag, the tool parses ranges using a prefix system:

    • Address range (a): Uses absolute addresses. Format: a,start_addr,end_addr (e.g., a,0x0000,0x1000).
    • Page range (p or page): Uses page indices. Format: p,start_page,end_page (e.g., p,1,4).

    Addresses must be aligned to the device's page_size.

  7. Use the cc2538-bsl CLI to manage TI SoCs

    main

    The cc2538-bsl CLI tool allows you to erase, program, verify, and read flash memory on TI CC13xx, CC2538, and CC26xx SoCs via a serial port.

    Basic Usage Pattern: python cc2538_bsl.py [OPTIONS] FILE

    Common Operations:

    • Write firmware: Use -w to write the specified FILE to the target address.
    • Read flash: Use -r to read flash memory from the device into the specified FILE.
    • Erase flash: Use -e for a mass erase, or -E for a specific range/page erase.
    • Verify: Use -v to perform a CRC32 check between the local file and the target flash.
    • Erase and Write: Use -W to erase the section required for the write (rounding up to page alignment) before writing, which is more efficient than a mass erase.
    python cc2538_bsl.py -w firmware.bin
    python cc2538_bsl.py -r backup.bin
    python cc2538_bsl.py -e firmware.bin
    python cc2538_bsl.py -W firmware.bin
  8. Parse IEEE addresses in cc2538-bsl

    main

    The tool supports parsing 64-bit IEEE addresses in several formats to set the secondary IEEE address on the device. Supported formats include:

    • A hex integer (e.g., 0x1234567812345678)
    • A colon-separated list of 8 bytes (e.g., 12:34:56:78:12:34:56:78)
    • A hyphen-separated list of 8 bytes (e.g., 12-34-56-78-12-34-56-78)

    Note: The address must contain exactly 8 bytes.

  9. Manage chip-specific operations with Chip classes

    main

    The project uses a class hierarchy to handle different TI SoC families. All chip classes inherit from Chip and provide high-level methods for erasing and reading memory.

    CC2538

    • Flash Start Address: 0x00200000
    • Erase: Use erase() to clear the entire flash range.
    • Read: Use read_memory(addr) to read memory (handles byte order inversion specific to CC2538).

    CC26xx and CC13xx

    • Erase:
      • erase(): Erases all main bank flash sectors using cmdBankErase.
      • eraseRange(addr, size): Erases specific sectors using cmdSectorEraseCC26xx.
    • Read: Use read_memory(addr) to read memory.
    • Identification: The class automatically detects whether the chip is a CC13xx or CC26xx and identifies the specific model (e.g., CC2650, CC1350) and revision (PG) via ICEPICK_DEVICE_ID and FCFG_USER_ID.
    from cc2538_bsl.cc2538_bsl import CommandInterface, CC2538, CC26xx
    
    ci = CommandInterface()
    ci.open("/dev/ttyUSB0")
    ci.invoke_bootloader()
    
    # For CC2538
    chip = CC2538(ci)
    chip.erase()
    
    # For CC26xx
    chip = CC26xx(ci)
    chip.erase() # Erases main bank flash sectors
  10. Communicate with the bootloader using CommandInterface

    main

    The CommandInterface class manages the serial communication with the TI SoC bootloader.

    Opening a connection

    Use open(aport, abaudrate) to initialize the serial port. The aport is the serial device URL (e.g., /dev/ttyUSB0 or COM3). The default baud rate is 500000.

    Invoking the bootloader

    To transition the chip from running firmware into the bootloader mode, use invoke_bootloader(). This method uses the DTR and RTS lines to toggle the bootloader pin and the !RESET pin automatically.

    Supported hardware-specific configurations:

    • dtr_active_high: Set if the DTR line logic is inverted.
    • inverted: If True, swaps the roles of DTR and RTS.
    • sonoff_usb: Specific sequence for the ITead Sonoff Zigbee 3.0 USB Dongle to handle its unique RTS/DTR/IO15 relationship.

    Core Commands

    • cmdPing(): Verifies communication.
    • cmdGetChipId(): Retrieves the chip ID.
    • cmdGetStatus(): Checks the current status of the bootloader.
    • cmdEraseMemory(addr, size): Erases a range of memory.
    • cmdDownload(addr, size): Prepares the device for a data download.
    • cmdSendData(data): Sends the actual firmware data.
    • cmdMemRead(addr): Reads memory (Note: behavior varies between CC2538 and CC26xx).
    from cc2538_bsl.cc2538_bsl import CommandInterface
    
    ci = CommandInterface()
    ci.open(aport="/dev/ttyUSB0", abaudrate=500000)
    ci.invoke_bootloader(sonoff_usb=True)
    ci.cmdPing()
    ci.close()
  11. Parse firmware files with FirmwareFile

    main

    The FirmwareFile class is used to load firmware data from a file path. It supports both Intel HEX and raw binary formats.

    It attempts to auto-detect the file type using python-magic. If python-magic is not installed, it falls back to checking file extensions (.hex, .ihx, .ihex) or assumes a raw binary (.bin) format.

    If you want more reliable auto-detection, install python-magic. If you are using Intel HEX files, installing the intelhex library is recommended to avoid errors.

    from cc2538_bsl.cc2538_bsl import FirmwareFile
    
    # Example usage (conceptual)
    fw = FirmwareFile("path/to/firmware.hex")
    print(fw.bytes)  # Access the loaded bytearray
  12. Reference the cc2538-bsl CLI flags

    main

    The following command-line arguments are available for controlling the bootloader operations:

    FlagLong FlagDescription
    -qQuiet mode
    -VVerbose mode
    -f--forceForce operation(s) without asking questions
    -e--eraseMass erase
    -E--erase-pageReceives an address range (a,start,end) or page range (p,start,end). Example: -E a,0x00000000,0x00001000 or -E p,1,4
    -w--writeWrite firmware to target
    -W--erase-writeWrite after erasing the required section (avoids mass erase)
    -v--verifyVerify via CRC32 check
    -r--readRead flash memory
    -l--lenLength of read (default: 0x80000)
    -p--portSerial port (defaults to first USB-like port in /dev)
    -b--baudBaud speed
    -a--addressTarget flash address
    -i--ieee-addressSet the secondary 64-bit IEEE address
    --bootloader-active-highUse active high signals to enter bootloader
    --bootloader-invert-linesInvert RTS and DTR signals
    --bootloader-sonoff-usbUse specific RTS/DTR pattern for Sonoff USB dongles
    -D--disable-bootloaderDisable the bootloader after finishing
    --versionShow version information

    Positional Argument:

    • file: The firmware file to write or the destination file to read into.
    python cc2538_bsl.py -p /dev/ttyUSB0 -a 0x0000 -w firmware.bin