]> rtime.felk.cvut.cz Git - arc.git/commitdiff
Implemented full support for big/little endian signals on big/little endian architectures
authortojo <devnull@localhost>
Mon, 4 Jul 2011 17:49:36 +0000 (19:49 +0200)
committertojo <devnull@localhost>
Mon, 4 Jul 2011 17:49:36 +0000 (19:49 +0200)
communication/Com/Com.c
communication/Com/Com_Com.c
communication/Com/Com_misc.c
communication/Com/Com_misc.h
include/Com.h

index 8e749b3624e38798aeb173d29fe0630cc27ea134..b3d857d6af87fe8d956bbd37b17bdf5f80a765ee 100644 (file)
 #include "Com_misc.h"\r
 #include "debug.h"\r
 \r
+\r
+/* TODO: Better way to get endianness across all compilers? */\r
+static const uint32_t endianness_test = 0xdeadbeef;\r
+ComSignalEndianess_type Com_SystemEndianness;\r
+\r
+\r
 const Com_ConfigType * ComConfig;\r
 \r
 \r
@@ -43,6 +49,14 @@ void Com_Init(const Com_ConfigType *config ) {
        uint32 earliestDeadline;\r
        uint32 firstTimeout;\r
 \r
+       uint8 endiannessByte = *(const uint8 *)&endianness_test;\r
+       if      ( endiannessByte == 0xef ) { Com_SystemEndianness = COM_LITTLE_ENDIAN; }\r
+       else if ( endiannessByte == 0xde ) { Com_SystemEndianness = COM_BIG_ENDIAN; }\r
+       else {\r
+               // No other endianness supported\r
+               assert(0);\r
+       }\r
+\r
        // Initialize each IPdu\r
        //ComIPdu_type *IPdu;\r
        //Com_Arc_IPdu_type *Arc_IPdu;\r
index e060683c901ff9573aaff13c8df93539acb49b87..50166f8fd2734abc83e1c1f5ac2814ebb2496aa6 100644 (file)
@@ -255,9 +255,10 @@ Std_ReturnType Com_ReceiveSignalGroup(Com_SignalGroupIdType SignalGroupId) {
 \r
 void Com_UpdateShadowSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {\r
        Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(SignalId);\r
+\r
        // TODO: CopyData\r
        // Com_CopyData(Arc_GroupSignal->Com_Arc_ShadowBuffer, SignalDataPtr, GroupSignal->ComBitSize, GroupSignal->ComBitPosition, 0);\r
-       Com_WriteSignalDataToPduBuffer(SignalId, TRUE, SignalDataPtr, (void *)Arc_GroupSignal->Com_Arc_ShadowBuffer);\r
+       Com_WriteSignalDataToPduBuffer(SignalId, TRUE, SignalDataPtr, (void *)Arc_GroupSignal->Com_Arc_ShadowBuffer, 8);\r
 }\r
 \r
 void Com_ReceiveShadowSignal(Com_SignalIdType SignalId, void *SignalDataPtr) {\r
index 8ed736e8265e1f256e69c94d3801ab9e63c293ad..9a2a835020b9d82886276c13c8ba0ecc9ed79d8e 100644 (file)
  * -------------------------------- Arctic Core ------------------------------*/\r
 \r
 \r
-\r
-\r
-\r
 #include <string.h>\r
+#include <assert.h>\r
 \r
 #include "Com_Arc_Types.h"\r
 #include "Com.h"\r
@@ -93,10 +91,11 @@ void Com_ReadSignalDataFromPduBuffer(
 \r
        // Pointer to a byte of the source and dest respectively.\r
        uint8 *signalDataBytes = (uint8 *)signalData;\r
+       uint8 signalDataBytesArray[8];\r
        const uint8 *pduBufferBytes = (const uint8 *)pduBuffer;\r
        uint8 startBitOffset = 0;\r
 \r
-       if (signalEndianess != CPU_ENDIANESS) {\r
+       if (signalEndianess == COM_LITTLE_ENDIAN) {\r
                // Swap source bytes before reading\r
                // TODO: Must adapt to larger PDUs!\r
                uint8 pduBufferBytes_swap[8];\r
@@ -106,17 +105,33 @@ void Com_ReadSignalDataFromPduBuffer(
                startBitOffset = intelBitNrToPduOffset(bitPosition, bitSize, 64);\r
                //lint -save -esym(960,12.5) PC-Lint Exception: OK. PC-Lint Wrong interpretation of MISRA rule 12.5.\r
                Com_ReadDataSegment(\r
-                               signalDataBytes, pduBufferBytes_swap, destSize,\r
+                               signalDataBytesArray, pduBufferBytes_swap, destSize,\r
                                startBitOffset, bitSize,\r
                                SignalTypeSignedness(signalType));\r
                //lint -restore\r
        } else {\r
                startBitOffset = motorolaBitNrToPduOffset(bitPosition);\r
                Com_ReadDataSegment(\r
-                               signalDataBytes, pduBufferBytes, destSize,\r
+                               signalDataBytesArray, pduBufferBytes, destSize,\r
                                startBitOffset, bitSize,\r
                                SignalTypeSignedness(signalType));\r
        }\r
+\r
+       if (Com_SystemEndianness == COM_BIG_ENDIAN) {\r
+               // Straight copy\r
+               int i;\r
+               for (i = 0; i < destSize; i++) {\r
+                       signalDataBytes[i] = signalDataBytesArray[i];\r
+               }\r
+\r
+       } else if (Com_SystemEndianness == COM_LITTLE_ENDIAN) {\r
+               // Data copy algorithm creates big-endian output data so we swap\r
+               int i;\r
+               for (i = 0; i < destSize; i++) {\r
+                       signalDataBytes[destSize - 1 - i] = signalDataBytesArray[i];\r
+               }\r
+       }\r
+\r
 }\r
 \r
 \r
@@ -125,16 +140,18 @@ void Com_WriteSignalDataToPdu(
                        const void *signalData) {\r
 \r
        // Get PDU\r
-       const ComSignal_type * Signal =  GET_Signal(signalId);\r
-       Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
-       Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
+       const ComSignal_type *Signal     = GET_Signal(signalId);\r
+       Com_Arc_Signal_type  *Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
+       Com_Arc_IPdu_type    *Arc_IPdu   = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
+       const ComIPdu_type   *IPdu       = GET_IPdu(Arc_Signal->ComIPduHandleId);\r
 \r
        // Get data\r
        Com_WriteSignalDataToPduBuffer(\r
                        signalId,\r
                        FALSE,\r
                        signalData,\r
-                       Arc_IPdu->ComIPduDataPtr);\r
+                       Arc_IPdu->ComIPduDataPtr,\r
+                       IPdu->ComIPduSize);\r
 }\r
 \r
 void Com_WriteGroupSignalDataToPdu(\r
@@ -143,16 +160,18 @@ void Com_WriteGroupSignalDataToPdu(
                const void *signalData) {\r
 \r
        // Get PDU\r
-       const ComSignal_type * Signal =  GET_Signal(parentSignalId);\r
-       Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
-       Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
+       const ComSignal_type *Signal     = GET_Signal(parentSignalId);\r
+       Com_Arc_Signal_type  *Arc_Signal = GET_ArcSignal(Signal->ComHandleId);\r
+       Com_Arc_IPdu_type    *Arc_IPdu   = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
+       const ComIPdu_type   *IPdu       = GET_IPdu(Arc_Signal->ComIPduHandleId);\r
 \r
        // Get data\r
        Com_WriteSignalDataToPduBuffer(\r
                        groupSignalId,\r
                        TRUE,\r
                        signalData,\r
-                       Arc_IPdu->ComIPduDataPtr);\r
+                       Arc_IPdu->ComIPduDataPtr,\r
+                       IPdu->ComIPduSize);\r
 }\r
 \r
 \r
@@ -160,13 +179,15 @@ void Com_WriteSignalDataToPduBuffer(
                        const uint16 signalId,\r
                        const boolean isGroupSignal,\r
                        const void *signalData,\r
-                       void *pduBuffer) {\r
+                       void *pduBuffer,\r
+                       const uint8 pduSize) {\r
        // TODO: Implement writing little-endian signals\r
 \r
        Com_SignalType signalType;\r
        uint8 signalLength;\r
        uint8 bitPosition;\r
        uint8 bitSize;\r
+       ComSignalEndianess_type endian;\r
 \r
        if (!isGroupSignal) {\r
                const ComSignal_type * Signal =  GET_Signal(signalId);\r
@@ -174,21 +195,57 @@ void Com_WriteSignalDataToPduBuffer(
                signalLength = Signal->ComBitSize / 8;\r
                bitPosition = Signal->ComBitPosition;\r
                bitSize = Signal->ComBitSize;\r
+               endian = Signal->ComSignalEndianess;\r
        } else {\r
                const ComGroupSignal_type *GroupSignal = GET_GroupSignal(signalId);\r
                signalType = GroupSignal->ComSignalType;\r
                signalLength = GroupSignal->ComBitSize / 8;\r
                bitPosition = GroupSignal->ComBitPosition;\r
                bitSize = GroupSignal->ComBitSize;\r
+               endian = GroupSignal->ComSignalEndianess;\r
        }\r
 \r
+       uint8 signalBufferSize = SignalTypeToSize(signalType, signalLength);\r
+       uint8 pduSignalMask[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
 \r
+       uint8 signalDataBytesArray[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
        const uint8 *signalDataBytes = (const uint8 *)signalData;\r
-       uint8 *pduBufferBytes = (uint8 *)pduBuffer;\r
-       uint8 startBitOffset = motorolaBitNrToPduOffset(bitPosition);\r
-       uint8 signalBufferSize = SignalTypeToSize(signalType, signalLength);\r
+       if (Com_SystemEndianness == COM_BIG_ENDIAN) {\r
+               // Straight copy\r
+               int i;\r
+               for (i = 0; i < signalBufferSize; i++) {\r
+                       signalDataBytesArray[i] = signalDataBytes[i];\r
+               }\r
+\r
+       } else if (Com_SystemEndianness == COM_LITTLE_ENDIAN) {\r
+               // Data copy algorithm assumes big-endian input data so we swap\r
+               int i;\r
+               for (i = 0; i < signalBufferSize; i++) {\r
+                       signalDataBytesArray[signalBufferSize - 1 - i] = signalDataBytes[i];\r
+               }\r
+       }\r
+\r
+       if (endian == COM_BIG_ENDIAN) {\r
+               uint8 *pduBufferBytes = (uint8 *)pduBuffer;\r
+               uint8 startBitOffset = motorolaBitNrToPduOffset(bitPosition);\r
+\r
+               Com_WriteDataSegment(pduBufferBytes, pduSignalMask,\r
+                               signalDataBytesArray, signalBufferSize, startBitOffset, bitSize);\r
 \r
-       Com_WriteDataSegment(pduBufferBytes, signalDataBytes, signalBufferSize, startBitOffset, bitSize);\r
+       } else {\r
+               uint8 startBitOffset = intelBitNrToPduOffset(bitPosition, bitSize, pduSize * 8);\r
+               uint8 pduBufferBytesSwapped[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
+\r
+               Com_WriteDataSegment(pduBufferBytesSwapped, pduSignalMask,\r
+                               signalDataBytesArray, signalBufferSize, startBitOffset, bitSize);\r
+\r
+               uint8 *pduBufferBytes = (uint8 *)pduBuffer;\r
+               uint8 i;\r
+               for (i = 0; i < pduSize; i++) {\r
+                       pduBufferBytes[ i ]  &=       ~( pduSignalMask[ (pduSize - 1) - i ] );\r
+                       pduBufferBytes[ i ]  |=  pduBufferBytesSwapped[ (pduSize - 1) - i ];\r
+               }\r
+       }\r
 }\r
 \r
 \r
@@ -304,8 +361,10 @@ void Com_ReadDataSegment(uint8 *dest, const uint8 *source, uint8 destByteLength,
  * Copies the <segmentBitLength> least significant bits from <signal> into <pdu>.\r
  * The bit segment is placed in <pdu> so that the most significant bit ends up\r
  * at <segmentStartBitOffset> from the msb of <pdu>.\r
+ * <pduSignalMask> is cleared and written to contain a mask with 1´s where the\r
+ * signal is located in the <pdu>.\r
  */\r
-void Com_WriteDataSegment(uint8 *pdu, const uint8 *signalDataPtr, uint8 destByteLength,\r
+void Com_WriteDataSegment(uint8 *pdu, uint8 *pduSignalMask, const uint8 *signalDataPtr, uint8 destByteLength,\r
                uint8 segmentStartBitOffset, uint8 segmentBitLength) {\r
        uint8 pduEndBitOffset = segmentStartBitOffset + segmentBitLength - 1;\r
        uint8 pduStartByte = segmentStartBitOffset / 8;\r
@@ -323,8 +382,13 @@ void Com_WriteDataSegment(uint8 *pdu, const uint8 *signalDataPtr, uint8 destByte
        uint16 shiftReg = 0;\r
        uint16 clearReg = 0;\r
 \r
+       // clear pduSignalMask all the way from 0\r
+       memset(pduSignalMask, 0x00, pduEndByte);\r
+\r
        // setup to point to end (LSB) of buffers\r
-       pdu += pduEndByte;\r
+       pdu           += pduEndByte;\r
+       pduSignalMask += pduEndByte;\r
+\r
        signalDataPtr += destByteLength - 1;\r
 \r
        // splits and writes one source byte on each iteration\r
@@ -339,8 +403,9 @@ void Com_WriteDataSegment(uint8 *pdu, const uint8 *signalDataPtr, uint8 destByte
                        shiftReg &= pduStartByteMask;\r
                        clearReg &= pduStartByteMask;\r
                }\r
-               *(pdu - pduByteNr) &= (uint16)~(clearReg & 0x00FFu);\r
-               *(pdu - pduByteNr) |= shiftReg & 0x00FFu;\r
+               *(pdu           - pduByteNr) &= (uint16)~(clearReg & 0x00FFu);\r
+               *(pduSignalMask - pduByteNr) |= (uint16) (clearReg & 0x00FFu);\r
+               *(pdu           - pduByteNr) |= shiftReg & 0x00FFu;\r
 \r
                pduByteNr++;\r
                if ( (pduAlignmentShift != 0)\r
@@ -357,8 +422,9 @@ void Com_WriteDataSegment(uint8 *pdu, const uint8 *signalDataPtr, uint8 destByte
                                shiftReg &= pduStartByteMask;\r
                                clearReg &= pduStartByteMask;\r
                        }\r
-                       *(pdu - pduByteNr) &= (uint16)~(clearReg & 0x00FFu);\r
-                       *(pdu - pduByteNr) |= shiftReg & 0x00FFu;\r
+                       *(pdu           - pduByteNr) &= (uint16)~(clearReg & 0x00FFu);\r
+                       *(pduSignalMask - pduByteNr) |= (uint16) (clearReg & 0x00FFu);\r
+                       *(pdu           - pduByteNr) |= shiftReg & 0x00FFu;\r
                }\r
                signalByteNr++;\r
        } while (signalByteNr < segmentByteLength);\r
index a084bcbb5bd5be5b147fa6a67bf711e93a76423a..71fae664511c94d4cebccad3fb36d6bf0eaf3b76 100644 (file)
@@ -56,7 +56,8 @@ void Com_WriteSignalDataToPduBuffer(
                const uint16 signalId,\r
                const boolean isGroupSignal,\r
                const void *signalData,\r
-               void *pduBuffer);\r
+               void *pduBuffer,\r
+               const uint8 pduSize);\r
 \r
 /*\r
  * This function copies numBits bits of data from Source to Destination with the possibility to offset\r
@@ -71,7 +72,7 @@ void Com_WriteSignalDataToPduBuffer(
 void Com_ReadDataSegment(uint8 *dest, const uint8 *source, uint8 destByteLength,\r
                uint8 segmentStartBitOffset, uint8 segmentBitLength, boolean signedOutput);\r
 \r
-void Com_WriteDataSegment(uint8 *pdu, const uint8 *signalDataPtr, uint8 destByteLength,\r
+void Com_WriteDataSegment(uint8 *pdu, uint8 *pduSignalMask, const uint8 *signalDataPtr, uint8 destByteLength,\r
                uint8 segmentStartBitOffset, uint8 segmentBitLength);\r
 \r
 uint8 motorolaBitNrToPduOffset (uint8 motorolaBitNr);\r
index 40ab68a79b1c9e83a12766018773f14c780157db..305f938d7eaf5192d8ac7ae3fef59c9879a91a42 100644 (file)
@@ -79,4 +79,6 @@ void Com_IpduGroupStart(Com_PduGroupIdType IpduGroupId, boolean Initialize);
 void Com_IpduGroupStop(Com_PduGroupIdType IpduGroupId);\r
 \r
 \r
+extern ComSignalEndianess_type Com_SystemEndianness;\r
+\r
 #endif /*COM_H_*/\r