Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
tools-mirror
Micropython
提交
b41d08cf
M
Micropython
项目概览
tools-mirror
/
Micropython
12 个月 前同步成功
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
Micropython
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b41d08cf
编写于
2月 24, 2020
作者:
A
Andrew Leech
提交者:
Damien George
3月 22, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
stm32/mboot: Update dfu state/status flags to better match standard.
上级
03b1ed80
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
145 addition
and
79 deletion
+145
-79
ports/stm32/mboot/dfu.h
ports/stm32/mboot/dfu.h
+96
-0
ports/stm32/mboot/main.c
ports/stm32/mboot/main.c
+49
-79
未找到文件。
ports/stm32/mboot/dfu.h
0 → 100644
浏览文件 @
b41d08cf
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017-2019 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_STM32_MBOOT_DFU_H
#define MICROPY_INCLUDED_STM32_MBOOT_DFU_H
#include <stdint.h>
// DFU spec: https://www.usb.org/sites/default/files/DFU_1.1.pdf
#define DFU_XFER_SIZE (2048)
// DFU class requests
enum
{
DFU_DETACH
=
0
,
DFU_DNLOAD
=
1
,
DFU_UPLOAD
=
2
,
DFU_GETSTATUS
=
3
,
DFU_CLRSTATUS
=
4
,
DFU_GETSTATE
=
5
,
DFU_ABORT
=
6
,
};
// DFU States
typedef
enum
{
DFU_STATE_IDLE
=
2
,
DFU_STATE_BUSY
=
4
,
DFU_STATE_DNLOAD_IDLE
=
5
,
DFU_STATE_MANIFEST
=
7
,
DFU_STATE_UPLOAD_IDLE
=
9
,
DFU_STATE_ERROR
=
0xa
,
}
dfu_state_t
;
typedef
enum
{
DFU_CMD_NONE
=
0
,
DFU_CMD_EXIT
=
1
,
DFU_CMD_UPLOAD
=
7
,
DFU_CMD_DNLOAD
=
8
,
}
dfu_cmd_t
;
// Error status flags
typedef
enum
{
DFU_STATUS_OK
=
0x00
,
// No error condition is present.
DFU_STATUS_ERROR_TARGET
=
0x01
,
// File is not targeted for use by this device.
DFU_STATUS_ERROR_FILE
=
0x02
,
// File is for this device but fails some vendor-specific verification test.
DFU_STATUS_ERROR_WRITE
=
0x03
,
// Device is unable to write memory.
DFU_STATUS_ERROR_ERASE
=
0x04
,
// Memory erase function failed.
DFU_STATUS_ERROR_CHECK_ERASED
=
0x05
,
// Memory erase check failed.
DFU_STATUS_ERROR_PROG
=
0x06
,
// Program memory function failed.
DFU_STATUS_ERROR_VERIFY
=
0x07
,
// Programmed memory failed verification.
DFU_STATUS_ERROR_ADDRESS
=
0x08
,
// Cannot program memory due to received address that is out of range.
DFU_STATUS_ERROR_NOTDONE
=
0x09
,
// Received DFU_DNLOAD with wLength = 0, but device does not think it has all of the data yet.
DFU_STATUS_ERROR_FIRMWARE
=
0x0A
,
// Device's firmware is corrupt. It cannot return to run-time (non-DFU) operations.
DFU_STATUS_ERROR_VENDOR
=
0x0B
,
// iString indicates a vendor-specific error.
DFU_STATUS_ERROR_USBR
=
0x0C
,
// Device detected unexpected USB reset signaling.
DFU_STATUS_ERROR_POR
=
0x0D
,
// Device detected unexpected power on reset.
DFU_STATUS_ERROR_UNKNOWN
=
0x0E
,
// Something went wrong, but the device does not know what it was.
DFU_STATUS_ERROR_STALLEDPKT
=
0x0F
,
// Device stalled an unexpected request.
}
dfu_status_t
;
typedef
struct
_dfu_state_t
{
dfu_state_t
state
;
dfu_cmd_t
cmd
;
dfu_status_t
status
;
uint8_t
error
;
uint16_t
wBlockNum
;
uint16_t
wLength
;
uint32_t
addr
;
uint8_t
buf
[
DFU_XFER_SIZE
]
__attribute__
((
aligned
(
4
)));
}
dfu_context_t
;
static
dfu_context_t
dfu_context
SECTION_NOZERO_BSS
;
#endif // MICROPY_INCLUDED_STM32_MBOOT_DFU_H
ports/stm32/mboot/main.c
浏览文件 @
b41d08cf
...
...
@@ -33,6 +33,7 @@
#include "storage.h"
#include "i2cslave.h"
#include "mboot.h"
#include "dfu.h"
// Using polling is about 10% faster than not using it (and using IRQ instead)
// This DFU code with polling runs in about 70% of the time of the ST bootloader
...
...
@@ -905,113 +906,80 @@ uint8_t i2c_slave_process_tx_byte(void) {
/******************************************************************************/
// DFU
#define DFU_XFER_SIZE (2048)
enum
{
DFU_DNLOAD
=
1
,
DFU_UPLOAD
=
2
,
DFU_GETSTATUS
=
3
,
DFU_CLRSTATUS
=
4
,
DFU_ABORT
=
6
,
};
enum
{
DFU_STATUS_IDLE
=
2
,
DFU_STATUS_BUSY
=
4
,
DFU_STATUS_DNLOAD_IDLE
=
5
,
DFU_STATUS_MANIFEST
=
7
,
DFU_STATUS_UPLOAD_IDLE
=
9
,
DFU_STATUS_ERROR
=
0xa
,
};
enum
{
DFU_CMD_NONE
=
0
,
DFU_CMD_EXIT
=
1
,
DFU_CMD_UPLOAD
=
7
,
DFU_CMD_DNLOAD
=
8
,
};
typedef
struct
_dfu_state_t
{
int
status
;
int
cmd
;
uint16_t
wBlockNum
;
uint16_t
wLength
;
uint32_t
addr
;
uint8_t
buf
[
DFU_XFER_SIZE
]
__attribute__
((
aligned
(
4
)));
}
dfu_state_t
;
static
dfu_state_t
dfu_state
SECTION_NOZERO_BSS
;
static
void
dfu_init
(
void
)
{
dfu_
state
.
status
=
DFU_STATUS
_IDLE
;
dfu_
state
.
cmd
=
DFU_CMD_NONE
;
dfu_
state
.
addr
=
0x08000000
;
dfu_
context
.
state
=
DFU_STATE
_IDLE
;
dfu_
context
.
cmd
=
DFU_CMD_NONE
;
dfu_
context
.
addr
=
0x08000000
;
}
static
int
dfu_process_dnload
(
void
)
{
int
ret
=
-
1
;
if
(
dfu_
state
.
wBlockNum
==
0
)
{
if
(
dfu_
context
.
wBlockNum
==
0
)
{
// download control commands
if
(
dfu_
state
.
wLength
>=
1
&&
dfu_state
.
buf
[
0
]
==
0x41
)
{
if
(
dfu_
state
.
wLength
==
1
)
{
if
(
dfu_
context
.
wLength
>=
1
&&
dfu_context
.
buf
[
0
]
==
0x41
)
{
if
(
dfu_
context
.
wLength
==
1
)
{
// mass erase
ret
=
do_mass_erase
();
}
else
if
(
dfu_
state
.
wLength
==
5
)
{
}
else
if
(
dfu_
context
.
wLength
==
5
)
{
// erase page
uint32_t
next_addr
;
ret
=
do_page_erase
(
get_le32
(
&
dfu_
state
.
buf
[
1
]),
&
next_addr
);
ret
=
do_page_erase
(
get_le32
(
&
dfu_
context
.
buf
[
1
]),
&
next_addr
);
}
}
else
if
(
dfu_
state
.
wLength
>=
1
&&
dfu_state
.
buf
[
0
]
==
0x21
)
{
if
(
dfu_
state
.
wLength
==
5
)
{
}
else
if
(
dfu_
context
.
wLength
>=
1
&&
dfu_context
.
buf
[
0
]
==
0x21
)
{
if
(
dfu_
context
.
wLength
==
5
)
{
// set address
dfu_
state
.
addr
=
get_le32
(
&
dfu_state
.
buf
[
1
]);
dfu_
context
.
addr
=
get_le32
(
&
dfu_context
.
buf
[
1
]);
ret
=
0
;
}
}
}
else
if
(
dfu_
state
.
wBlockNum
>
1
)
{
}
else
if
(
dfu_
context
.
wBlockNum
>
1
)
{
// write data to memory
uint32_t
addr
=
(
dfu_
state
.
wBlockNum
-
2
)
*
DFU_XFER_SIZE
+
dfu_state
.
addr
;
ret
=
do_write
(
addr
,
dfu_
state
.
buf
,
dfu_state
.
wLength
);
uint32_t
addr
=
(
dfu_
context
.
wBlockNum
-
2
)
*
DFU_XFER_SIZE
+
dfu_context
.
addr
;
ret
=
do_write
(
addr
,
dfu_
context
.
buf
,
dfu_context
.
wLength
);
}
if
(
ret
==
0
)
{
return
DFU_STAT
US
_DNLOAD_IDLE
;
return
DFU_STAT
E
_DNLOAD_IDLE
;
}
else
{
return
DFU_STAT
US
_ERROR
;
return
DFU_STAT
E
_ERROR
;
}
}
static
void
dfu_handle_rx
(
int
cmd
,
int
arg
,
int
len
,
const
void
*
buf
)
{
if
(
cmd
==
DFU_CLRSTATUS
)
{
// clear status
dfu_state
.
status
=
DFU_STATUS_IDLE
;
dfu_state
.
cmd
=
DFU_CMD_NONE
;
dfu_context
.
state
=
DFU_STATE_IDLE
;
dfu_context
.
cmd
=
DFU_CMD_NONE
;
dfu_context
.
status
=
DFU_STATUS_OK
;
dfu_context
.
error
=
0
;
}
else
if
(
cmd
==
DFU_ABORT
)
{
// clear status
dfu_state
.
status
=
DFU_STATUS_IDLE
;
dfu_state
.
cmd
=
DFU_CMD_NONE
;
dfu_context
.
state
=
DFU_STATE_IDLE
;
dfu_context
.
cmd
=
DFU_CMD_NONE
;
dfu_context
.
status
=
DFU_STATUS_OK
;
dfu_context
.
error
=
0
;
}
else
if
(
cmd
==
DFU_DNLOAD
)
{
if
(
len
==
0
)
{
// exit DFU
dfu_
state
.
cmd
=
DFU_CMD_EXIT
;
dfu_
context
.
cmd
=
DFU_CMD_EXIT
;
}
else
{
// download
dfu_
state
.
cmd
=
DFU_CMD_DNLOAD
;
dfu_
state
.
wBlockNum
=
arg
;
dfu_
state
.
wLength
=
len
;
memcpy
(
dfu_
state
.
buf
,
buf
,
len
);
dfu_
context
.
cmd
=
DFU_CMD_DNLOAD
;
dfu_
context
.
wBlockNum
=
arg
;
dfu_
context
.
wLength
=
len
;
memcpy
(
dfu_
context
.
buf
,
buf
,
len
);
}
}
}
static
void
dfu_process
(
void
)
{
if
(
dfu_
state
.
status
==
DFU_STATUS
_MANIFEST
)
{
if
(
dfu_
context
.
state
==
DFU_STATE
_MANIFEST
)
{
do_reset
();
}
if
(
dfu_
state
.
status
==
DFU_STATUS
_BUSY
)
{
if
(
dfu_
state
.
cmd
==
DFU_CMD_DNLOAD
)
{
dfu_
state
.
cmd
=
DFU_CMD_NONE
;
dfu_
state
.
status
=
dfu_process_dnload
();
if
(
dfu_
context
.
state
==
DFU_STATE
_BUSY
)
{
if
(
dfu_
context
.
cmd
==
DFU_CMD_DNLOAD
)
{
dfu_
context
.
cmd
=
DFU_CMD_NONE
;
dfu_
context
.
state
=
dfu_process_dnload
();
}
}
}
...
...
@@ -1019,32 +987,34 @@ static void dfu_process(void) {
static
int
dfu_handle_tx
(
int
cmd
,
int
arg
,
int
len
,
uint8_t
*
buf
,
int
max_len
)
{
if
(
cmd
==
DFU_UPLOAD
)
{
if
(
arg
>=
2
)
{
dfu_
state
.
cmd
=
DFU_CMD_UPLOAD
;
uint32_t
addr
=
(
arg
-
2
)
*
max_len
+
dfu_
state
.
addr
;
dfu_
context
.
cmd
=
DFU_CMD_UPLOAD
;
uint32_t
addr
=
(
arg
-
2
)
*
max_len
+
dfu_
context
.
addr
;
do_read
(
addr
,
len
,
buf
);
return
len
;
}
}
else
if
(
cmd
==
DFU_GETSTATUS
&&
len
==
6
)
{
// execute command and get status
switch
(
dfu_
state
.
cmd
)
{
switch
(
dfu_
context
.
cmd
)
{
case
DFU_CMD_NONE
:
break
;
case
DFU_CMD_EXIT
:
dfu_
state
.
status
=
DFU_STATUS
_MANIFEST
;
dfu_
context
.
state
=
DFU_STATE
_MANIFEST
;
break
;
case
DFU_CMD_UPLOAD
:
dfu_
state
.
status
=
DFU_STATUS
_UPLOAD_IDLE
;
dfu_
context
.
state
=
DFU_STATE
_UPLOAD_IDLE
;
break
;
case
DFU_CMD_DNLOAD
:
dfu_
state
.
status
=
DFU_STATUS
_BUSY
;
dfu_
context
.
state
=
DFU_STATE
_BUSY
;
break
;
default:
dfu_context
.
state
=
DFU_STATE_BUSY
;
}
buf
[
0
]
=
0
;
buf
[
1
]
=
dfu_state
.
cmd
;
// TODO is this correct?
buf
[
2
]
=
0
;
buf
[
3
]
=
0
;
buf
[
4
]
=
dfu_
state
.
status
;
buf
[
5
]
=
0
;
buf
[
0
]
=
dfu_context
.
status
;
// bStatus
buf
[
1
]
=
0
;
// bwPollTimeout (ms)
buf
[
2
]
=
0
;
// bwPollTimeout (ms)
buf
[
3
]
=
0
;
// bwPollTimeout (ms)
buf
[
4
]
=
dfu_
context
.
state
;
// bState
buf
[
5
]
=
dfu_context
.
error
;
// iString
return
6
;
}
return
-
1
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录