WIOTA UBOOT API
本文含有两部分,分别介绍基站侧(ap)和终端侧(iote)有关uboot的相关接口。
1. 基站(AP)
以下接口在头文件名:uc_uboot.h中声明。
1.1 获取uboot版本
-
目的
获取uboot版本。 -
语法
void boot_get_version(char *version);
-
描述
获取uboot版本。 -
返回值
无。 -
参数
version
:最小四字节空间。
1.2 设置uboot工作模式
-
目的
设置工作模式 -
原型
void boot_set_mode(unsigned int modem);
-
描述
uboot工作模式见模式介绍。 -
返回值
无。 -
参数
modem
:字符 a-g,即对应97-103。
1.3 获取uboot工作模式
-
目的
获取uboot工作模式。 -
原型
unsigned char boot_get_mode(void);
-
描述
uboot工作模式见模式介绍。 - 返回值
unsigned char //返回工作模式 a-g
- 参数
无。
1.4 设置OTA文件长度
-
目的
设置写入的镜像文件长度。 -
原型
void boot_set_file_size(unsigned int len);
-
描述
设置写入下载区的数据长度。 -
返回值
无。 -
参数
len
:文件大小
注:该函数需要手动添加声明。
1.5 获取OTA文件长度
- 目的
获取写入的镜像文件长度。 -
原型
unsigned int boot_get_file_size(void);
-
描述
获取写入下载区的数据长度。 - 返回值
unsigned int
- 参数
无。
注:该函数需要手动添加声明。
1.6 设置riscv重启
-
目的
实现不重置共享数据区的系统重启。 -
原型
void boot_riscv_reboot(void);
-
描述
不重置共享数据区的一种重启方式。 - 返回值
无。 - 参数
无。
1.7 设置串口0波特率
-
目的
设置uart0串口的波特率。 -
原型
void boot_set_uart0_baud_rate(unsigned int baud_rate);
-
描述
设置uart0串口的波特率,默认115200。 -
返回值
无。 -
参数
baud_rate
:波特率。
1.8 设置UBOOT日志输出口
-
目的
指定日志输出口。 -
原型
void boot_set_uart_flag(unsigned char flag);
-
描述
指定日志输出口,相关参数只能设置0或1。 -
返回值
无。 -
参数
flag
:指定日志输出口,0 uart0, 1 uart1。
1.9 获取UBOOT日志输出口
-
目的
获取uboot的日志输出口。 -
原型
unsigned char boot_get_uart_flag(void);
-
描述
获取uboot的日志输出口,相关参数值为0或1。 -
返回值
unsigned char
-
参数
无。
1.10 设置UBOOT日志标记
-
目的
打开或者关闭uboot的日志标记。 -
原型
void boot_set_log_flag(unsigned char flag);
-
描述
打开或者关闭uboot的日志标记,相关参数只能设置0或1。 -
返回值
无。 -
参数
flag
:日志输出开关,0 开启,1 关闭。
1.11 获取UBOOT日志标记
-
目的
获取uboot的日志标记。 -
原型
unsigned char boot_get_log_flag(void);
-
描述
获取uboot的日志标记,相关参数值为0或1。 -
返回值
unsigned char
- 参数
无。
1.12 设置UBOOT菜单输出开关
-
目的
打开或者关闭uboot的菜单输出开关。 -
原型
void boot_set_select_flag(unsigned char flag);
-
描述
打开或者关闭uboot的菜单输出开关,相关参数只能设置0或1。 -
返回值
无。 -
参数
flag
:菜单输出开关,0 关闭,1 开启。
1.13 获取UBOOT菜单输出开关
-
目的
获取uboot的菜单输出开关。 -
原型
unsigned char boot_get_select_flag(void);
- 描述
获取uboot的菜单输出开关,相关参数值为0或1。 - 返回值
unsigned char
- 参数
无。
1.14 二次开发示例
1.14.1 概述
该示例模拟AP端进行OTA升级,涉及到的流程是a->b,即OTA文件下载后再升级,模式参考。
默认该DEMO为关闭状态,打开需要添加宏定义如下:
#define WIOTA_AP_UBOOT_OTA_TEST
在main.c文件中添加头文件:
#include "test_wiota_uboot_ota.h"
同时在main()函数中调用下列函数:
uboot_reflash_update_test();
1.14.2 生成ota_data
下载的ota_data的内容是OTA差分文件内容,使用OTA_TOOL工具,生成ota_data时,需要选择镜像文件的差分区域,如何选择参考,此处只勾选uboot部分(只选这个块是为了演示差分升级的过程,不明确哪些块参与到ota升级时应全部勾选),然后鼠标左击Generate生成.patch文件,如下:
把生成的.patch文件中的内容添加到ota_data里去,请注意大小端的问题,flash使用大端模式存储数据。
1.14.3 源码
/******************************************************************************
* @file test_wiota_uboot_ota.c
* @brief Simulate OTA upgrade
* @author ypzhang
* @version 1.0
* @date 2023.12.20
*
* @copyright Copyright (c) 2018 UCchip Technology Co.,Ltd. All rights reserved.
*
******************************************************************************/
#include "uc_wiota_api.h"
#include "uc_uboot.h"
#include "partition_info.h"
#include "rthw.h"
#ifdef WIOTA_AP_UBOOT_OTA_TEST
void uboot_reflash_update_test( void)
{
int ota_data_size;
//模拟的数据文件
// 06 00 00 1B 01 00 70 00 00 00 00 E5 B8 01 00 00 00 10 F2 00 00 70 04 E0 04 6F F9 文件.patch里的顺序
unsigned char ota_data[28] = { 0x1B, 0x00, 0x00, 0x06,
0x00, 0x70, 0x00, 0x01,
0xE5, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xB8,
0x00, 0xF2, 0x10, 0x00,
0xE0, 0x04, 0x70, 0x00,
0x00, 0xF9, 0x6F, 0x04}; // 0X00补齐
unsigned int address = UC_OTA_PARTITION_START_ADDRESS; // 写flash地址
ota_data_size = sizeof(ota_data) - 1;
// 如果 数据大小超过限制,退出
if (ota_data_size > MAX_DOWN_FILE_8088)
{
return 0;
}
//分页
unsigned int num = ota_data_size / FLASH_PAGE_LEN;
/*
// 写整数倍的完全页
for (int i = 0; i < num; i++)
{
// 先擦再写
uc_wiota_flash_erase_4K(address);
uc_wiota_flash_write((unsigned char*)ota_data + i * FLASH_PAGE_LEN,
address,
FLASH_PAGE_LEN);
address += FLASH_PAGE_LEN;
}
*/
//写不足一页的数据
uc_wiota_flash_erase_4K(address);
uc_wiota_flash_write((unsigned char*)ota_data + num * FLASH_PAGE_LEN,
address,
ota_data_size % FLASH_PAGE_LEN);
// 设置数据文件长度
boot_set_file_size(ota_data_size);
// 设置uboot启动模式
boot_set_mode('b');
// 关闭相关中断
rt_hw_interrupt_disable();
// 软重启
boot_riscv_reboot();
}
#endif // WIOTA_AP_UBOOT_OTA_TEST
2. 终端(IOTE)
以下接口在头文件名:uc_uboot.h中声明。
2.1 获取uboot版本
-
目的
获取uboot版本。 -
语法
void get_uboot_version(unsigned char *version);
-
描述
获取uboot版本。 -
返回值
无。 -
参数
version
:最小四字节空间。
2.2 设置uboot工作模式
-
目的
设置工作模式 -
原型
void set_uboot_mode(unsigned char mode);
-
描述
uboot工作模式见模式介绍。 -
返回值
无。 -
参数
mode
:字符 a-g,即对应97-103。 -
注:目前iote仅支持a,b,g三种工作模式
2.3 获取uboot工作模式
-
目的
获取uboot工作模式。 -
原型
void get_uboot_mode(unsigned char *mode);
- 描述
uboot工作模式见模式介绍。 - 返回值
无。 - 参数
mode
:字符 a-g,即对应97-103。
2.4 设置OTA文件长度
-
目的
设置写入的镜像文件长度。 -
原型
void set_download_file_size(int file_size);
-
描述
设置写入下载区的数据长度。 -
返回值
无。 -
参数
file_size
:文件大小
注:该函数需要手动添加声明。
2.5 获取OTA文件长度
- 目的
获取写入的镜像文件长度。 - 原型
void get_download_file_size(int *file_size);
-
描述
获取写入下载区的数据长度。 -
返回值
无。 -
参数
file_size
:文件大小
注:该函数需要手动添加声明。
2.6 设置riscv重启
-
目的
实现不重置共享数据区的系统重启。 -
原型
void boot_riscv_reboot(void);
- 描述
不重置共享数据区的一种重启方式。 - 返回值
无。 - 参数
无。
2.7 设置分区大小
-
目的 自定义每个分区大小。
-
语法
void set_partition_size(int bin_size , int reserved_size , int ota_size)
-
描述 bin_size:系统区大小,默认300KB。 reserved_size:备份区大小,默认112KB。 ota_size:下载区大小,默认92KB。差分包最大支持92KB。 分区介绍见分区介绍
-
返回值 无。
-
参数
bin_size
:系统区大小。reserved_size
:备份区大小。ota_size
:下载区大小。
2.8 获取分区大小
-
目的 获取每个分区大小。
-
语法
void get_partition_size(int * bin_size,int * reserved_size,int * ota_size)
- 描述 获取各个分区大小。
- 返回值 无。
- 参数
bin_size
:系统区大小,默认300KB。reserved_size
:备份区大小,默认112KB。ota_size
:下载区大小,默认92KB。差分包最大支持92KB。
2.9 设置串口0波特率
-
目的
设置uart0串口的波特率。 -
原型
void set_uboot_baud_rate(int baud_rate);
-
描述
设置uart0串口的波特率,默认115200。 -
返回值
无。 -
参数
baud_rate
:波特率。
2.10 获取串口0波特率
-
目的
获取uart0串口的波特率。 -
原型
void get_uboot_baud_rate(int *baud_rate);
-
描述
获取uart0串口的波特率,默认115200。 -
返回值
无。 -
参数
baud_rate
:波特率。
2.11 设置UBOOT日志标记
-
目的
打开或者关闭uboot的日志标记。 -
原型
void set_uboot_log(unsigned char uart_flag,
unsigned char log_flag,
unsigned char select_flag);
-
描述
打开或者关闭uboot的日志标记,相关参数只能设置0或1。 -
返回值
无。 -
参数
uart_flag
:指定日志输出口,0 uart0, 1 uart1。
log_flag
:日志输出开关,0 开启,1 关闭。
select_flag
:菜单输出开关,0 关闭,1 开启。
2.12 设置UBOOT菜单等待时长
- 目的
设置UBOOT菜单等待时长,单位:秒。
- 原型
void set_uboot_wait_sec(unsigned char wait_sec);
-
描述
当打开UBOOT日志标记后,菜单可见,通过调用该接口设置等待输入的时长,单位:秒。
-
返回值
无。
-
参数
wait_sec
:等待时长,单位:秒。 -
出现版本
同步3.0后支持该函数,异步3.03后支持该函数。
2.13 获取UBOOT菜单等待时长
- 目的
获取UBOOT菜单等待时长,单位:秒。
- 原型
unsigned char get_uboot_wait_sec();
-
描述
获取UBOOT菜单等待时长,单位:秒。
-
返回值
等待时长,单位:秒。
-
参数
无。
-
出现版本
同步3.0后支持该函数,异步3.03后支持该函数。
2.14 二次开发示例
2.14.1 概述
该示例模拟IOTE端进行OTA升级,涉及到的流程是a->b,模式参考。该示例支持同步和异步,如果测试异步,则需要定义宏UBOOT_OTA_UPDATE_ASYNC。
默认该DEMO为关闭状态,打开需要添加宏定义如下:
#define WIOTA_IOTE_UBOOT_TEST
在main.c文件中添加头文件:
#include "test_wiota_uboot_ota.h"
同时在main()函数中调用下列函数:
uboot_reflash_test();
2.14.2 生成ota_data
参考.
2.14.3 源码
/******************************************************************************
* @file test_wiota_uboot_ota.c
* @brief Simulate OTA upgrade
* @author ypzhang
* @version 1.0
* @date 2023.12.20
*
* @copyright Copyright (c) 2018 UCchip Technology Co.,Ltd. All rights reserved.
*
******************************************************************************/
#include "uc_wiota_api.h"
#ifdef WIOTA_IOTE_UBOOT_TEST
#define FLASH_ERASE_SIZE (4096)
#define FLASH_WRITE_LEN (256)
// #define UBOOT_OTA_UPDATE_ASYNC // 是异步ota升级
#define BOOT_RUN_OTA_ONLY_UPDATE 'b'
#ifdef UBOOT_OTA_UPDATE_ASYNC
/**
* @brief 异步接收开关控制
* @param[IN] enable 0 关闭, 1打开
* @return int 0 正常, 1 错误
*/
static int wiota_async_recv_ctrl(int enable)
{
int count = 0;
if (enable)
{
uc_wiota_set_recv_mode(UC_AUTO_RECV_START);
}
else
{
uc_wiota_set_recv_mode(UC_AUTO_RECV_STOP);
rt_thread_delay(uc_wiota_get_subframe_len() >> 1);
while ((uc_wiota_get_physical_status() != RF_STATUS_IDLE)
|| (uc_wiota_get_state() != UC_STATUS_NULL))
{
count++;
if (count > 200)
{
// 等待超时
return 1;
}
rt_thread_delay(5);
}
}
return 0;
}
#endif // UBOOT_OTA_UPDATE_ASYNC
void uboot_reflash_test(void)
{
int i;
int bin_size;
int reserved_size;
int ota_size;
int ota_data_size;
int write_count = FLASH_WRITE_LEN;
// OTA分区首地址
int ota_addr;
// 模拟的数据文件
// 05 00 00 1B 01 00 70 00 00 00 00 0F FF 01 00 00 00 10 F2 00 00 70 04 E0 04 6F F9 文件.patch里的顺序
u8_t ota_data[28] = {0x1B, 0x00, 0x00, 0x05,
0x00, 0x70, 0x00, 0x01,
0x0F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xFF,
0x00, 0xF2, 0x10, 0x00,
0xE0, 0x04, 0x70, 0x00,
0x00, 0xF9, 0x6F, 0x04}; // 0X00补齐
ota_data_size = sizeof(ota_data) - 1;
get_partition_size(&bin_size, &reserved_size, &ota_size);
ota_addr = bin_size + reserved_size;
rt_kprintf("bin_size = %d , reserved_size = %d, ota_size = %d, ota_addr = %d\n", bin_size, reserved_size, ota_size, ota_addr);
// bin_size = 307200 (4B000) , reserved_size = 147456 (24000), ota_size = 61440 (F000), ota_addr = 454656 (6F000)
if (ota_data_size > ota_size)
{
rt_kprintf("ota_data_size > ota_size!!! return");
return;
}
#ifdef UBOOT_OTA_UPDATE_ASYNC
// 异步接收关闭
wiota_async_recv_ctrl(0);
#else
// 同步接收关闭
uc_wiota_suspend_connect();
#endif // UBOOT_OTA_UPDATE_ASYNC
// 先擦再写
for (i = 0; i < ota_size; i += FLASH_ERASE_SIZE)
{
uc_wiota_flash_erase_4K(ota_addr + i);
}
// 写OTA数据
for (i = 0; i < ota_data_size;)
{
uc_wiota_flash_write(&ota_data[i], ota_addr + i, write_count);
i += write_count;
write_count = ((ota_data_size - i) >= (int)FLASH_WRITE_LEN) ?
FLASH_WRITE_LEN : (ota_data_size - i);
}
// 设置OTA文件大小
set_download_file_size(ota_data_size);
// 设置uboot工作模式
set_uboot_mode(BOOT_RUN_OTA_ONLY_UPDATE);
#ifdef UBOOT_OTA_UPDATE_ASYNC
// 异步接收打开
wiota_async_recv_ctrl(1);
#else
// 同步接收打开
uc_wiota_recover_connect();
#endif // UBOOT_OTA_UPDATE_ASYNC
// 关闭相关中断
rt_hw_interrupt_disable();
// 重启
boot_riscv_reboot();
}
#endif // WIOTA_IOTE_UBOOT_TEST