2

私はPICC18を使用してかなり簡単な呼び出しを行おうとしています。

MPLABシミュレータを使用すると、関数に入るときでさえ、引数が完全に文字化けしているのがわかります。

私は次のtypedefを持っています

typedef struct
{
    //  t_ax25AddressChar callsign[6];
    unsigned char callsign[6];
    union
    {
        struct
        {
            unsigned isRepeated:1; // MSB - 1=repeated
            unsigned reserved:2; // Reserved
            unsigned ssid:4; // SSID
            unsigned isLast:1; // LSB - Is the last address
        };
        unsigned char value;
    } flags;
} t_ax25Callsign;

(私のTODOリストには、ビットフィールドを指定するために必要な順序の計算が含まれています)

それはさらなる構造体に埋め込まれています

typedef struct
{
    union
    {
        struct
        {
            t_ax25Callsign to;
            t_ax25Callsign from;
            t_ax25Callsign path[APRS_MAX_REPEATERS];
        };
        t_ax25Callsign allCallsigns[APRS_MAX_REPEATERS + 2];
    } address;
    // PID and Control are hard coded for APRS
    const char message[APRS_MAX_MESSAGE_LENGTH + 1]; // null terminated message string
} t_aprsPacket;

ページングされたRAMのどこかに割り当てられます(main.c内)

#pragma udata   
static t_aprsPacket s_packet;

aprs.hで定義されているメソッド

extern void aprsMakeCallsignPgm(t_ax25Callsign *buffer,
                                const rom char *callsign, unsigned char ssid);

(string.hの例に従って、そこに「far」を入れてみました。効果はありません。このPICには64Kがないので、すべてを「near」として再コンパイルする必要があります)

aprs.cでの実装は

void aprsMakeCallsignPgm(t_ax25Callsign *buffer,
                     const rom char *callsign,
                     unsigned char ssid)
{
    int i = 0;
    volatile char ch;
    for(i=0; i<6 && (ch = callsign[i]) != 0; i++)
    {
        buffer->callsign[i] = ch << 1;
    }
    for(   ; i<6; i++)
    {
        buffer->callsign[i] = (' '<<1);
    }

    buffer->flags.value = 0;
    buffer->flags.ssid = ssid;
}

(最適化することができます。最初にこれを機能させるのが最善です。この実装により、ループを一周するときにchに何があるかを確認できます。)

main.cのmain()からのいくつかの呼び出しは次のとおりです。

aprsMakeCallsignPgm(&(s_packet.address.from), "M0RJC", (unsigned char)9);
aprsMakeCallsignPgm(&(s_packet.address.to), "APRS", 0);
s_packet.address.to.flags.isLast = 1;
strcpypgm2ram(s_packet.message, "Hard coded test message");

(unsigned char)へのキャストも役に立ちませんでした。

最初の3行はコンパイルされますが、MPLABシミュレータで実行すると、関数実装の引数にジブリッシュが発生します。

strcpy行は、コンパイラに「警告[2066]型修飾子の割り当ての不一致」という警告を出します。それがどの割り当てを教えてくれたらいいのにと思います。

私はここで何を間違えましたか?

ありがとう

  • リチャード
4

1 に答える 1

3

FSR2 を使用するアセンブラーの初期化ルーチンを呼び出していたため、C スタックが破損していました。代わりに FSR0 を使用するように変更したところ、動作するようになりました。

同じことを行う短いコードは次のとおりです。

void aprsMakeCallsignPgm(t_ax25Callsign *buffer,
                         const rom char *callsign,
                         unsigned char ssid)
{
    int i; 
    overlay char *dst = buffer->callsign;
    for(i = 6; i && (*dst++ = (*callsign++ << 1)); i--);
    dst--; // Rewind that 0. Good job flags is there to save from overrun
    for(   ; i ; i--) *dst++ = (' '<<1);

    buffer->flags.value = (ssid & 0x0F) << 1;
}

「デバッグ」モードでコンパイルしているため、最適化されていません。私はコンパイラの評価版しか持っていないので、このモードでどのように動作するかを確認すると便利です。新しいバージョンでは、66 のプログラム ロケーションと 3 バイトの RAM が節約されます。また、ビットフィールドの正しい方法は次のとおりであることも教えてくれます

   struct
    {
        unsigned isLast:1;     // LSB - Is the last address
        unsigned ssid:4;       // SSID
        unsigned reserved:2;   // Reserved
        unsigned isRepeated:1; // MSB - 1=repeated
    };

<< 演算子はキャリーを含まないと見なします。

ありがとう - リチャード

(私はこの質問に削除のマークを付けます - ただし、お気に入りとしてマークされているので、誰かの足元から一掃したくないことに注意してください)

于 2011-08-23T21:48:33.300 に答える