or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

backends.mdcontrol-requests.mddevice-communication.mddevice-discovery.mdindex.mdlegacy-api.mdutilities.md

backends.mddocs/

0

# Backends

1

2

Pluggable backend architecture supporting multiple USB libraries with automatic backend detection and configuration. PyUSB's backend system provides abstraction over different USB implementations while maintaining consistent API behavior.

3

4

## Capabilities

5

6

### Backend Interface

7

8

Abstract base class defining the backend interface that all USB backends must implement.

9

10

```python { .api }

11

class IBackend:

12

"""

13

Abstract backend interface for USB operations.

14

15

All USB backends must implement this interface to provide

16

USB device access through different underlying libraries.

17

"""

18

19

def enumerate_devices(self):

20

"""Enumerate available USB devices."""

21

22

def open_device(self, device):

23

"""Open device for communication."""

24

25

def close_device(self, device_handle):

26

"""Close device handle."""

27

28

def set_configuration(self, device_handle, config_value):

29

"""Set device configuration."""

30

31

def claim_interface(self, device_handle, interface_number):

32

"""Claim interface for exclusive access."""

33

34

def release_interface(self, device_handle, interface_number):

35

"""Release interface."""

36

```

37

38

### libusb 1.x Backend

39

40

Modern libusb 1.x backend providing comprehensive USB support with advanced features.

41

42

```python { .api }

43

def get_backend():

44

"""

45

Get libusb 1.x backend instance.

46

47

Returns:

48

Backend object for libusb 1.x operations

49

50

Raises:

51

- NoBackendError: libusb 1.x not available

52

"""

53

54

# libusb 1.x error codes

55

LIBUSB_SUCCESS = 0

56

LIBUSB_ERROR_IO = -1

57

LIBUSB_ERROR_INVALID_PARAM = -2

58

LIBUSB_ERROR_ACCESS = -3

59

LIBUSB_ERROR_NO_DEVICE = -4

60

LIBUSB_ERROR_NOT_FOUND = -5

61

LIBUSB_ERROR_BUSY = -6

62

LIBUSB_ERROR_TIMEOUT = -7

63

LIBUSB_ERROR_OVERFLOW = -8

64

LIBUSB_ERROR_PIPE = -9

65

LIBUSB_ERROR_INTERRUPTED = -10

66

LIBUSB_ERROR_NO_MEM = -11

67

LIBUSB_ERROR_NOT_SUPPORTED = -12

68

LIBUSB_ERROR_OTHER = -99

69

```

70

71

### libusb 0.1 Backend

72

73

Legacy libusb 0.1 backend for compatibility with older systems.

74

75

```python { .api }

76

def get_backend():

77

"""

78

Get libusb 0.1 backend instance.

79

80

Returns:

81

Backend object for libusb 0.1 operations

82

83

Raises:

84

- NoBackendError: libusb 0.1 not available

85

"""

86

```

87

88

### OpenUSB Backend

89

90

OpenUSB backend providing alternative USB library support.

91

92

```python { .api }

93

def get_backend():

94

"""

95

Get OpenUSB backend instance.

96

97

Returns:

98

Backend object for OpenUSB operations

99

100

Raises:

101

- NoBackendError: OpenUSB not available

102

"""

103

104

# OpenUSB result codes

105

OPENUSB_SUCCESS = 0

106

OPENUSB_PLATFORM_FAILURE = -1

107

OPENUSB_NO_RESOURCES = -2

108

OPENUSB_NO_BANDWIDTH = -3

109

OPENUSB_NOT_SUPPORTED = -4

110

OPENUSB_HC_HARDWARE_ERROR = -5

111

OPENUSB_INVALID_PERM = -6

112

OPENUSB_BUSY = -7

113

OPENUSB_BADARG = -8

114

OPENUSB_NOACCESS = -9

115

OPENUSB_PARSE_ERROR = -10

116

OPENUSB_UNKNOWN_DEVICE = -11

117

OPENUSB_INVALID_HANDLE = -12

118

OPENUSB_IO_TIMEOUT = -13

119

OPENUSB_IO_CANCELLED = -14

120

OPENUSB_IO_OVERFLOW = -15

121

OPENUSB_CB_CONTINUE = -16

122

```

123

124

### Backend Selection

125

126

Automatic backend selection and access to specific backend modules.

127

128

```python { .api }

129

def get_backend():

130

"""

131

Get best available backend automatically.

132

133

Attempts to load backends in order of preference:

134

1. libusb 1.x (most modern and capable)

135

2. libusb 0.1 (legacy compatibility)

136

3. OpenUSB (alternative implementation)

137

138

Returns:

139

Backend object for the first available backend

140

141

Raises:

142

- NoBackendError: No USB backend available

143

"""

144

145

import usb.backend.libusb1 # Modern libusb 1.x backend

146

import usb.backend.libusb0 # Legacy libusb 0.1 backend

147

import usb.backend.openusb # OpenUSB backend

148

```

149

150

### Library Loading (libloader module)

151

152

Helper functions for loading USB backend libraries with error handling and library location.

153

154

```python { .api }

155

def locate_library(candidates, find_library=None):

156

"""

157

Locate library from candidate list.

158

159

Parameters:

160

- candidates: list, candidate library names

161

- find_library: callable, library finder function

162

163

Returns:

164

str: path to library or None if not found

165

"""

166

167

def load_library(lib, name=None, lib_cls=None):

168

"""

169

Load library from path.

170

171

Parameters:

172

- lib: str, library path

173

- name: str, library name for error messages

174

- lib_cls: class, library wrapper class

175

176

Returns:

177

Library object

178

179

Raises:

180

- LibraryException: Library loading failed

181

"""

182

183

class LibraryException(Exception):

184

"""Base exception for library loading errors."""

185

186

class LibraryNotFoundException(LibraryException):

187

"""Library not found exception."""

188

189

class NoLibraryCandidatesException(LibraryException):

190

"""No library candidates available exception."""

191

```

192

193

## Usage Examples

194

195

### Automatic Backend Selection

196

197

```python

198

import usb.core

199

200

# PyUSB automatically selects the best available backend

201

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

202

203

if device:

204

print(f"Device found using automatic backend selection")

205

print(f"Backend: {device._ctx.backend.__class__.__module__}")

206

else:

207

print("No device found or no backend available")

208

```

209

210

### Explicit Backend Selection

211

212

```python

213

import usb.core

214

import usb.backend.libusb1

215

216

# Use specific backend

217

try:

218

backend = usb.backend.libusb1.get_backend()

219

device = usb.core.find(idVendor=0x1234, idProduct=0x5678, backend=backend)

220

221

if device:

222

print("Device found using libusb1 backend")

223

else:

224

print("Device not found")

225

226

except usb.core.NoBackendError:

227

print("libusb1 backend not available")

228

```

229

230

### Backend Availability Check

231

232

```python

233

import usb.backend.libusb1

234

import usb.backend.libusb0

235

import usb.backend.openusb

236

import usb.core

237

238

def check_backends():

239

"""Check which backends are available."""

240

backends = {

241

'libusb1': usb.backend.libusb1,

242

'libusb0': usb.backend.libusb0,

243

'openusb': usb.backend.openusb

244

}

245

246

available = []

247

for name, backend_module in backends.items():

248

try:

249

backend = backend_module.get_backend()

250

if backend:

251

available.append(name)

252

print(f"{name}: Available")

253

except usb.core.NoBackendError:

254

print(f"{name}: Not available")

255

256

return available

257

258

print("Backend availability:")

259

available_backends = check_backends()

260

print(f"Available backends: {available_backends}")

261

```

262

263

### Backend-Specific Error Handling

264

265

```python

266

import usb.core

267

import usb.backend.libusb1

268

269

try:

270

backend = usb.backend.libusb1.get_backend()

271

device = usb.core.find(idVendor=0x1234, idProduct=0x5678, backend=backend)

272

273

if device:

274

# Perform operations that might fail

275

try:

276

device.set_configuration()

277

data = device.read(0x81, 64, timeout=1000)

278

279

except usb.core.USBError as e:

280

# Check for libusb1-specific error codes

281

if hasattr(e, 'backend_error_code'):

282

error_code = e.backend_error_code

283

if error_code == usb.backend.libusb1.LIBUSB_ERROR_TIMEOUT:

284

print("Operation timed out")

285

elif error_code == usb.backend.libusb1.LIBUSB_ERROR_NO_DEVICE:

286

print("Device disconnected")

287

elif error_code == usb.backend.libusb1.LIBUSB_ERROR_ACCESS:

288

print("Access denied - check permissions")

289

else:

290

print(f"USB error with backend code: {error_code}")

291

else:

292

print(f"USB error: {e}")

293

294

except usb.core.NoBackendError:

295

print("libusb1 backend not available")

296

```

297

298

### Multi-Backend Device Search

299

300

```python

301

import usb.core

302

import usb.backend.libusb1

303

import usb.backend.libusb0

304

305

def find_device_any_backend(vendor_id, product_id):

306

"""Try to find device using any available backend."""

307

308

backends_to_try = [

309

('libusb1', usb.backend.libusb1),

310

('libusb0', usb.backend.libusb0),

311

]

312

313

for backend_name, backend_module in backends_to_try:

314

try:

315

backend = backend_module.get_backend()

316

device = usb.core.find(

317

idVendor=vendor_id,

318

idProduct=product_id,

319

backend=backend

320

)

321

322

if device:

323

print(f"Device found using {backend_name} backend")

324

return device, backend_name

325

326

except usb.core.NoBackendError:

327

print(f"{backend_name} backend not available")

328

continue

329

330

return None, None

331

332

# Search for device

333

device, backend_used = find_device_any_backend(0x1234, 0x5678)

334

335

if device:

336

print(f"Successfully found device using {backend_used}")

337

else:

338

print("Device not found with any backend")

339

```

340

341

### Backend Configuration

342

343

```python

344

import usb.core

345

import usb.backend.libusb1

346

import os

347

348

# Some backends may support configuration through environment variables

349

# For example, libusb debug output:

350

os.environ['LIBUSB_DEBUG'] = '3' # Enable verbose libusb debugging

351

352

try:

353

backend = usb.backend.libusb1.get_backend()

354

print("libusb1 backend initialized with debug output")

355

356

# Find device with debugging enabled

357

device = usb.core.find(idVendor=0x1234, idProduct=0x5678, backend=backend)

358

359

except usb.core.NoBackendError:

360

print("libusb1 backend not available")

361

```

362

363

### Backend Performance Comparison

364

365

```python

366

import usb.core

367

import usb.backend.libusb1

368

import usb.backend.libusb0

369

import time

370

371

def benchmark_backend(backend_module, backend_name):

372

"""Benchmark device enumeration with specific backend."""

373

try:

374

backend = backend_module.get_backend()

375

376

start_time = time.time()

377

devices = usb.core.find(find_all=True, backend=backend)

378

end_time = time.time()

379

380

device_count = len(devices) if devices else 0

381

elapsed = end_time - start_time

382

383

print(f"{backend_name}: Found {device_count} devices in {elapsed:.3f}s")

384

return elapsed

385

386

except usb.core.NoBackendError:

387

print(f"{backend_name}: Not available")

388

return None

389

390

print("Backend performance comparison:")

391

libusb1_time = benchmark_backend(usb.backend.libusb1, "libusb1")

392

libusb0_time = benchmark_backend(usb.backend.libusb0, "libusb0")

393

394

if libusb1_time and libusb0_time:

395

if libusb1_time < libusb0_time:

396

print("libusb1 is faster for device enumeration")

397

else:

398

print("libusb0 is faster for device enumeration")

399

```

400

401

### Custom Backend Integration

402

403

```python

404

import usb.core

405

from usb.backend import IBackend

406

407

class CustomBackend(IBackend):

408

"""Example custom backend implementation."""

409

410

def enumerate_devices(self):

411

"""Custom device enumeration logic."""

412

# Implement custom device discovery

413

pass

414

415

def open_device(self, device):

416

"""Custom device opening logic."""

417

# Implement custom device access

418

pass

419

420

# Implement other required methods...

421

422

# Use custom backend

423

custom_backend = CustomBackend()

424

425

try:

426

device = usb.core.find(

427

idVendor=0x1234,

428

idProduct=0x5678,

429

backend=custom_backend

430

)

431

432

if device:

433

print("Device found using custom backend")

434

435

except Exception as e:

436

print(f"Custom backend error: {e}")

437

```