[PATCH 10/11] Firmware upgrade for OSTC3

Jef Driesen jef at libdivecomputer.org
Tue Dec 16 07:57:46 PST 2014


On 2014-11-21 21:28, Anton Lundin wrote:
> +dc_status_t
> +hw_ostc3_device_fwupdate (dc_device_t *abstract, const char *filename)
> +{
> +	dc_status_t rc = DC_STATUS_SUCCESS;
> +	hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
> +	dc_context_t *context = (abstract ? abstract->context : NULL);
> +
> +	// Enable progress notifications.
> +	dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
> +
> +	if (!ISINSTANCE (abstract))
> +		return DC_STATUS_INVALIDARGS;
> +
> +	if (device->state == OPEN) {
> +		if ((rc = hw_ostc3_device_service_mode(abstract)) != 
> DC_STATUS_SUCCESS)
> +			return rc;
> +	} else if (device->state != SERVICE) {
> +		return DC_STATUS_INVALIDARGS;
> +	}
> +	// load, erase, upload FZ, verify FZ, reprogram
> +	progress.maximum = 3 + SZ_FIRMWARE * 2 / SZ_FIRMWARE_BLOCK;
> +	device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
> +
> +	hw_ostc3_device_display(abstract, " Loading FW...");
> +
> +	// Allocate memory for the firmware data.
> +	hw_ostc3_firmware_t *firmware = (hw_ostc3_firmware_t *) malloc
> (sizeof (hw_ostc3_firmware_t));
> +	if (firmware == NULL) {
> +		ERROR (context, "Failed to allocate memory.");
> +		return DC_STATUS_NOMEMORY;
> +	}
> +
> +	// Read the hex file.
> +	rc = hw_ostc3_firmware_readfile (firmware, context, filename);
> +	if (rc != DC_STATUS_SUCCESS) {
> +		free (firmware);
> +		return rc;
> +	}
> +
> +	// Firmware loaded
> +	progress.current++;
> +	device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);

I think it's better to load the firmware file before trying to boot into 
service mode. If there is anything wrong with the firmware file, then 
there is no point to boot into service mode. That might save user some 
trouble.

Reading the firmware file should be instant compared to the time it 
takes to flash it. So the fact that we won't reporting any progress for 
this stage won't be an issue.

BTW, how do you exit service mode? Here, I'm thinking about the case 
where something goes wrong and we have to abort the firmware upgrade. If 
I understand correctly, the original firmware will be preserved, so the 
device can't be bricked. But I assume it's more re-assuring to the user 
if the device boots again, rather than staying in service mode. Note 
that I haven't tested the firmware update yet, so if this is something 
obvious just ignore the question :-)

> +	hw_ostc3_device_display(abstract, " Erasing FW...");

I'm not really sure what's the best way to deal with these 
notifications. When doing this from within libdivecomputer, then it 
won't be possible to localize these messages. That might be confusing 
because the ostc firmware is available in several languages. Doing this 
on the application is not impossible, but there you only have access to 
the progress events, so you could show the overall percentage but not 
the stage (e.g. erasing, uploading, verifying and flashing).

Suggestions are welcome.

> +		rc = hw_ostc3_device_read_block (device, FIRMWARE_AREA + len,
> block, sizeof(block));
> +		if (rc != DC_STATUS_SUCCESS || memcmp (firmware->data + len, block,
> sizeof (block)) != 0) {
> +			hw_ostc3_device_display (abstract, " Verify FAILED");
> +			free (firmware);
> +			ERROR (context, "Failed verify.");
> +			return DC_STATUS_IO;
> +		}

If hw_ostc3_device_read_block() fails, you should return rc, like you 
already do elsewhere. Not DC_STATUS_IO. And when the memcmp() fails, the 
most appropriate error code is DC_STATUS_PROTOCOL.

Jef



More information about the devel mailing list