PICのメモリ消費について

MPLABXを使ってPICのプログラムを記述してビルドすると、プログラムメモリとデータメモリの消費量が左下のDashboardに表示される。

プログラムコードをどんどん記述していくと消費するのは想像しやすいが、どんな感じで増えていくのかをちょっとだけ検証してみた。

なお使用したPICはPIC16F1455で、データメモリが1024B、プログラムメモリ8192Bのメモリサイズになる。

MCCでオシレータ設定だけした状態

ほぼ空の状態。

#include "mcc_generated_files/mcc.h"
void main(void)
{
    SYSTEM_Initialize();
    return;
}

picmem01

関数内のローカル領域に配列の宣言と初期化する処理を追加

ほぼ想定通りで、追加したコード量がプログラムメモリを消費し、配列で確保したサイズだけデータ領域を消費していた。

#include "mcc_generated_files/mcc.h"
void main(void)
{
    SYSTEM_Initialize();
    char buf[64];
    memset(buf, 0, sizeof(buf));
    return;
}

picmem02

グローバル領域に配列を追加+初期化

ローカル領域で配列を定義した先の結果と変わらず。

配列サイズを100Byteに増やす(ローカル領域)

ローカル変数領域で増やしたところ、「スペースがない」とビルドエラーが発生した為、モジュール作成ができなかった。無償版コンパイラなので最適化されてないのかちょっと意外だった。

#include "mcc_generated_files/mcc.h"
void main(void)
{
    SYSTEM_Initialize();
    char buf[100];
    memset(buf, 0, sizeof(buf));
    return;
}
main.c:15:: error: (1250) could not find space (100 bytes) for variable _buf
(908) exit status = 1

配列サイズを100Byteに増やす(グローバル領域)

上記と同じサイズの配列をグローバル領域で宣言したところ、ビルドに成功した。

#include "mcc_generated_files/mcc.h"
char buf[100];
void main(void)
{
    SYSTEM_Initialize();
    memset(buf, 0, sizeof(buf));
    return;
}

picmem03

グローバル領域で宣言した配列のサイズを限界まで増やしてみる

グローバル領域だと、ビルドできることが分かったので、どんどん増やしてみると、ほぼデータメモリサイズだけちゃんとアロケートできることが分かった。

picmem04

#include "mcc_generated_files/mcc.h"

char buf[1008];

void main(void)
{
    SYSTEM_Initialize();
    memset(buf, 0, sizeof(buf));
    return;
}

ローカル領域で定義できるサイズの確認その他

エラーにならないサイズの確認と、複数の配列で定義した場合どうなるのかを確認。とりあえずローカル宣言した配列のサイズをどんどん増やしていくと、要素数80( char buf[80] )までビルドが可能だった。

その後、関数を1つ増やして、同じサイズの配列を追加したところ、ビルドが可能だった。同一関数のローカル領域で使用できる変数サイズの限界値は小さいということと、このサイズは関数毎でカウントして合算値ではない。


void func(){
    char buf[80];
    memset(buf, 0, sizeof(buf));
}
void func2(){
    char buf[80];
    memset(buf, 0, sizeof(buf));
}
void main(void)
{
    SYSTEM_Initialize();
    func();
    func2();
    return;
}

picmem05