4
4
5
5
'''Runner for flashing with dfu-util.'''
6
6
7
+ from collections import namedtuple
8
+ import os
7
9
import sys
8
10
import time
9
11
10
- from .core import ZephyrBinaryRunner , RunnerCaps
12
+ from .core import ZephyrBinaryRunner , RunnerCaps , BuildConfiguration
13
+
14
+
15
+ DfuSeConfig = namedtuple ('DfuSeConfig' , ['address' , 'options' ])
11
16
12
17
13
18
class DfuUtilBinaryRunner (ZephyrBinaryRunner ):
14
19
'''Runner front-end for dfu-util.'''
15
20
16
- def __init__ (self , pid , alt , img , dfuse = None , exe = 'dfu-util' , debug = False ):
21
+ def __init__ (self , pid , alt , img , exe = 'dfu-util' ,
22
+ dfuse_config = None , debug = False ):
17
23
super (DfuUtilBinaryRunner , self ).__init__ (debug = debug )
18
24
self .alt = alt
19
25
self .img = img
20
- self .dfuse = dfuse
21
26
self .cmd = [exe , '-d,{}' .format (pid )]
22
27
try :
23
28
self .list_pattern = ', alt={},' .format (int (self .alt ))
24
29
except ValueError :
25
30
self .list_pattern = ', name="{}",' .format (self .alt )
26
31
32
+ if dfuse_config is None :
33
+ self .dfuse = False
34
+ else :
35
+ self .dfuse = True
36
+ self .dfuse_config = dfuse_config
37
+
27
38
@classmethod
28
39
def name (cls ):
29
40
return 'dfu-util'
30
41
31
42
@classmethod
32
43
def capabilities (cls ):
33
- return RunnerCaps (commands = {'flash' })
44
+ return RunnerCaps (commands = {'flash' }, flash_addr = True )
34
45
35
46
@classmethod
36
47
def do_add_parser (cls , parser ):
@@ -43,18 +54,27 @@ def do_add_parser(cls, parser):
43
54
# Optional:
44
55
parser .add_argument ("--img" ,
45
56
help = "binary to flash, default is --kernel-bin" )
46
- parser .add_argument ("--dfuse-addr " , default = None ,
47
- help = '''target address if the board is a DfuSe
48
- device; ignored it not present ''' )
57
+ parser .add_argument ("--dfuse" , default = False , action = 'store_true' ,
58
+ help = '''set if target is a DfuSe device;
59
+ implies --dt-flash. ''' )
49
60
parser .add_argument ('--dfu-util' , default = 'dfu-util' ,
50
61
help = 'dfu-util executable; defaults to "dfu-util"' )
51
62
52
63
@classmethod
53
64
def create_from_args (cls , args ):
54
65
if args .img is None :
55
66
args .img = args .kernel_bin
67
+
68
+ if args .dfuse :
69
+ args .dt_flash = True # --dfuse implies --dt-flash.
70
+ build_conf = BuildConfiguration (os .getcwd ())
71
+ dcfg = DfuSeConfig (address = cls .get_flash_address (args , build_conf ),
72
+ options = "leave" )
73
+ else :
74
+ dcfg = None
75
+
56
76
return DfuUtilBinaryRunner (args .pid , args .alt , args .img ,
57
- dfuse = args .dfuse_addr , exe = args . dfu_util ,
77
+ exe = args .dfu_util , dfuse_config = dcfg ,
58
78
debug = args .verbose )
59
79
60
80
def find_device (self ):
@@ -64,17 +84,28 @@ def find_device(self):
64
84
return self .list_pattern in output
65
85
66
86
def do_run (self , command , ** kwargs ):
67
- reset = 0
87
+ reset = False
68
88
if not self .find_device ():
69
- reset = 1
89
+ reset = True
70
90
print ('Please reset your board to switch to DFU mode...' )
71
91
while not self .find_device ():
72
92
time .sleep (0.1 )
73
93
74
94
cmd = list (self .cmd )
75
- if self .dfuse is not None :
76
- cmd .extend (['-s' , '{}:leave' .format (self .dfuse )])
95
+ if self .dfuse :
96
+ # http://dfu-util.sourceforge.net/dfuse.html
97
+ dcfg = self .dfuse_config
98
+ addr_opts = hex (dcfg .address ) + ':' + dcfg .options
99
+ cmd .extend (['-s' , addr_opts ])
77
100
cmd .extend (['-a' , self .alt , '-D' , self .img ])
78
101
self .check_call (cmd )
102
+
103
+ if self .dfuse and 'leave' in dcfg .options .split (':' ):
104
+ # Normal DFU devices generally need to be reset to switch
105
+ # back to the flashed program.
106
+ #
107
+ # DfuSe targets do as well, except when 'leave' is given
108
+ # as an option.
109
+ reset = False
79
110
if reset :
80
111
print ('Now reset your board again to switch back to runtime mode.' )
0 commit comments