mirror of
https://github.com/hathach/tinyusb.git
synced 2026-02-07 16:35:33 +00:00
test mtp with hil
This commit is contained in:
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -208,8 +208,6 @@ jobs:
|
||||
- name: Checkout TinyUSB
|
||||
if: github.run_attempt == '1'
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: test/hil
|
||||
|
||||
- name: Download Artifacts
|
||||
if: github.run_attempt == '1'
|
||||
|
||||
@ -71,7 +71,8 @@ storage_info_t storage_info = {
|
||||
//--------------------------------------------------------------------+
|
||||
// MTP FILESYSTEM
|
||||
//--------------------------------------------------------------------+
|
||||
#define FS_MAX_FILE_COUNT 5UL
|
||||
// only allow to add 1 more object to make it simpler to manage memory
|
||||
#define FS_MAX_FILE_COUNT 3UL
|
||||
#define FS_MAX_FILENAME_LEN 16
|
||||
|
||||
#ifdef CFG_EXAMPLE_MTP_READONLY
|
||||
@ -82,14 +83,13 @@ storage_info_t storage_info = {
|
||||
// object data buffer (excluding 2 predefined files) with simple allocation pointer
|
||||
uint8_t fs_buf[FS_MAX_CAPACITY_BYTES];
|
||||
#endif
|
||||
size_t fs_buf_head = 0;
|
||||
|
||||
#define FS_FIXED_DATETIME "20250808T173500.0" // "YYYYMMDDTHHMMSS.s"
|
||||
#define README_TXT_CONTENT "TinyUSB MTP Filesystem example"
|
||||
|
||||
typedef struct {
|
||||
uint16_t name[FS_MAX_FILENAME_LEN];
|
||||
mtp_object_formats_t object_format;
|
||||
uint16_t object_format;
|
||||
uint16_t protection_status;
|
||||
uint32_t image_pix_width;
|
||||
uint32_t image_pix_height;
|
||||
@ -112,7 +112,7 @@ static fs_file_t fs_objects[FS_MAX_FILE_COUNT] = {
|
||||
.parent = 0,
|
||||
.association_type = MTP_ASSOCIATION_UNDEFINED,
|
||||
.data = (uint8_t*) (uintptr_t) README_TXT_CONTENT,
|
||||
.size = sizeof(README_TXT_CONTENT)
|
||||
.size = sizeof(README_TXT_CONTENT)-1
|
||||
},
|
||||
{
|
||||
.name = { 't', 'i', 'n', 'y', 'u', 's', 'b', '.', 'p', 'n', 'g', 0 }, // "tinyusb.png"
|
||||
@ -212,12 +212,10 @@ static inline uint8_t* fs_malloc(size_t size) {
|
||||
(void) size;
|
||||
return NULL;
|
||||
#else
|
||||
if (fs_buf_head + size > FS_MAX_CAPACITY_BYTES) {
|
||||
if (size > FS_MAX_CAPACITY_BYTES) {
|
||||
return NULL;
|
||||
}
|
||||
uint8_t* ptr = &fs_buf[fs_buf_head];
|
||||
fs_buf_head += size;
|
||||
return ptr;
|
||||
return fs_buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -394,7 +392,7 @@ static int32_t fs_get_storage_info(tud_mtp_cb_data_t* cb_data) {
|
||||
// update storage info with current free space
|
||||
storage_info.max_capacity_in_bytes = sizeof(README_TXT_CONTENT) + logo_len + FS_MAX_CAPACITY_BYTES;
|
||||
storage_info.free_space_in_objects = FS_MAX_FILE_COUNT - fs_get_file_count();
|
||||
storage_info.free_space_in_bytes = FS_MAX_CAPACITY_BYTES-fs_buf_head;
|
||||
storage_info.free_space_in_bytes = storage_info.free_space_in_objects ? FS_MAX_CAPACITY_BYTES : 0;
|
||||
mtp_container_add_raw(io_container, &storage_info, sizeof(storage_info));
|
||||
tud_mtp_data_send(io_container);
|
||||
return 0;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
// convert using tools/file2carray.py
|
||||
const size_t logo_len = 2733;
|
||||
const uint8_t logo_bin[] __attribute__((aligned(16))) = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
@ -37,16 +38,11 @@ import json
|
||||
import glob
|
||||
from multiprocessing import Pool
|
||||
import fs
|
||||
|
||||
import hashlib
|
||||
import ctypes
|
||||
from pymtp import MTP, LIBMTP_MTPDevice, LIBMTP_RawDevice
|
||||
from pymtp import MTP
|
||||
|
||||
mtp = MTP()
|
||||
lib = mtp.mtp
|
||||
|
||||
# # tell ctypes that Open_Raw_Device returns MTPDevice*
|
||||
lib.LIBMTP_Open_Raw_Device.restype = ctypes.POINTER(LIBMTP_MTPDevice)
|
||||
lib.LIBMTP_Open_Raw_Device.argtypes = [ctypes.POINTER(LIBMTP_RawDevice)]
|
||||
|
||||
|
||||
ENUM_TIMEOUT = 30
|
||||
|
||||
@ -502,15 +498,64 @@ def test_device_hid_composite_freertos(id):
|
||||
|
||||
def test_device_mtp(board):
|
||||
uid = board['uid']
|
||||
|
||||
# --- BEFORE: mute C-level stderr for libmtp vid/pid warnings ---
|
||||
fd = sys.stderr.fileno()
|
||||
_saved = os.dup(fd)
|
||||
_null = os.open(os.devnull, os.O_WRONLY)
|
||||
os.dup2(_null, fd)
|
||||
|
||||
for raw in mtp.detect_devices():
|
||||
mtp.device = lib.LIBMTP_Open_Raw_Device(ctypes.byref(raw))
|
||||
mtp.device = mtp.mtp.LIBMTP_Open_Raw_Device(ctypes.byref(raw))
|
||||
if mtp.device and mtp.get_serialnumber().decode('utf-8') == uid:
|
||||
break
|
||||
else:
|
||||
mtp.device = None
|
||||
|
||||
# --- AFTER: restore stderr ---
|
||||
os.dup2(_saved, fd)
|
||||
os.close(_null)
|
||||
os.close(_saved)
|
||||
|
||||
if mtp.device is None:
|
||||
assert False, 'MTP device not found'
|
||||
|
||||
assert b"TinyUSB" == mtp.get_manufacturer(), 'MTP wrong manufacturer'
|
||||
assert b"MTP Example" == mtp.get_modelname(), 'MTP wrong model'
|
||||
assert b'1.0' == mtp.get_deviceversion(), 'MTP wrong version'
|
||||
assert b'TinyUSB MTP' == mtp.get_devicename(), 'MTP wrong device name'
|
||||
|
||||
# read and compare readme.txt and logo.png
|
||||
f1_expect = b'TinyUSB MTP Filesystem example'
|
||||
f2_md5_expect = '40ef23fc2891018d41a05d4a0d5f822f' # md5sum of logo.png
|
||||
f1 = uid.encode("utf-8") + b'_file1'
|
||||
f2 = uid.encode("utf-8") + b'_file2'
|
||||
f3 = uid.encode("utf-8") + b'_file3'
|
||||
mtp.get_file_to_file(1, f1)
|
||||
with open(f1, 'rb') as file:
|
||||
f1_data = file.read()
|
||||
os.remove(f1)
|
||||
assert f1_data == f1_expect, 'MTP file1 wrong data'
|
||||
mtp.get_file_to_file(2, f2)
|
||||
with open(f2, 'rb') as file:
|
||||
f2_data = file.read()
|
||||
os.remove(f2)
|
||||
assert f2_md5_expect == hashlib.md5(f2_data).hexdigest(), 'MTP file2 wrong data'
|
||||
# test send file
|
||||
with open(f3, "wb") as file:
|
||||
f3_data = os.urandom(random.randint(1024, 3*1024))
|
||||
file.write(f3_data)
|
||||
file.close()
|
||||
fid = mtp.send_file_from_file(f3, b'file3')
|
||||
f3_readback = f3 + b'_readback'
|
||||
mtp.get_file_to_file(fid, f3_readback)
|
||||
with open(f3_readback, 'rb') as f:
|
||||
f3_rb_data = f.read()
|
||||
os.remove(f3_readback)
|
||||
assert f3_rb_data == f3_data, 'MTP file3 wrong data'
|
||||
os.remove(f3)
|
||||
mtp.delete_object(fid)
|
||||
|
||||
|
||||
|
||||
# -------------------------------------------------------------
|
||||
|
||||
1290
test/hil/pymtp.py
Normal file
1290
test/hil/pymtp.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user