OTA_SDK Usage Guide and Porting Guide*
1. Overview*
- This document describes how to integrate the OTA_SDK into the host computer and perform OTA upgrades on the GX8002, GX8008(C), GX8009/GX8010 and other chip series.
- This document mainly explains the OTA_SDK code, core code description of the upgrade process, and download instructions.
Important Information
The OTA upgrade described in this document supports firmware upgrade on blank chips, which means that OTA can be used to upgrade chips with or without existing firmware.
2. Obtaining the Code*
The OTA_SDK
is hosted on a private GitLab repository. Please read the Register GitLab Account guide and provide your GitLab account to our sales manager. Our project manager will then grant access to the code for your account.
2.1 Downloading the Code*
-
Go to the GitLab project and find the
uart_bootx_example
project. Copy the git address of the project as shown in the figure. -
Clone the code to your local machine:
$ git clone git@gitlab.com:nationalchip/ota_sdk.git
3. OTA SDK Architecture Overview*
-
Overview of various chips:
Leo : Including 8008/8009/8010, supports USB/UART transmission Leo mini: Including 8008c/8008b, supports USB/UART transmission Grus : Including 8002, supports UART/I2C transmission
-
Project structure:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
. ├── README.txt Help documentation ├── Makefile Compilation script ├── main.c Main program entry ├── main.md ├── bootfile Bootfile storage location, no need to modify during porting │ ├── grus-i2c.boot Boot file for grus I2C download │ ├── grus-uart.boot Boot file for grus UART download │ ├── leo_mini-uart.boot Boot file for leo mini UART download │ ├── leo_mini-usb.boot Boot file for leo mini USB download │ └── leo-uart.boot Boot file for leo UART download ├── common Common libraries, no need to modify during porting │ ├── crc.c │ └── misc.c ├── include Common header files, no need to modify during porting │ ├── i2c.h │ ├── misc.h │ ├── porting.h │ ├── uart.h │ └── usb.h ├── porting When porting to other platforms, implement corresponding porting APIs for the transmission method │ ├── porting_common.c Porting of PC-side common interfaces, needs to be implemented during porting │ ├── porting_i2c.c I2C API, needs to be implemented during porting │ ├── porting_i2c.h I2C header file, no need to modify during porting │ ├── porting_uart.c Uart API, needs to be implemented during porting │ ├── porting_uart.h Uart header file, no need to modify during porting │ ├── porting_usb.c USB API, needs to be implemented during porting │ ├── porting_usb.h USB header file, no need to modify during porting │ └── usb2i2c PC-side USB to I2C operation library, only used for PC-side demo, no need to be concerned during porting │ ├── ch34x_lib.c │ ├── ch34x_lib.h │ └── Linux_driver USB to I2C device Linux driver │ ├── ch34x_pis.c │ └── Makefile ├── i2c I2C download protocol, no need to modify during porting │ ├── i2c.c I2C download protocol code, no need to modify ├── uart UART download protocol, no need to modify during porting │ ├── uart.c UART download protocol code, no need to modify └── usb USB download protocol, no need to modify during porting ├── usb.c USB download protocol code, no need to modify
4. OTA UART Upgrade Instructions and Porting Steps*
4.1 Analysis of porting_uart.c
*
The porting_uart.c
file contains API functions for UART initialization, configuration, data reading, and writing. Below is an explanation of the API functions:
API Interface | API Description |
---|---|
int32_t nc_uart_init(void); | * nc_uart_init: UART initialization * return: Returns 0 for successful configuration, negative value for configuration failure |
int32_t nc_uart_done(void); | * nc_uart_done: Release UART resources * return: Returns 0 for successful configuration, negative value for configuration failure |
int32_t nc_uart_config(int32_t baudrate, int32_t databits, int32_t stopbits, int32_t parity); | * nc_uart_config: Configure UART baud rate and other information * @baudrate: Baud rate * @databits: Data bits * @stopbits: Stop bits * @parity: Parity * return: Returns 0 for successful configuration, negative value for configuration failure |
int32_t nc_uart_read(uint8_t *buf, int32_t len); | * nc_uart_read: Blocking receive UART data * @buf: Buffer for receiving UART data * @len: Expected length of received data * return: Returns the actual length of data received from UART, negative value in case of an error |
int32_t nc_uart_try_read(uint8_t *buf, int32_t len); | * nc_uart_try_read: Attempt to read data from UART (returns immediately) * @buf: Buffer for receiving UART data * @len: Expected length of received data * return: Returns the actual length of data received from UART, negative value in case of an error |
int32_t nc_uart_read_nonblock(uint8_t *buf, int32_t len, int32_t timeout_ms); | * nc_uart_read_nonblock: Read data from UART with a timeout * @buf: Buffer for receiving UART data * @len: Expected length of received data * @timeout_ms: Timeout setting * return: Returns the actual length of data received from UART, negative value in case of an error |
int32_t nc_uart_write(const uint8_t *buf, int32_t len); | * nc_uart_write: Write data to UART * @buf: Buffer for sending UART data * @len: Length of data to be sent * return: Returns the actual length of data sent via UART, negative value in case of an error |
4.2 UART Upgrade Process*
- Download Boot Files:
- The boot file download is divided into two stages: stage1 and stage2.
- Download Image Files:
- Download the image file to the specified address.
4.3 UART Upgrade Process Diagram*
- It is recommended to right-click on the link and open it in a new window.
4.4 UART Upgrade Method*
- Firmware Package Information Structure Explanation
typedef struct {
uint32_t addr; // Flash address where the firmware package is burned
uint8_t *buff; // Address of the firmware package data buffer
uint32_t buff_len; // Length of the firmware package data
uint32_t crc; // CRC checksum
} fw_t;
typedef struct {
int32_t fw_num; // Number of firmware packages (grus has one firmware package, Leo/Leo_mini have one or two firmware packages)
fw_t fw[0]; // Firmware package information structure
} fw_info_t;
Note
When porting streaming download interfaces, you don't need to worry about the firmware buffer address in the info
structure. You need to pass the flash address, firmware data length, and CRC checksum to the function, and the firmware data address is passed through the last two parameters to input the streaming firmware data and length. This part is different from non-streaming mode.
4.4.1 Non-Streaming UART Download Interface*
-
Non-streaming download: The entire boot file data packet and firmware package data exist on the host, and all data is passed to the download interface at once.
/************************************** * Function: Non-streaming UART download boot * boot: Boot file buffer address * len: Length of boot file data * return: 0 for success, -1 for failure **************************************/ int uart_sendboot(uint8_t *boot, int len) /************************************** * Function: Non-streaming UART download firmware * info: Firmware package information structure * return: 0 for success, -1 for failure **************************************/ int uart_download(fw_info_t *info)
4.4.2 Streaming UART Download Interface*
-
Streaming download: The boot file data and firmware package are not completely available on the host, but are sent chunk by chunk from other sources. At the beginning, the size of the entire firmware package and the flash address where the firmware is burned are needed.
/************************************** * Function: Streaming UART download boot * boot: Boot file buffer address passed in each time * len: Length of boot data buffer to be burned each time * return: 0 for success, -1 for failure **************************************/ int uart_sendboot_streaming(uint8_t *boot, int len) /************************************** * Function: Streaming UART download firmware * info: Firmware package information structure * data: Buffer address for burning firmware data each time * len: Length of firmware data buffer to be burned each time * return: 0 for success, -1 for failure **************************************/ int32_t uart_download_streaming(fw_info_t *info, uint8_t *data, uint32_t len)
4.5 UART Download Porting Steps*
- Implement
porting_uart.c
. - Call the
uart_sendboot
oruart_sendboot_streaming
interface to download the boot file. - Call the
uart_download
oruart_download_streaming
interface to download the firmware.
5. I2C Upgrade Instructions and Porting Steps*
- The main control chip/host communicates with the I2C address
0x36
by writing data and reading the specified register at address0x2f
to achieve the update interaction. It supports downloading firmware for empty chips.
5.1 Analysis of porting_i2c.c*
API Interface | API Description |
---|---|
int nc_i2c_init(void); | * nc_i2c_init : I2C initialization * return : Returns 0 on successful configuration, negative value on configuration failure |
int nc_i2c_write(unsigned char address, unsigned char* buf, int buf_len); | * nc_i2c_write : I2C send data. If I2C writing fails, it is recommended to continue repeating the write for a certain number of times until it succeeds or times out. * @address: Slave address * @buf: Data buffer to be written * @buf_len: Length of data to be written * return : Returns a value greater than 0 on success, 0 on send failure |
int nc_i2c_write_reg(unsigned char reg, unsigned char data); | * nc_i2c_write_reg : I2C write register * @reg: Register address to be written * @data: Character to be written * return : Returns 0 on success, negative value on configuration failure |
int nc_i2c_wait_reply(unsigned char address, unsigned char reg, unsigned char reply, int timeout); | * nc_i2c_wait_reply : I2C wait for reply * @address: Slave address * @reg: Register address * @reply: Character to wait for reply * @timeout: Timeout setting * return : Returns 0 on success, negative value on timeout |
5.2 I2C Upgrade Process*
- Download Boot Files:
- The boot file download is divided into two stages: stage1 and stage2.
- Download Image Files:
- Download the image file to the specified address.
5.3 I2C Upgrade Process Diagram*
- It is recommended to right-click on the link and open it in a new window.
5.4 I2C Upgrade Method*
-
Firmware Package Information Structure Explanation
typedef struct { uint32_t addr; // Flash address where the firmware package is burned uint8_t *buff; // Address of the firmware package data buffer uint32_t buff_len; // Length of the firmware package data uint32_t crc; // CRC checksum } fw_t; typedef struct { int32_t fw_num; // Number of firmware packages (grus has one firmware package, Leo/Leo_mini have one or two firmware packages) fw_t fw[0]; // Firmware package information structure } fw_info_t;
Note
When porting streaming download interfaces, you don't need to worry about the firmware buffer address in the info
structure. You need to pass the flash address, firmware data length, and CRC checksum to the function, and the firmware data address is passed through the last two parameters to input the streaming firmware data and length. This part is different from non-streaming mode.
5.4.1 i2c Non-Streaming Download Interface*
-
Non-streaming download: The entire boot file data packet and firmware package data exist on the host, and all data is passed to the download interface at once.
/************************************** * Function: i2c Non-streaming download boot * boot: Boot file buffer address * len: Length of boot file data * return: 0 for success, -1 for failure **************************************/ int32_t i2c_sendboot(uint8_t *buff, uint32_t len) /************************************** * Function: i2c Non-streaming download boot * info: Firmware package information structure * return: 0 for success, -1 for failure **************************************/ int32_t i2c_download(fw_info_t *info)
5.4.2 i2c Streaming Download Interface*
-
Streaming download: The boot file data and firmware package are not completely available on the host, but are sent chunk by chunk from other sources. At the beginning, the size of the entire firmware package and the flash address where the firmware is burned are needed.
/************************************** * Function: i2c Streaming download boot * boot: Boot file buffer address passed in each time * len: Length of boot data buffer to be burned each time * return: 0 for success, -1 for failure **************************************/ int32_t i2c_sendboot_streaming(uint8_t *boot, int len) /************************************** * Function: i2c Streaming download boot * info: Firmware package information structure * data: Buffer address for burning firmware data each time * len: Length of firmware data buffer to be burned each time * return: 0 for success, -1 for failure **************************************/ int32_t i2c_download_streaming(fw_info_t *info, uint8_t *data, uint32_t len)
5.5 i2c Upgrade Porting Steps*
- Implement
porting_i2c.c
. - Call the
i2c_sendboot
ori2c_sendboot_streaming
interface to download the boot file. - Call the
i2c_download
ori2c_download_streaming
interface to download the firmware.
6. OTA USB Upgrade Instructions and Porting Steps*
6.1 Analysis of porting_usb.c*
API Interface | API Description |
---|---|
int nc_usb_init(void); |
* nc_usb_init : USB initialization * return : Returns 0 on successful configuration, negative value on configuration failure |
void nc_usb_done(void); | * nc_usb_done : USB resource release |
int nc_usb_open(void); | * nc_usb_open : Open the USB device * return : Returns 0 on successful configuration, negative value on configuration failure |
void nc_usb_close(void); | * nc_usb_close : Close the USB device |
int nc_usb_rx(void *buf, int len); | * nc_usb_rx : USB receive data * @buf : Memory for receiving data * @len : Length of data to receive * return : Returns the actual length of received data |
int nc_usb_tx(void *buf, int len); | * nc_usb_tx : USB send data * @buf : Memory containing the data to send * @len : Length of data to send * return : Returns the actual length of sent data |
int nc_waituntildevicedisconnect(int timeout_s); | * nc_waituntildevicedisconnect : Timeout waiting for USB device disconnection * return : Returns 0 if the device disconnects within the timeout, negative value if the device remains connected within the timeout |
int nc_waituntildeviceconnect(int timeout_s); | * nc_waituntildeviceconnect : Timeout waiting for USB device connection * return : Returns 0 if the device connects within the timeout, negative value if the device remains disconnected within the timeout |
6.2 USB Upgrade Process*
- Download Boot Files:
- The boot file download is divided into two stages: stage1 and stage2.
- Download Image Files:
- Download the image file to the specified address.
6.3 USB Upgrade Process Diagram*
- It is recommended to right-click on the link and open it in a new window.
6.4 USB Upgrade Method*
-
Firmware Package Information Structure Explanation
typedef struct { uint32_t addr; // Flash address where the firmware package is burned uint8_t *buff; // Address of the firmware package data buffer uint32_t buff_len; // Length of the firmware package data uint32_t crc; // CRC checksum } fw_t; typedef struct { int32_t fw_num; // Number of firmware packages (grus has one firmware package, Leo/Leo_mini have one or two firmware packages) fw_t fw[0]; // Firmware package information structure } fw_info_t;
Note
When porting streaming download interfaces, you don't need to worry about the firmware buffer address in the info
structure. You need to pass the flash address, firmware data length, and CRC checksum to the function, and the firmware data address is passed through the last two parameters to input the streaming firmware data and length. This part is different from non-streaming mode.
6.4.1 USB Non-Streaming Download Interface*
-
Non-streaming download: The entire boot file data packet and firmware package data exist on the host, and all data is passed to the download interface at once.
/************************************** * Function: usb Non-streaming download boot * boot: Boot file buffer address * len : Length of boot file data * return: 0 for success, -1 for failure **************************************/ int32_t usb_sendboot(uint8_t *buff, uint32_t len) /************************************** * Function: usb Non-streaming download boot * info: Firmware package information structure * return: 0 for success, -1 for failure **************************************/ int32_t usb_download(fw_info_t *info)
6.4.2 USB Streaming Download Interface (Not Supported)*
- USB download currently does not support streaming download.
6.5 USB Upgrade Porting Steps*
- Implement
porting_usb.c
. - Call the
usb_sendboot
interface to download the boot file. - Call the
usb_download
interface to download the firmware.
7. OTA Verification Test*
Note
The provided code in this document can be compiled and run on the Linux PC platform, so the verification is also based on the Linux PC platform.
7.1 Select Boot File*
-
Boot file explanation:
- A runnable file downloaded to the chip from the host via USB/UART/I2C. The chip runs this file and interacts with the host to complete the download and other tasks.
-
Bootfile list:
grus-i2c.boot: Boot file for grus I2C download grus-uart.boot: Boot file for grus UART download leo_mini-uart.boot: Boot file for leo mini UART download leo_mini-usb.boot: Boot file for leo mini USB download leo-uart.boot: Boot file for leo UART download
-
When executing the executable file, input the chip model parameter. The program will automatically select the corresponding boot file.
Hint
If porting to a non-PC platform, you can convert the boot file to a C file and compile it into the program using the xxd
command.
$ xxd -i grus.boot > grus_boot.h
7.2 Compile and Generate Executable File*
- Execute
make clean; make
to generate./a.out
. - Then execute the executable file:
sudo ./a.out [chip_model] [download_method]
chip_model: grus / leo / leo mini download_method: uart / i2c / usb
- Chip-supported download methods:
Leo : Including 8008/8009/8010, supports USB/UART Leo mini : Including 8008c/8008b, supports USB/UART Grus : Including 8002, supports UART/I2C
- Example:
sudo ./a.out grus i2c
7.3 Burn Test*
Execute the following command for the burn test:
$ sudo ./a.out grus uart
UART PROTOCOL VERSION: V1.1.0
download_bootfile:309
please reboot the board
[ DBG]recv : f8
[ DBG]recv : 46
[ DBG]CRC SUCCESS
[ DBG]baud : 1500000
[ DBG]stage1 finished
[ DBG]stage2 finished
[ DBG]uart cmd : serialdown 0x0 102400 51200
[ DBG]uart cmd : serialdown 0x10000 102400 51200
Download finish
8. Notes*
- UART Usage:
Warning
The demo assumes /dev/ttyUSB0 as the default UART port. If it doesn't match, please modify nc_uart_init
to specify the correct serial port.
1. The default UART port is /dev/ttyUSB0. If it is different, please modify `nc_uart_init`.
2. Compile:
make
3. Execute:
./a.out grus uart
- I2C Usage:
1. Purchase the CH341TA USB-to-I2C device. Reference TB link: https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-1379463985.13.665333e6JZjkKZ&id=16318219421
2. Enter the porting/usb2i2c/Linux_driver directory and compile the driver:
make
3. Install the driver:
3.1 Uninstall the system's ch341 generic serial driver (not uninstalling may cause the USB serial device to be misidentified as a USB serial device):
sudo rmmod ch341
3.2 Install the current driver:
sudo modprobe usbserial
sudo insmod ch34x_pis.ko
4. Compile the program:
make
5. Test whether the program works properly:
sudo ./a.out grus i2c
- USB Usage:
1. Compile:
make
2. Execute:
sudo ./a.out leo_mini usb
- General Debugging Method:
Open DEBUG := -DDEBUG
in the Makefile to enable debugging output.