Skip to content

Commit ef39688

Browse files
committed
pbio/sys/storage: Limit program size to slot division.
Technically, only the sum of all slots is limited since they are stored consecutively. However, we send only one static value to Pybricks Code, so it doesn't know about the dynamic limit. Having a fixed limit ensures that we can give the appropriate error message for large programs instead of failing with a Bluetooth/USB error code when storage is full. This limits programs on SPIKE Prime to 52,300 bytes, which should cover most use cases. We can relax this limit once we make upgrades to Pybricks Code.
1 parent 155f995 commit ef39688

File tree

1 file changed

+7
-9
lines changed

1 file changed

+7
-9
lines changed

lib/pbio/sys/storage.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,11 @@ static uint32_t pbsys_storage_get_used_program_data_size(void) {
7373
* @returns Maximum program size in bytes.
7474
*/
7575
uint32_t pbsys_storage_get_maximum_program_size(void) {
76-
// FIXME: This is the total size of *all* slots. This is not a
77-
// good indicator of the free space for multi-slot hubs. We need to inform
78-
// the host dynamically about the available size of the current slot.
79-
return pbdrv_block_device_get_writable_size() - sizeof(pbsys_storage_data_map_t);
76+
// FIXME: This is overly conservative since only the sum of of all program
77+
// slots is the limiting factor. However, then we would need to inform the
78+
// host dynamically about the available size of the current slot. Until
79+
// we have that, it is safer to use an absolute limit.
80+
return ((pbdrv_block_device_get_writable_size() - sizeof(pbsys_storage_data_map_t)) / PBSYS_CONFIG_STORAGE_NUM_SLOTS / sizeof(uint32_t)) * sizeof(uint32_t);
8081
}
8182

8283
/**
@@ -266,7 +267,7 @@ pbio_error_t pbsys_storage_set_program_size(uint32_t new_size) {
266267
}
267268

268269
/**
269-
* Writes program data to user RAM.
270+
* Writes program data to user RAM, from the offset of the incoming slot.
270271
*
271272
* Should be combined with at least one call to ::pbsys_storage_set_program_size.
272273
*
@@ -280,10 +281,7 @@ pbio_error_t pbsys_storage_set_program_size(uint32_t new_size) {
280281
* Otherwise ::PBIO_SUCCESS.
281282
*/
282283
pbio_error_t pbsys_storage_set_program_data(uint32_t offset, const void *data, uint32_t size) {
283-
// REVISIT: This protects against writing beyond the limit, but we should
284-
// be informing the host about this ahead of time instead of failing during
285-
// runtime.
286-
if (map->slot_info[incoming_slot].offset + offset + size > pbsys_storage_get_maximum_program_size()) {
284+
if (offset + size > pbsys_storage_get_maximum_program_size()) {
287285
return PBIO_ERROR_INVALID_ARG;
288286
}
289287

0 commit comments

Comments
 (0)