0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

nRF9160 で ZIPファイルを解凍する

Posted at

概要

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程度ヒープサイズ必要だが、
ライブラリのヒープ領域の使い方に依存し、
大きめにしておかないと
メモリアロケーションエラーになって解凍に失敗する。

スタックオバーフローになりやすいので、スタックサイズもそれなりに確保しておく必要がある。

以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?