Fw compress merge#68
Conversation
Refactor the driver to call cyw43_get_firmware_funcs to get functions to load firmware data. If CYW43_ENABLE_FIRMWARE_COMPRESSION is true it will load gzip compressed firmware using uzlib. Extra header files have been added that contain the compressed firmware. Compression dictionary size is 4096 bytes
We can no longer malloc in Micropython.
So my initial impressions:
Also, looking at I wonder if some of these (e.g. wifi_fw_addr) belong in here... I think the firmware details (and I haven't totally scrutinized the firmware loading code) should be limited to meaningful data about the firmware itself (sizes and wot not) These are just suggestions, perhaps @dpgeorge has some thoughts too Maybe something like this you can still use a static streaming_context if you like (we can document that we won't read multiple fws concurrently/overlapped) |
|
Thanks Graham. Some comments below - but I'll have a think about your suggestion.
I guess they don't need any context. To support reading uncompressed, we just return the address requested. To support decompression we return a buffer of the size requested and the address is unused.
The only reason for having them separate is that nvram is always uncompressed. It's a small human readable separate file that's annoyingly loaded between wifi and clm data, so would need a separate decompression object.
It is, unless compression is disabled, when it's the actual data.
Yes, it is a bit odd. It's because wifi and bt is loaded at different times. Maybe I should have start functions for all the components in case they are ever separated.
I'm not sure where else we'd get the data from. It's used to get a pointer to the compressed data, or the actual data if |
|
I might try compressing the nvram data into the wifi firmware file before clm data, so the order of compressed data matches the order the data is used. Currently I've left nvram uncompressed which doesn't work with the suggested API. |
Now just start, stream and end.
86622a3 to
24362d6
Compare
|
I updated the API more or less as Graham suggested. But cyw43_firmware_details_t is unchanged. |
|
I haven't done a detailed review of this, but here are a few comments/questions based on an initial look:
|
I had to make sure the pico-sdk version of uzlib was not included as there is already a version in Micropython added in moduzlib.c. There didn't seem to be a nicer way to solve this.
It looks similar to the code I have - I suspect I copied it?
There are two versions of wifi firmware, just wifi... bt+wifi... Just the bt firmware...
I'll have to measure that and get back to you.
It's just complicated to convert the raw binaries into header files and add the "meta" data needed. I could write it in Python but I thought make would be easier - see https://github.com/peterharperuk/cyw43-firmware/blob/master/make_firmware/Makefile |
|
Some performance measurements... (still to do bluetooth) Firmware loading without any changes: wifi 135.95ms nvram 3.68ms, clm 3.64ms So in summary, wifi +657ms, nvram +0.12ms, clm +2.4ms |
That's quite a big increase in time taken. Is this for Pico W? I already notice that Pico W is rather slow doing If compression approximately doubles that time to activate the WLAN interface, that will definitely be noticed by users. |
|
Yes, Pico W. The cyw43 firmware is 227KB and is downloaded in 64 byte chunks for some reason. I'm using max compression. I guess we could speed it up by compressing less, but it's always going to be slower. We could even disable compression by default. |
|
It's a difficult trade off to decide upon: save 80k of flash but pay 650ms penalty? |
|
I had a play around with the compression ratio. It doesn't seem to make any difference to the decompression time. Increasing the dictionary size from 4KB to 32KB reduces the load time from >800 to 348ms, so around 212ms penalty for compression. |
This is a fairly big change which enables firmware compression.
Firmware compression is enabled with a flag CYW43_ENABLE_FIRMWARE_COMPRESSION.
Firmware details and functions for reading firmware are stored in function pointers in cyw43_get_firmware_funcs_default. This can be replaced by changing the macro cyw43_get_firmware_funcs
One of these functions returns the firmware details cyw43_firmware_details_func
New firmware header files have been added that have a compressed (gzip) version of the firmware.
If firmware is compressed it reads the firmware with uzlib, see cyw43_gz_read.c
As the firmware header files are quite complicated now, I have a project to generate them. This also includes a test/demo that demonstrates how firmware could now be stored in flash, see https://github.com/peterharperuk/cyw43-firmware