no space for auto/param xxx@buffer

PIC16F1455を使って、MPLABXでPICプログラムをビルドすると、no space for auto/param xxx@bufferでコンパイルエラーになることがあった。(xxxは関数名)

mcc_generated_files/eusart.c:218:: error: (1360) no space for auto/param main_interrupt2@buffer
(908) exit status = 1

ローカル変数で領域を確保していくと、ビルドが成功したときに表示されるData spaceがどんどん消費されていって、配列で64バイト確保した時点でビルドエラーになった。(あくまで、ほかの関数でも確保しようとしている領域があるためエラーになっているのであって、64バイト確保できないわけではない)

// uint8_t buffer[32]
Memory Summary:
    Program space        used  1200h (  4608) of  2000h words   ( 56.2%)
    Data space           used   31Eh (   798) of   400h bytes   ( 77.9%) <--
    EEPROM space         None available
    Data stack space     used     0h (     0) of    5Fh bytes   (  0.0%)
    Configuration bits   used     2h (     2) of     2h words   (100.0%)
    ID Location space    used     0h (     0) of     4h bytes   (  0.0%)

// uint8_t buffer[54]
Memory Summary:
    Program space        used  121Eh (  4638) of  2000h words   ( 56.6%)
    Data space           used   32Ah (   810) of   400h bytes   ( 79.1%) <--
    EEPROM space         None available
    Data stack space     used     0h (     0) of    49h bytes   (  0.0%)
    Configuration bits   used     2h (     2) of     2h words   (100.0%)
    ID Location space    used     0h (     0) of     4h bytes   (  0.0%)

// uint8_t buffer[64]

コンパイルエラー

この場合、ローカル変数をグローバル領域に移動してビルドすると、成功するようになる。

// compile error
void func(){

  uint8_t buffer[64];
  numBytes = getsUSBUSART(buffer, 64);
}
// compile ok
uint8_t buffer[64];
void func(){
  numBytes = getsUSBUSART(buffer, 64);
}

無償版コンパイラなので、このあたりの最適化が利いてない可能性がある。とりあえず、バッファなどの領域は全部グローバルに移動したほうが良さそう。