联盛德 HLK-W806 (三): 免按键自动下载和复位
目录
- 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明
- 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明
- 联盛德 HLK-W806 (三): 免按键自动下载和复位
- 联盛德 HLK-W806 (四): 软件SPI和硬件SPI驱动ST7735液晶LCD
- 联盛德 HLK-W806 (五): W801开发板上手报告
免按键自动复位下载
如果只是了解如何使用, 看这部分就可以了. 在项目中将SDK更新到最新版本, 在SDK中找到这个文件 include/arch/xt804/csi_config.h, 将下面这行的值从0改成1
#define USE_UART0_AUTO_DL 0 // Auto download, 0:OFF, 1:ON
然后编译, 按正常的操作流程烧录到开发板. 之后的烧录就可以免按键自动下载了, 在下载前会自动复位, 下载后也会自动复位.
注意:
- 这个功能仅仅适用于开发和测试阶段, 不能用在生产环境.
- 这个功能(以及默认的printf打印)会占用UART0, 如果你的项目需要使用UART0与其它设备通信, 必须关闭这个功能
免按键下载的功能分析
烧录下载的指令分析
在tools/W806/rules.mk中
flash:all
@$(WM_TOOL) -c $(DL_PORT) -rs at -ds $(DL_BAUD) -dl $(FIRMWAREDIR)/$(TARGET)/$(TARGET).fls
可以看到make flash会先执行编译, 然后调用 wm_tool 根据预设的下载端口, 下载波特率, 将fls文件下载到设备. 在正常的下载过程中, 需要先复位开发板进入下载模式, 这时候才开始实际的下载, 下载结束后开发板会依然处于下载模式, 此时需要复位开发板进入普通模式, 运行用户程序. 现在这两步都是手工按Reset键完成的.
烧录下载复位的代码
在上面的命令中, 有一个参数是-rs at, 这个参数的说明是
-rs reset_action, set device reset method, default is manual control <none | at | rts>
none - manual control device reset
at - use the at command to control the device reset
rts - use the serial port rts pin to control the device reset
at对应的选项是使用AT命令去重启设备, 重启动作对应的有两处, 分别就是需要手工按Reset按钮的两个时间点.
下载前复位
对于下载前复位, wm_tool中的处理是
if (WM_TOOL_DL_ACTION_AT == wm_tool_dl_action)
{
if (WM_TOOL_DEFAULT_BAUD_RATE != wm_tool_normal_serial_rate)
wm_tool_uart_set_speed(wm_tool_normal_serial_rate);
#if 0 /* use erase option */
if (WM_TOOL_DL_TYPE_FLS == wm_tool_dl_type)
{
ret = wm_tool_uart_write("AT+&FLSW=8002000,0\r\n", strlen("AT+&FLSW=8002000,0\r\n"));
if (ret <= 0)
{
wm_tool_printf("destroy secboot failed.\r\n");
wm_tool_uart_close();
return -3;
}
wm_tool_delay_ms(300);
}
#endif
ret = wm_tool_uart_write("AT+Z\r\n", strlen("AT+Z\r\n"));
if (ret <= 0)
{
wm_tool_printf("reset error.\r\n");
wm_tool_uart_close();
return -4;
}
if (WM_TOOL_DEFAULT_BAUD_RATE != wm_tool_normal_serial_rate)
wm_tool_uart_set_speed(WM_TOOL_DEFAULT_BAUD_RATE);
}
...
wm_tool_printf("wait serial sync...");
wm_tool_send_esc2uart(500);/* used for delay */
可以看到wm_tool的实际操作是通过串口发出AT+Z\r\n指令, 然后等待500ms再检测是否复位
下载后复位
对于下载后的复位, 在代码中只处理了rts选项, 这里使用at选项是无动作的
...
if (WM_TOOL_DL_TYPE_FLS == wm_tool_dl_type)
{
if (WM_TOOL_DL_ACTION_RTS == wm_tool_dl_action)/* auto reset */
{
wm_tool_uart_set_dtr(0);
wm_tool_uart_set_rts(1);
wm_tool_delay_ms(50);
wm_tool_uart_set_dtr(1);
wm_tool_uart_set_rts(0);
wm_tool_delay_ms(50);
wm_tool_uart_set_dtr(0);
}
else
{
wm_tool_printf("please manually reset the device.\r\n");
}
}
...
W806的烧录自动复位实现
根据上面的分析, W806的自动复位需要实现两处, 一处是下载前, 一处是下载完成后
下载前的复位实现
下载前开发板还运行在普通模式, 此时串口由用户程序控制, 如果需要响应串口命令, 需要在用户程序中添加串口0的RX中断和命令判断. 这一步可以参考SDK中UART0作为printf打印输出的实现
增加UART0初始化
在 platform/arch/xt804/bsp/board_init.c 中增加初始化代码, 当配置为开启时, 开启UART0接收中断
...
static void uart0Init (int bandrate)
{
unsigned int bd;
#if USE_UART0_AUTO_DL
WRITE_REG(UART0->INTM, ~UART_RX_INT_FLAG);
NVIC_ClearPendingIRQ(UART0_IRQn);
NVIC_EnableIRQ(UART0_IRQn);
#else
NVIC_DisableIRQ(UART0_IRQn);
NVIC_ClearPendingIRQ(UART0_IRQn);
#endif
...
}
增加UART0接收中断响应和命令检测
在 platform/component 下新增一个组件, 在组件中实现中断响应和命令检测
/******************************************************************************
**
* \file auto_dl.c
* \author Xu Ruijun | 1687701765@qq.com
* \date
* \brief Reset device with UART0 AT+Z command
* \note Set USE_UART0_AUTO_DL = 1 to enable this feature
* \version
* \ingroup
* \remarks
*
******************************************************************************/
#include "wm_hal.h"
#if USE_UART0_AUTO_DL
#define __AUTO_DL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->INTS |= __FLAG__)
#define __AUTO_DL_TIMEOUT 5
#define __AUTO_DL_BUF_SIZE 32
const static uint8_t auto_dl_cmd[] = {'A', 'T', '+', 'Z', '\r', '\n'};
uint8_t auto_dl_buf[__AUTO_DL_BUF_SIZE] = {0}, auto_dl_buf_pt = 0, auto_dl_cmd_pt = 0;
uint32_t auto_dl_act_ts = 0;
void AUTO_DL_Reset(void)
{
CLEAR_REG(RCC->RST); // reset all peripherals
uint32_t rv = *(uint32_t*)(0x00000000U); // get reset vector
((void (*)())(rv))(); // go to ROM
}
__attribute__((weak)) void USER_UART0_RX(uint8_t ch)
{
UNUSED(ch);
}
void AUTO_DL_UART_IRQHandler(USART_TypeDef* huart)
{
uint8_t ch, count;
uint32_t ts, isrflags = READ_REG(huart->INTS), isrmasks = READ_REG(huart->INTM);
// Clear interrupts
__AUTO_DL_UART_CLEAR_FLAG(huart, isrflags);
if (((isrflags & UART_RX_INT_FLAG) != RESET) && ((isrmasks & UART_RX_INT_FLAG) == RESET))
{
/**
* 1) Data always comes in as single bytes, so the count is always 1(or 0);
* 2) Each byte will comes in twice, the second time with count=0 will be ignored;
*/
count = ((READ_REG(huart->FIFOS) & UART_FIFOS_RFC) >> UART_FIFOS_RFC_Pos);
while (count-- > 0)
{
// Write ch to ring buffer
ch = (uint8_t)(huart->RDW);
auto_dl_buf[auto_dl_buf_pt++] = ch;
if (auto_dl_buf_pt == __AUTO_DL_BUF_SIZE) auto_dl_buf_pt = 0;
// Command detection
ts = HAL_GetTick();
if ((ts - auto_dl_act_ts) > __AUTO_DL_TIMEOUT)
{
// Restart the comparison if timeout
auto_dl_cmd_pt = 0;
if (auto_dl_cmd[auto_dl_cmd_pt] == ch)
{
auto_dl_cmd_pt++;
}
}
else
{
// Avoid starting new comparison in the middle of RX
if ((auto_dl_cmd[auto_dl_cmd_pt] == ch) && (auto_dl_cmd_pt > 0))
{
auto_dl_cmd_pt++;
if (auto_dl_cmd_pt == sizeof(auto_dl_cmd))
{
AUTO_DL_Reset();
}
}
else
{
// Restart the comparison
auto_dl_cmd_pt = 0;
}
}
// Record last active timestamp
auto_dl_act_ts = ts;
USER_UART0_RX(ch);
}
}
if (((isrflags & UART_INTS_TL) != RESET) && ((isrmasks & UART_INTM_RL) == RESET))
{
//UART_Transmit_IT(huart);
}
if (((isrflags & UART_INTS_TEMPT) != RESET) && ((isrmasks & UART_INTM_TEMPT) == RESET))
{
//UART_EndTransmit_IT(huart);
}
}
__attribute__((isr)) void UART0_IRQHandler(void)
{
AUTO_DL_UART_IRQHandler(UART0);
}
#endif
下载成功后的复位实现
下载成功后, 开发板还运行在下载模式, 因此找到下载模式下对应复位的命令就可以了, 这个命令是
0x21, 0x06, 0x00, 0xc7, 0x7c, 0x3f, 0x00, 0x00, 0x00
对应的, 在 wm_tool.c中增加这个命令常量
const static unsigned char wm_tool_chip_cmd_reset[] = {0x21, 0x06, 0x00, 0xc7, 0x7c, 0x3f, 0x00, 0x00, 0x00};
和对AT模式的处理逻辑
if (WM_TOOL_DL_TYPE_FLS == wm_tool_dl_type)
{
if (WM_TOOL_DL_ACTION_RTS == wm_tool_dl_action) // Use UART RTS pin to control the device reset
{
...
}
else if(WM_TOOL_DL_ACTION_AT == wm_tool_dl_action) // Use AT command to reset the device
{
wm_tool_delay_ms(500);
ret = wm_tool_uart_write(wm_tool_chip_cmd_reset, sizeof(wm_tool_chip_cmd_reset));
wm_tool_delay_ms(30);
if(ret > 0){
wm_tool_printf("reset command has been sent.\r\n");
}else{
wm_tool_printf("reset command sending failed.\r\n");
}
ret = 0;
}
...
}
联盛德 HLK-W806 (三): 免按键自动下载和复位的更多相关文章
- 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (五): W801开发板上手报告
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (四): 软件SPI和硬件SPI驱动ST7735液晶LCD
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (六): I2C驱动SSD1306 128x64 OLED液晶屏
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (八): 4线SPI驱动SSD1306/SSD1315 128x64 OLED液晶屏
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (七): 兼容开发板 LuatOS Air103
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (十): 在 CDK IDE开发环境中使用WM-SDK-W806
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (九): 软件SPI和硬件SPI驱动ST7789V液晶LCD
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
随机推荐
- Egg.js学习与实战系列 · Post请求`csrf token`问题
在使用axios请求egg.js封装的post接口时出现missing csrf token 或 invalid csrf token.踩过坑的新手估计不在少数,本篇记录一下解决方法. 问题原因 引用 ...
- Noip模拟18 2021.7.17 (文化课专场)
T1 导弹袭击(数学) 显然,我们要找到最优的A,B使得一组a,b优于其他组那么可以列出: $\frac{A}{a_i}+\frac{B}{b_i}<\frac{A}{a_j}+\frac{B} ...
- ShardingSphere-初见
目录 概述 认识shardingjdbc shardingjdbc功能架构图 认识Sharding-Proxy 三个组件的比较 ShardingJdbc混合架构 ShardingShpere的功能清单 ...
- 最近公共祖先(lca)与树上叉分
lca的定义不在过多解释, 代码如下: inline void bfs() { queue<int>q; deep[s]=1;q.push(s); while(!q.empty()) { ...
- openssh 7.4 升级 8.3
1.删除旧版本(如果是远程连接升级,不能卸载旧版本,否则连接会断开.安装8.3完也不能卸载7.4,否则要到服务器直连重新安装8.3.) # rpm -qa |grep openssh #rpm -e ...
- linux系列之: 你知道查看文件空间的两种方法吗?
目录 简介 du命令 df命令 总结 简介 linux系统中查看文件空间大小应该是一个非常常见的命令了,今天给大家介绍linux系统中查看文件空间的两种方法和在使用中可能会遇到的奇怪问题. 为什么会有 ...
- JavaScript 简单介绍
一.简介 JavaScript是一门面向对象的动态语言,他一般用来处理以下任务: 修饰网页 生成HTML和CSS 生成动态HTML内容 生成一些特效 提供用户交互接口 生成用户交互组件 验证用户输入 ...
- 服务端渲染技术NUXT
什么是服务端渲染 服务端渲染又称SSR (Server Side Render),是在服务端完成页面的内容,而不是在客户端通过AJAX获取数据. 服务器端渲染(SSR)的优势主要在于:更好的 SE ...
- Windows内核中的CPU架构-7-陷阱门(32-Bit Trap Gate)
Windows内核中的CPU架构-7-陷阱门(32-Bit Trap Gate) 陷阱门和中断门几乎是一模一样的: (注:图里高32位中的第11位的值为D,其实是1) 除了高32位中的type字段的内 ...
- 浏览器调用接口正常,jmeter调不通的可能原因
首先,还是http状态码介绍(网上都能找到这些简介): 1xx 信息,服务器收到请求,需要请求者继续执行操作 2xx 成功,操作被成功接收并处理 3xx 重定向,需要进一步的操作以完成请求 4xx 客 ...