Skip to content

Commit 13a4ace

Browse files
committed
feat!: add dpcmd support
Add support for dpcmd (DediProg command-line tool) alongside flashrom and flashprog. Each tool now has tool-specific command-line generation to handle their different CLI syntax (dpcmd uses -u for write instead of -w, and auto-detects hardware). BREAKING CHANGE: Flash module removed default tool. Users must now explicitly configure the tool option in their flash module configuration. Signed-off-by: llogen <christoph.lange@blindspot.software>
1 parent 7a9c309 commit 13a4ace

2 files changed

Lines changed: 48 additions & 20 deletions

File tree

pkg/module/flash/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ For write operation, <image> is the local filepath to the image at the client.
1313
1414
```
1515

16-
This module is a wrapper around a flasher tool on the _dutagent_. Supported tools: _flashrom_, _flashprog_.
16+
This module is a wrapper around a flasher tool on the _dutagent_. Supported tools: _flashrom_, _flashprog_, _dpcmd_.
1717
The flasher tool must be installed on the _dutagent_, and suitable flasher hardware must be hooked up to the DUT.
1818
Functionality is tested with DediProg programmers.
1919

@@ -23,5 +23,5 @@ See [flash-example-cfg.yml](./flash-example-cfg.yml) for examples.
2323

2424
| Option | Value | Description |
2525
|------------|--------|---------------------------------------------------------------------------------------------------|
26-
| programmer | string | Name of the flasher hardware, that is used by the _dutagent_ and attached to the DUT's SPI flash. |
27-
| tool | string | Path to the flasher tool binary on the _dutagent_. Defaults to `/bin/flashrom` if not specified. Supported: flashrom, flashprog. |
26+
| tool | string | Path to the flasher tool binary on the _dutagent_. Supported: flashrom, flashprog, dpcmd. |
27+
| programmer | string | Specifics of the flasher hardware. For flashrom/flashprog: programmer name (e.g., "dediprog"). For dpcmd: (Optional) USB device number. Required for flashrom/flashprog, optional for dpcmd. See the respective flash-tool documentation for supported values. |

pkg/module/flash/flash.go

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,12 @@ func init() {
2727
ID: "flash",
2828
New: func() module.Module {
2929
return &Flash{
30-
supportedTools: []string{"flashrom", "flashprog"},
30+
supportedTools: []string{"flashrom", "flashprog", "dpcmd"},
3131
}
3232
},
3333
})
3434
}
3535

36-
// DefaultFlashTool is the default tool on the dutagent.
37-
const DefaultFlashTool = "/bin/flashrom"
38-
3936
// localImagePath is the local path on the dutagent to temporally store the flash image
4037
// during read/write operations.
4138
const localImagePath = "./image"
@@ -50,11 +47,16 @@ const (
5047

5148
// Flash is a module that reads or writes the SPI flash on the DUT.
5249
type Flash struct {
50+
// Tool is the path to the underlying flash-tool on the dutagent.
51+
// It must be set to one of the following:
52+
// - flashrom
53+
// - flashprog
54+
// - dpcmd
55+
Tool string `yaml:"tool"`
5356
// Programmer is the name of the flasher hardware.
54-
Programmer string
55-
// Tool is the path to the underlying flash-tool on the dutagent. If unset, [DefaultFlashTool] is used.
56-
// Supported tools: flashrom, flashprog.
57-
Tool string
57+
// For flashrom/flashprog: passed via -p flag (e.g., "dediprog", "ch341a_spi").
58+
// For dpcmd: optional, used with --device flag to select specific USB device number.
59+
Programmer string `yaml:"programmer"`
5860

5961
op op // op holds the current flash operation
6062
localImagePath string // localImagePath is the path to SPI image file at the dutagent
@@ -100,7 +102,7 @@ func (f *Flash) Init() error {
100102
log.Println("flash module: Init called")
101103

102104
if f.Tool == "" {
103-
f.Tool = DefaultFlashTool
105+
return fmt.Errorf("tool must be configured; supported tools are %v", f.supportedTools)
104106
}
105107

106108
if !f.isSupported(f.Tool) {
@@ -112,8 +114,11 @@ func (f *Flash) Init() error {
112114
return fmt.Errorf("flash tool %q: %w", f.Tool, err)
113115
}
114116

115-
if f.Programmer == "" {
116-
return errors.New("programmer must be configured")
117+
// dpcmd auto-detects hardware, so programmer is optional
118+
// flashrom/flashprog require a programmer to be specified
119+
base := filepath.Base(f.Tool)
120+
if base != "dpcmd" && f.Programmer == "" {
121+
return fmt.Errorf("programmer must be configured for %q", base)
117122
}
118123

119124
return nil
@@ -210,14 +215,37 @@ func execute(tool string, args ...string) error {
210215
}
211216

212217
// cmdline returns the arg list for the wrapped flash tool.
218+
// flashrom/flashprog use: -p <programmer> -r/-w <file>.
219+
// dpcmd uses: -r/-u <file> [--device <n>].
213220
func (f *Flash) cmdline() []string {
214-
args := []string{"-p", f.Programmer}
221+
base := filepath.Base(f.Tool)
222+
223+
var args []string
224+
225+
// dpcmd has different CLI syntax than flashrom/flashprog
226+
if base == "dpcmd" {
227+
// dpcmd auto-detects hardware, but can optionally specify device number
228+
if f.Programmer != "" {
229+
args = append(args, "--device", f.Programmer)
230+
}
215231

216-
switch f.op {
217-
case opWrite:
218-
args = append(args, "-w", f.localImagePath)
219-
case opRead:
220-
args = append(args, "-r", f.localImagePath)
232+
switch f.op {
233+
case opWrite:
234+
// dpcmd uses -u (update: erase then program) instead of -w
235+
args = append(args, "-u", f.localImagePath)
236+
case opRead:
237+
args = append(args, "-r", f.localImagePath)
238+
}
239+
} else {
240+
// flashrom and flashprog use the same CLI
241+
args = []string{"-p", f.Programmer}
242+
243+
switch f.op {
244+
case opWrite:
245+
args = append(args, "-w", f.localImagePath)
246+
case opRead:
247+
args = append(args, "-r", f.localImagePath)
248+
}
221249
}
222250

223251
return args

0 commit comments

Comments
 (0)