ベアメタル環境のmalloc等をご使用されますとuITRONの環境ではメモリ管理領域
を破壊する等mallocがリエントラントでないために期待しない動作を動作を行う恐れ
があるためにヒープ領域の使用を推奨しておりません。
メモリ領域の取得には固定長メモリプールや可変長メモリプールのAPIを使用する
ことを推奨しております。
独自にヒープ領域をご使用になられる場合は以下の設定が必要になります。
(使用する場合は自己責任でお願いいたします。)
1.__use_no_heapを定義しないようにする。
コード: 全て選択
/******************************************************************
        ヒープ不使用を宣言
 ******************************************************************/
#if 0 /*def __CC_ARM */
#pragma import(__use_no_heap)
#endif
(0x00002000がヒープ領域のサイズになります)
http://infocenter.arm.com/help/index.js ... JBEFD.html
ここではヒープ領域はARM_LIB_HEAPとしておきます。
ヒープ領域はSTACK領域やSTKMEM領域よりもアドレスを前にしてください。
しない場合は、該当する割込みハンドラ内のスタックやタスクのスタックとの衝突
チェックでエラーになり期待した動作にならない場合があります。
また、このスタックの衝突チェックの機能はOSレス(ベアメタル)の環境を期待した
チェックですので、uC3上では正確な衝突チェックはできませんのでご了承ください。
コード: 全て選択
    ARM_LIB_HEAP +0x0 EMPTY 0x00002000
    {
    }
必要に応じてImage$$ARM_LIB_HEAP$$BaseからImage$$ARM_LIB_HEAP$$ZI$$Limit
の領域を0に初期化しておいてください。
(シングルコアのサンプルが該当)
http://infocenter.arm.com/help/index.js ... GAAHA.html
コード: 全て選択
        EXPORT  __user_setup_stackheap
__user_setup_stackheap
        ldr     r0,  =|Image$$ARM_LIB_HEAP$$Base|
        ldr     r2,  =|Image$$ARM_LIB_HEAP$$ZI$$Limit|
        bx      lr
(※こちらは検証していません)
http://infocenter.arm.com/help/index.js ... fiabf.html
_init_alloc(base, , top) を使用してヒープ領域を設定
4.ヒープ領域の自動拡張を無効にする
これを行わないと、ヒープサイズ以上の領域の確保が成功してしまう場合があり、予期しない動作になります。
コード: 全て選択
        EXPORT  __rt_heap_extend
__rt_heap_extend
        mov     r0, #0
        bx      lr
5.コンパイル後にヒープ領域の確認
lstファイルでアドレスを確認しておく。
コード: 全て選択
    Image$$ARM_LIB_HEAP$$Base                0x004f13c4   Number         0  anon$$obj.o(linker$$defined$$symbols)
    Image$$ARM_LIB_HEAP$$ZI$$Limit           0x004f33c4   Number         0  anon$$obj.o(ARM_LIB_HEAP.bss)
ヒープ領域から取得できていることを確認する。
メモリ取得・開放時はCPUロックやディスパッチ禁止などにして、
ヒープ領域の処理中に他のタスクへのディスパッチや割込みが発生
してリエントラントで呼び出されないようにしてください。
コード: 全て選択
void* pmem[3] = NULL;
/*******************************
       Main Task
*******************************/
void MainTask(VP_INT exinf)
{
        dis_dsp();
        pmem[0] = (void*)malloc(1000); /* 0x004F13D8が取得 */
        pmem[1] = (void*)malloc(1000); /* 0x004F17C8が取得 */
        pmem[2] = (void*)malloc(1000); /* 0x004F1BB8が取得 */
        ena_dsp();
    for(;;) {
        dis_dsp();
        free(pmem[0]);
        free(pmem[1]);
        free(pmem[2]);
        ena_dsp();
        dly_tsk(1000);
        dis_dsp();
        pmem[0] = (void*)malloc(1000);
        pmem[1] = (void*)malloc(1000);
        pmem[2] = (void*)malloc(1000);
        ena_dsp();
    }
}
