RX111でmallocに失敗する
RX111でmallocに失敗する
GCC for Renesas RX 8.3.0.202002を使ってRX111でmallocをしてみたところ、
mallocが0を返し、失敗してしまいます。
開発環境はe2studioで、スマートコンフィグレータを使っていて、bspのheap sizeの設定は0x400になっています。
mallocの引数を1にして、1バイトだけ確保するようにしても失敗するようなのですが、
なにか他に設定しなければならない項目等ありますでしょうか?
なお、RX71Mで同じことをすると、そちらでは問題無く動きました。
あと、RX111でもツールチェインをCCRXにした場合も問題無く動きました。
fujimotoさん、こんにちは。NoMaYと申します。
スマートコンフィグレータ(というかbsp)のnewlibのmalloc処理(正確にはその内部で呼ばれるsbrk処理)に私は多少の縁がありましたので調べてみました。newlib内部に4096バイト境界を意識した処理があり、例えmalloc(1)としても、最悪1+4095バイトを確保しようとする可能性があるようです。(ざっくりとしたイメージとしての言い回しですけれども。) なので、newlibのmallocを使用する場合、最低でもbspのheap sizeは0x1000としておく必要があるということになりますね。
[追記]
逆に言うと、パソコン向けの4096バイト境界を意識した処理をRXマイコン対応に改善しないといけない、ということですね。
fujimotoさん、こんにちは。NoMaYです。
ヒープ領域の大元はbspのsbrk.cで定義されているs_heap_areaという構造体のheap[BSP_CFG_HEAP_BYTES]という配列なのですが、正確には、この構造体/配列が配置されているアドレスに依存して、heap sizeで余分に必要とされるサイズが変化するのです。この構造体/配列が配置されているアドレスが4096バイト境界の少し手前から配置されていれば少ないサイズで済みますし、逆に、配置されているアドレスが4096バイト境界のずっと手前(言い換えると4096バイト境界の少し後)から配置されていると沢山の余分なサイズが必要になるのです。(なお、少し手前とか少し後とか、ざっくりした表現ですが、僅かに、数十バイト手前とか数十バイト後とか、そういう場合にどちらになるかは、すみません、ガッツリとnewlibのソースを見ないと分からないです。)
ですので、もしfujimotoさんの手元のRX111のプログラムでその構造体/配列が配置されているアドレスが4096バイト境界の少し手前であればRX111でも0x400でmalloc(1)が成功しますし、逆に、もしfujimotoさんの手元のRX71Mのプログラムでその構造体/配列が配置されているアドレスが4096バイト境界のずっと手前であればRX71Mでも0x400でmalloc(1)が失敗する、ということになる筈なのです。
実際、私の手元で作成したmalloc(1)の確認用の以下のプログラムでは、RX111でもRX71Mでもheap sizeが0x400ではmalloc(1)が失敗してしまいますし、RX111でもRX71Mでもheap sizeを0x1000にしておけばmalloc(1)は成功する、という挙動になりました。
#include “r_smc_entry.h”
#include <stdlib.h>
void main(void);
volatile void *p = NULL; /* volatileは最適化の影響でコードが削除されるのを防ぐ為 */
void main(void)
{
p = malloc(1);
for (;;) ; /* breakpoint設定用 */
}