概要
NSC 2.4.1 環境にて、
外部の spi-norフラッシュにLittleFS領域を作成し、
miniz ライブラリを使用して、
LTE経由でダウンロードしたZIPファイルを解凍できることを確認した。
miniz については 以下が参考になる
https://qiita.com/ishihatta/items/0d7e529f7dca3220e1d9
注意点
nRF9160の環境では、メモリの確保に k_malloc,k_free などを利用するが、
minizライブラリを使用する場合、realloc も必要になる。
しかし k_realloc は存在しないので、
sys_heap系の関数を利用する必要があった。
k_malloc()で、heap領域を確保して、
その領域を sys_heap_init() で、独自の heap 領域を作成すれば利用できるようになる。
sys_heap_alloc
sys_heap_free
sys_heap_realloc
の3つをつかって、
メモリ管理用の関数を作成して。
miniz ライブラリに渡してあげれば、あとはminizライブラリが処理してくれる。
デフォルトで、以下の関数が使用される。
MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
{
(void)opaque, (void)items, (void)size;
return MZ_MALLOC(items * size);
}
MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address)
{
(void)opaque, (void)address;
MZ_FREE(address);
}
MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
{
(void)opaque, (void)address, (void)items, (void)size;
return MZ_REALLOC(address, items * size);
}
heap を作成しておき、以下のような関数を定義して、
MINIZ_EXPORT void *miniz_alloc_func(void *opaque, size_t items, size_t size)
{
(void)opaque, (void)items, (void)size;
return sys_heap_alloc(&heap,items * size);
}
MINIZ_EXPORT void miniz_free_func(void *opaque, void *address)
{
(void)opaque, (void)address;
return sys_heap_free(&heap,address);
}
MINIZ_EXPORT void *miniz_realloc_func(void *opaque, void *address, size_t items, size_t size)
{
(void)opaque, (void)address, (void)items, (void)size;
return sys_heap_realloc(&heap,address,items * size);
}
解凍実行時に作成する mz_zip_archive 構造体のメンバに関数を設定しておけば良い。
mz_zip_archive zip_archive;
memset(&zip_archive, 0, sizeof(zip_archive));
zip_archive.m_pAlloc = miniz_alloc_func;
zip_archive.m_pFree = miniz_free_func;
zip_archive.m_pRealloc = miniz_realloc_func;
zip_archive.m_pRead = zip_read_func;
nRF9160のヒープ領域は、prj.conf で CONFIG_HEAP_MEM_POOL_SIZE で指定する。
スタックサイズは、CONFIG_MAIN_STACK_SIZE を指定しする。
miniz.h に
MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024
という記述があるので、
これを調整すれば miniz ライブラリのメモリアロケーションサイズを縮小できるが、
32 * 1024 くらいまでしか縮小できないので注意。
(これより小さくすると解凍に失敗した)
また、ディクショナリーサイズとして
TDEFL_LZ_DICT_SIZE=32768
が宣言されており、
32KiB分のヒープ領域が別途必要になる。
(サイズ変更はできないと考えた方が良い)
単純に考えると64KiB程度ヒープサイズ必要だが、
ライブラリのヒープ領域の使い方に依存し、
大きめにしておかないと
メモリアロケーションエラーになって解凍に失敗する。
スタックオバーフローになりやすいので、スタックサイズもそれなりに確保しておく必要がある。