1

CAN メッセージのデータ フィールドの値を 16 進形式の一連のショートとして出力できるコードを作成しようとしています。CAN メッセージ データ フィールドには 4 つの short が含まれているため、たとえば、1 つのメッセージを「FFFF EEEE ABAB 2013」として出力する場合があります。

CAN メッセージの 2 つの short を整数値にエンコードできます。整数の 32 番目のビットが設定されていない限り、すべて正常に動作します。Java は符号付き整数を使用するため、32 番目のビットを設定すると、一連の "f" が出力されます。私が望むのは、整数を符号なしの値として機能させて、出力しても問題が発生しないようにすることです。

うまくいかない例を次に示します。

(int value): 0x80000000
(string rep short 1): 0xffff8000
<crash>

そして、これが他のすべての場合にどのように機能するかを示します。

(int value): 0x40000000
(string rep short 1): 0x4000
(string rep short 2): 0x0

CAN メッセージ データを表現しようとするコードとクラッシュが発生するコード:

public String getFormattedData() {
    String dataString = "";

    for(String aShort : Utility.splitStringByWhitespace(getData())) {
        try{
            dataString += ("0000".substring(0, 4 - aShort.length()) + aShort) + " ";
        } catch(Exception e) {
            System.out.println(getData());
            System.exit(1);
        }
    }

    return dataString.toUpperCase();
}

具体的には、「f」が short の文字列表現の長さを 8 文字に増やし、「4 - aShort.length()」が無効な負の値を生成するため、クラッシュが発生します。

編集:お尋ねの場合、この特定のケースでは、文字列表現に変換する前に整数を使用してデータをエンコードする方法を次に示します。

public String convertToCANMessageData(PWMChannel channel) {
    int channelVal = channel.getValue();
    int entryDataHI = 0, entryDataLO = 0;

    entryDataHI += channelVal << 24;
    entryDataHI += smallData << 8;
    entryDataHI += (largeData >> 8) & 0xFF;
    entryDataLO += (largeData & 0xFF) << 24;

    if(ramping) {
        entryDataHI = entryDataHI | (1 << 16);
    } else {
        entryDataHI = entryDataHI & ~(1 << 16);
    }

    if(jumping) {
        entryDataHI = entryDataHI | (1 << 17);
    } else {
        entryDataHI = entryDataHI & ~(1 << 17);
    }

    if(frequencySetting) {
        entryDataHI = entryDataHI | (1 << 18);
    } else {
        entryDataHI = entryDataHI & ~(1 << 18);
    }

    return String.format("%x %x %x %x", entryDataHI >> 16, entryDataHI & 0xFFFF,
                            entryDataLO >> 16, entryDataLO & 0xFFFF);
}
4

3 に答える 3

0

ユーティリティ関数を追加することで、今のところ問題を解決しました。

public static int parseShort(String aShort) {
    if(aShort.length() > 4) aShort = aShort.substring(aShort.length()-4);

    return Integer.parseInt(aShort, 16);
}

誰かがより良い解決策を持っている場合は、その回答を承認済みとしてマークし、代わりにそれを試していただければ幸いです。

于 2013-09-19T14:09:06.210 に答える