32
32
33
33
#if MICROPY_VFS
34
34
35
- // Block device functions are expected to return 0 on success
36
- // and negative integer on errors. Check for positive integer
37
- // results as some callers (i.e. littlefs) will produce corrupt
38
- // results from these.
39
- static int mp_vfs_check_result (mp_obj_t ret ) {
40
- if (ret == mp_const_none ) {
41
- return 0 ;
42
- } else {
43
- int i = MP_OBJ_SMALL_INT_VALUE (ret );
44
- return i > 0 ? (- MP_EINVAL ) : i ;
45
- }
46
- }
47
-
48
35
void mp_vfs_blockdev_init (mp_vfs_blockdev_t * self , mp_obj_t bdev ) {
49
36
mp_load_method (bdev , MP_QSTR_readblocks , self -> readblocks );
50
37
mp_load_method_maybe (bdev , MP_QSTR_writeblocks , self -> writeblocks );
@@ -59,27 +46,38 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
59
46
}
60
47
}
61
48
49
+ // Helper function to minimise code size of read/write functions
50
+ // note the n_args argument is moved to the end for further code size reduction (args keep same position in caller and callee).
51
+ static int mp_vfs_blockdev_call_rw (mp_obj_t * args , size_t block_num , size_t block_off , size_t len , void * buf , size_t n_args ) {
52
+ mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , len , buf };
53
+ args [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
54
+ args [3 ] = MP_OBJ_FROM_PTR (& ar );
55
+ args [4 ] = MP_OBJ_NEW_SMALL_INT (block_off ); // ignored for n_args == 2
56
+ mp_obj_t ret = mp_call_method_n_kw (n_args , 0 , args );
57
+
58
+ if (ret == mp_const_none ) {
59
+ return 0 ;
60
+ } else {
61
+ // Block device functions are expected to return 0 on success
62
+ // and negative integer on errors. Check for positive integer
63
+ // results as some callers (i.e. littlefs) will produce corrupt
64
+ // results from these.
65
+ int i = MP_OBJ_SMALL_INT_VALUE (ret );
66
+ return i > 0 ? (- MP_EINVAL ) : i ;
67
+ }
68
+ }
69
+
62
70
int mp_vfs_blockdev_read (mp_vfs_blockdev_t * self , size_t block_num , size_t num_blocks , uint8_t * buf ) {
63
71
if (self -> flags & MP_BLOCKDEV_FLAG_NATIVE ) {
64
72
mp_uint_t (* f )(uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> readblocks [2 ];
65
73
return f (buf , block_num , num_blocks );
66
74
} else {
67
- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , buf };
68
- self -> readblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
69
- self -> readblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
70
- mp_call_method_n_kw (2 , 0 , self -> readblocks );
71
- // TODO handle error return
72
- return 0 ;
75
+ return mp_vfs_blockdev_call_rw (self -> readblocks , block_num , 0 , num_blocks * self -> block_size , buf , 2 );
73
76
}
74
77
}
75
78
76
79
int mp_vfs_blockdev_read_ext (mp_vfs_blockdev_t * self , size_t block_num , size_t block_off , size_t len , uint8_t * buf ) {
77
- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , len , buf };
78
- self -> readblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
79
- self -> readblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
80
- self -> readblocks [4 ] = MP_OBJ_NEW_SMALL_INT (block_off );
81
- mp_obj_t ret = mp_call_method_n_kw (3 , 0 , self -> readblocks );
82
- return mp_vfs_check_result (ret );
80
+ return mp_vfs_blockdev_call_rw (self -> readblocks , block_num , block_off , len , buf , 3 );
83
81
}
84
82
85
83
int mp_vfs_blockdev_write (mp_vfs_blockdev_t * self , size_t block_num , size_t num_blocks , const uint8_t * buf ) {
@@ -92,12 +90,7 @@ int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_
92
90
mp_uint_t (* f )(const uint8_t * , uint32_t , uint32_t ) = (void * )(uintptr_t )self -> writeblocks [2 ];
93
91
return f (buf , block_num , num_blocks );
94
92
} else {
95
- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , num_blocks * self -> block_size , (void * )buf };
96
- self -> writeblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
97
- self -> writeblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
98
- mp_call_method_n_kw (2 , 0 , self -> writeblocks );
99
- // TODO handle error return
100
- return 0 ;
93
+ return mp_vfs_blockdev_call_rw (self -> writeblocks , block_num , 0 , num_blocks * self -> block_size , (void * )buf , 2 );
101
94
}
102
95
}
103
96
@@ -106,13 +99,7 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t
106
99
// read-only block device
107
100
return - MP_EROFS ;
108
101
}
109
-
110
- mp_obj_array_t ar = {{& mp_type_bytearray }, BYTEARRAY_TYPECODE , 0 , len , (void * )buf };
111
- self -> writeblocks [2 ] = MP_OBJ_NEW_SMALL_INT (block_num );
112
- self -> writeblocks [3 ] = MP_OBJ_FROM_PTR (& ar );
113
- self -> writeblocks [4 ] = MP_OBJ_NEW_SMALL_INT (block_off );
114
- mp_obj_t ret = mp_call_method_n_kw (3 , 0 , self -> writeblocks );
115
- return mp_vfs_check_result (ret );
102
+ return mp_vfs_blockdev_call_rw (self -> writeblocks , block_num , block_off , len , (void * )buf , 3 );
116
103
}
117
104
118
105
mp_obj_t mp_vfs_blockdev_ioctl (mp_vfs_blockdev_t * self , uintptr_t cmd , uintptr_t arg ) {
0 commit comments