当前位置: 首页 > news >正文

【GD32F303红枫派使用手册】第二十九节 USB-IAP升级实验

29.1 实验内容

通过本实验主要学习以下内容:

  • USB IAP升级操作

29.2 实验原理

USB IAP升级本例程中使用的是Custom HID中的IAP设备类,其设备类协议的实现与HID的类似,主要包括GET_REPORT/GET_IDLE/GET_PROTOCOL/SET_REPORT/SET_IDLE/SET_PROTOCOL/USB_GET_DESCRIPTOR等。IAP的功能为通过USB接口通信的方式对app端代码进行更新。

29.3 硬件设计

USB虚拟键盘实验章节已介绍。

29.4 代码解析

IAP主函数如下所示,开始主要为delay延迟配置以及按键配置,之后判断KEY1按键是否被按下,如果KEY1按键没被按下,将会进入到跳转代码段,如果APP_LOADED_ADDR(0x08008000U)地址中有对应APP的堆栈指针,则认为APP段有数据可直接跳转执行。如果堆栈指针校验异常,则跳出判断执行后续代码;如果KEY1按键被按下,则跳过跳转语句段,直接运行USB IAP的升级代码。通过RCU/USB等相关配置后,在PC端将会识别一个USB IAP设备。

C
int main(void)
{uint32_t app_address;app_func application;uint32_t sram_sect = REG32(APP_LOADED_ADDR);driver_init();/* configure KEY1 key to run firmware */bsp_key_init(&KEY1);/* KEY1 key must be pressed on board when power on */if(SET !=bsp_key_state_get(&KEY1)) {/* test if user code is programmed starting from address 0x8008000 */if((sram_sect >= SRAM_BASE_ADDR) && (sram_sect < SRAM_END_ADDR)){app_address = *(__IO uint32_t*) (APP_LOADED_ADDR + 4U);application = (app_func) app_address;/* initialize user application's stack pointer */__set_MSP(*(__IO uint32_t*) APP_LOADED_ADDR);/* jump to user application */application();}}/* system clocks configuration */rcu_config();/* GPIO configuration */gpio_config();/* USB device configuration */usbd_init(&usbd_iap, &iap_desc, &iap_class);/* NVIC configuration */nvic_config();/* enabled USB pull-up */usbd_connect(&usbd_iap);while (1){}
}

HID报文描述符如下所示,该报文描述符描述了收发数据类型以及长度,其中,主机发送的IAP命令和数据长度为63个字节,MCU从机回复的状态数据长度为16个字节。

C
const uint8_t iap_report_desc[USB_DESC_LEN_IAP_REPORT] =
{0x05, 0x01,     /* USAGE_PAGE (Generic Desktop) */0x09, 0x00,     /* USAGE (Custom Device)        */0xa1, 0x01,     /* COLLECTION (Application)     *//* IAP command and data */0x85, 0x01,     /* REPORT_ID (0x01)          */0x09, 0x01,     /* USAGE (IAP command)       */0x15, 0x00,     /* LOGICAL_MINIMUM (0)       */0x25, 0xff,     /* LOGICAL_MAXIMUM (255)     */0x75, 0x08,     /* REPORT_SIZE (8)           */0x95, 0x3f,     /* REPORT_COUNT (63)         */0x91, 0x82,     /* OUTPUT (Data,Var,Abs,Vol) *//* device status and option byte */  0x85, 0x02,     /* REPORT_ID (0x02)               */0x09, 0x02,     /* USAGE (Status and option byte) */0x15, 0x00,     /* LOGICAL_MINIMUM (0)            */0x25, 0xff,     /* LOGICAL_MAXIMUM (255)          */0x75, 0x08,     /* REPORT_SIZE (8)                */0x95, 0x10,     /* REPORT_COUNT (16)              */0x81, 0x82,     /* INPUT (Data,Var,Abs,Vol)       */0xc0            /* END_COLLECTION            */
};

MCU接收到主机发送的数据后,将会进入iap_data_out回调函数,其中实现了IAP download(数据下载)、IAP Erase(擦除操作)、IAP OPTION BYTE(获取选项字节)、IAP LEAVE(退出IAP模式)、IAP GETBIN ADDRESS(获取APP起始地址)几个功能。

C
static void iap_data_out (usb_dev *udev ,uint8_t ep_num)
{usbd_iap_handler *iap = (usbd_iap_handler *)udev->class_data[USBD_IAP_INTERFACE];if (0x01U == iap->report_buf[0]) {switch(iap->report_buf[1]) {case IAP_DNLOAD:iap_req_dnload(udev);break;case IAP_ERASE:iap_req_erase(udev);break;case IAP_OPTION_BYTE:iap_req_optionbyte(udev);break;case IAP_LEAVE:iap_req_leave(udev);break;case IAP_GETBIN_ADDRESS:iap_address_send(udev);break;default:break;}}usbd_ep_recev(udev, IAP_OUT_EP, iap->report_buf, IAP_OUT_PACKET);
}

29.5 实验结果

将本实验历程烧录到红枫派开发板中,打开GD32 ALL IN One上位机,如下图所示,接口选择USB,Bootloader协议选择IAP,之后点击connect进行连接。

 连接成功后,显示如下图所示,connect按钮变成disconnect,且在左下角显示芯片信息。 右侧栏目即为USB IAP可实现的功能,主要包括载升级代码,其他功能为灰色不能操作。点击Browse选择下载bin或者hex文件,之后点击download即可进行下载,下载完成后,进度条显示100%,即完成升级下载。

 由聚沃科技原创,来源于【红枫派开发板】第二十九讲 USB-IAP升级实验 - 苏州聚沃电子科技有限公司 (gd32bbs.com)

相关文章:

  • 工作日常学习记录
  • c++ primer plus 第15章友,异常和其他:友元类
  • 003 线程的暂停和中断
  • 接私活儿神器,一款功能强大的 SaaS 快速开发平台
  • 【ubuntu自启shell脚本】——在ubuntu中如何使用系统自带的启动应用程序设置开机自启自己的本地shell脚本
  • (笔记)M1使用hombrew安装qemu
  • Linux应用开发-第三章Linux的目录IO
  • 【Android】构建 Android Automotive OS:适合初学者的指南
  • 一文带你入门机器学习聚类算法
  • Owl 中的 Props 概述
  • 20240705 每日AI必读资讯
  • # windows 安装 mysql 显示 no packages found 解决方法
  • 使用 pyecharts 渲染成图片程序报错: echarts is not defined问题处理
  • SQL面试题练习 —— 求连续段的起始位置和结束位置
  • 51单片机第18步_将TIM0用作13位定时器
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Android交互
  • conda常用的命令
  • If…else
  • Java新版本的开发已正式进入轨道,版本号18.3
  • JS+CSS实现数字滚动
  • vagrant 添加本地 box 安装 laravel homestead
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 机器学习中为什么要做归一化normalization
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 如何解决微信端直接跳WAP端
  • 使用 Docker 部署 Spring Boot项目
  • 一个完整Java Web项目背后的密码
  • 阿里云服务器如何修改远程端口?
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • #13 yum、编译安装与sed命令的使用
  • #include到底该写在哪
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (八)Spring源码解析:Spring MVC
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (附源码)ssm高校实验室 毕业设计 800008
  • (十五)使用Nexus创建Maven私服
  • (四)Linux Shell编程——输入输出重定向
  • (算法)Game
  • (五)c52学习之旅-静态数码管
  • (一)python发送HTTP 请求的两种方式(get和post )
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .net core使用ef 6
  • .net 流——流的类型体系简单介绍
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • @staticmethod和@classmethod的作用与区别
  • [.net] 如何在mail的加入正文显示图片
  • []error LNK2001: unresolved external symbol _m
  • [android学习笔记]学习jni编程
  • [Ariticle] 厚黑之道 一 小狐狸听故事
  • [BZOJ 4598][Sdoi2016]模式字符串