From 42b9929521a669ff065e9c6e286df2c39a0b8b4d Mon Sep 17 00:00:00 2001 From: dankers Date: Sat, 4 Jun 2011 09:35:55 +1000 Subject: [PATCH 1/5] Update milestones with the next heli challenge --- MILESTONES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MILESTONES.txt b/MILESTONES.txt index f0dd1962d..8f3e4a133 100644 --- a/MILESTONES.txt +++ b/MILESTONES.txt @@ -117,6 +117,10 @@ C: Sami Korhonen (Sambas) D: May 2011 V: http://vimeo.com/24258192 +M: First CopterControl flip on a Flybarless Heli +C: +D: +V: From 3e5d02cbaf9bb6942be49c0932e981dac6f79138 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Sat, 4 Jun 2011 08:55:15 -0500 Subject: [PATCH 2/5] OP-152: Abstract the CRC code out of uavtalk to allow it to be reused (PT - feel free to test moving this to the hardware CRC unit) --- flight/CopterControl/Makefile | 1 + flight/OpenPilot/Makefile | 1 + flight/PiOS/Common/pios_crc.c | 74 +++++++++++++++++++ flight/PiOS/inc/pios_crc.h | 31 ++++++++ flight/PiOS/pios.h | 2 + .../OpenPilotOSX.xcodeproj/project.pbxproj | 18 +++-- flight/UAVTalk/uavtalk.c | 73 ++---------------- 7 files changed, 128 insertions(+), 72 deletions(-) create mode 100644 flight/PiOS/Common/pios_crc.c create mode 100644 flight/PiOS/inc/pios_crc.h diff --git a/flight/CopterControl/Makefile b/flight/CopterControl/Makefile index bdfa8e2b5..21fa59f97 100644 --- a/flight/CopterControl/Makefile +++ b/flight/CopterControl/Makefile @@ -198,6 +198,7 @@ SRC += $(PIOSSTM32F10X)/pios_usb_hid_prop.c SRC += $(PIOSSTM32F10X)/pios_usb_hid_pwr.c ## PIOS Hardware (Common) +SRC += $(PIOSCOMMON)/pios_crc.c SRC += $(PIOSCOMMON)/pios_flashfs_objlist.c SRC += $(PIOSCOMMON)/pios_flash_w25x.c SRC += $(PIOSCOMMON)/pios_adxl345.c diff --git a/flight/OpenPilot/Makefile b/flight/OpenPilot/Makefile index a2a8e667b..a316f4cc3 100644 --- a/flight/OpenPilot/Makefile +++ b/flight/OpenPilot/Makefile @@ -186,6 +186,7 @@ SRC += $(PIOSSTM32F10X)/pios_usb_hid_prop.c SRC += $(PIOSSTM32F10X)/pios_usb_hid_pwr.c ## PIOS Hardware (Common) +SRC += $(PIOSCOMMON)/pios_crc.c SRC += $(PIOSCOMMON)/pios_sdcard.c SRC += $(PIOSCOMMON)/pios_com.c SRC += $(PIOSCOMMON)/pios_bmp085.c diff --git a/flight/PiOS/Common/pios_crc.c b/flight/PiOS/Common/pios_crc.c new file mode 100644 index 000000000..548ba2648 --- /dev/null +++ b/flight/PiOS/Common/pios_crc.c @@ -0,0 +1,74 @@ +/* + * pios_crc.c + * OpenPilotOSX + * + * Created by James Cotton on 6/4/11. + * Copyright 2011 OpenPilot. All rights reserved. + * + */ + +#include "pios.h" + +// CRC lookup table +static const uint8_t crc_table[256] = { + 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, + 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, + 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, + 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, + 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, + 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, + 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a, + 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, + 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, + 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, + 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, + 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, + 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63, + 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, + 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, + 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3 +}; + +/** + * Update the crc value with new data. + * + * Generated by pycrc v0.7.5, http://www.tty1.net/pycrc/ + * using the configuration: + * Width = 8 + * Poly = 0x07 + * XorIn = 0x00 + * ReflectIn = False + * XorOut = 0x00 + * ReflectOut = False + * Algorithm = table-driven + * + * \param crc The current crc value. + * \param data Pointer to a buffer of \a data_len bytes. + * \param length Number of bytes in the \a data buffer. + * \return The updated crc value. + */ +uint8_t PIOS_CRC_updateByte(uint8_t crc, const uint8_t data) +{ + return crc_table[crc ^ data]; +} + +/* + * @brief Update a CRC with a data buffer + * @param[in] crc Starting CRC value + * @param[in] data Data buffer + * @param[in] length Number of bytes to process + * @returns Updated CRC + */ +uint8_t PIOS_CRC_updateCRC(uint8_t crc, const uint8_t* data, int32_t length) +{ + // use registers for speed + register int32_t len = length; + register uint8_t crc8 = crc; + register const uint8_t *p = data; + + while (len--) + crc8 = crc_table[crc8 ^ *p++]; + + return crc8; +} + diff --git a/flight/PiOS/inc/pios_crc.h b/flight/PiOS/inc/pios_crc.h new file mode 100644 index 000000000..3a64f8bab --- /dev/null +++ b/flight/PiOS/inc/pios_crc.h @@ -0,0 +1,31 @@ +/** + ****************************************************************************** + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_CRC CRC Functions + * @{ + * + * @file pios_crc.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @brief CRC functions header. + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +uint8_t PIOS_CRC_updateByte(uint8_t crc, const uint8_t data); +uint8_t PIOS_CRC_updateCRC(uint8_t crc, const uint8_t* data, int32_t length); diff --git a/flight/PiOS/pios.h b/flight/PiOS/pios.h index 8362a3af4..ff7cd1af5 100644 --- a/flight/PiOS/pios.h +++ b/flight/PiOS/pios.h @@ -132,6 +132,8 @@ #include #endif +#include + #define NELEMENTS(x) (sizeof(x) / sizeof(*(x))) #endif /* PIOS_H */ diff --git a/flight/Project/OpenPilotOSX/OpenPilotOSX.xcodeproj/project.pbxproj b/flight/Project/OpenPilotOSX/OpenPilotOSX.xcodeproj/project.pbxproj index 7095dfad5..0fc7ccf73 100644 --- a/flight/Project/OpenPilotOSX/OpenPilotOSX.xcodeproj/project.pbxproj +++ b/flight/Project/OpenPilotOSX/OpenPilotOSX.xcodeproj/project.pbxproj @@ -2736,6 +2736,8 @@ 65E6E06112E031E300058553 /* STM32103CB_CC_Rev1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STM32103CB_CC_Rev1.h; sourceTree = ""; }; 65E6E06212E031E300058553 /* STM32103CB_PIPXTREME_Rev1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STM32103CB_PIPXTREME_Rev1.h; sourceTree = ""; }; 65E6E09912E037C800058553 /* pios_adc_priv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_adc_priv.h; sourceTree = ""; }; + 65E8C743139A6D0900E1F979 /* pios_crc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pios_crc.c; sourceTree = ""; }; + 65E8C745139A6D1A00E1F979 /* pios_crc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_crc.h; sourceTree = ""; }; 65E8EF1F11EEA61E00BBF654 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../../OpenPilot/Makefile; sourceTree = SOURCE_ROOT; }; 65E8EF2011EEA61E00BBF654 /* Makefile.posix */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Makefile.posix; path = ../../OpenPilot/Makefile.posix; sourceTree = SOURCE_ROOT; }; 65E8EF5C11EEA61E00BBF654 /* alarms.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = alarms.c; path = ../../OpenPilot/System/alarms.c; sourceTree = SOURCE_ROOT; }; @@ -7660,6 +7662,7 @@ 6528CCB412E406B800CF5144 /* pios_adxl345.c */, 6512D60712ED4CB8008175E5 /* pios_flash_w25x.c */, 65FF4D5E137EDEC100146BE4 /* pios_flashfs_objlist.c */, + 65E8C743139A6D0900E1F979 /* pios_crc.c */, ); name = Common; path = ../../PiOS/Common; @@ -7669,13 +7672,7 @@ isa = PBXGroup; children = ( 6528CCE212E40F6700CF5144 /* pios_adxl345.h */, - 6512D60512ED4CA2008175E5 /* pios_flash_w25x.h */, - 6526645B122DF972006F9A3C /* pios_wdg.h */, - 651CF9EF120B700D00EEFD70 /* pios_usb_hid_desc.h */, - 651CF9F0120B700D00EEFD70 /* pios_usb_hid_istr.h */, - 651CF9F1120B700D00EEFD70 /* pios_usb_hid_prop.h */, - 651CF9F2120B700D00EEFD70 /* pios_usb_hid_pwr.h */, - 651CF9F3120B700D00EEFD70 /* usb_conf.h */, + 65E8C745139A6D1A00E1F979 /* pios_crc.h */, 65E8F03A11EFF25C00BBF654 /* pios_adc.h */, 65E6E09912E037C800058553 /* pios_adc_priv.h */, 65E8F03B11EFF25C00BBF654 /* pios_bmp085.h */, @@ -7684,6 +7681,7 @@ 65E8F03E11EFF25C00BBF654 /* pios_debug.h */, 65E8F03F11EFF25C00BBF654 /* pios_delay.h */, 65E8F04011EFF25C00BBF654 /* pios_exti.h */, + 6512D60512ED4CA2008175E5 /* pios_flash_w25x.h */, 65FF4D61137EFA4F00146BE4 /* pios_flashfs_objlist.h */, 65E8F04111EFF25C00BBF654 /* pios_gpio.h */, 65E8F04211EFF25C00BBF654 /* pios_hmc5843.h */, @@ -7709,6 +7707,12 @@ 65E8F05211EFF25C00BBF654 /* pios_usart_priv.h */, 65E8F05311EFF25C00BBF654 /* pios_usb.h */, 65E8F05511EFF25C00BBF654 /* pios_usb_hid.h */, + 651CF9EF120B700D00EEFD70 /* pios_usb_hid_desc.h */, + 651CF9F0120B700D00EEFD70 /* pios_usb_hid_istr.h */, + 651CF9F1120B700D00EEFD70 /* pios_usb_hid_prop.h */, + 651CF9F2120B700D00EEFD70 /* pios_usb_hid_pwr.h */, + 6526645B122DF972006F9A3C /* pios_wdg.h */, + 651CF9F3120B700D00EEFD70 /* usb_conf.h */, 65E8F05611EFF25C00BBF654 /* stm32f10x_conf.h */, ); name = inc; diff --git a/flight/UAVTalk/uavtalk.c b/flight/UAVTalk/uavtalk.c index 57136db90..48ad03f53 100644 --- a/flight/UAVTalk/uavtalk.c +++ b/flight/UAVTalk/uavtalk.c @@ -50,25 +50,6 @@ #define MAX_PACKET_LENGTH (MAX_HEADER_LENGTH + MAX_PAYLOAD_LENGTH + CHECKSUM_LENGTH) -// CRC lookup table -static const uint8_t crc_table[256] = { - 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, - 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, - 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, - 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, - 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, - 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, - 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a, - 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, - 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, - 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, - 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, - 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, - 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63, - 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, - 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, - 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3 -}; // Private types typedef enum {STATE_SYNC, STATE_TYPE, STATE_SIZE, STATE_OBJID, STATE_INSTID, STATE_DATA, STATE_CS} RxState; @@ -85,8 +66,6 @@ static uint8_t txBuffer[MAX_PACKET_LENGTH]; static UAVTalkStats stats; // Private functions -static uint8_t updateCRCbyte(uint8_t crc, const uint8_t data); -static uint8_t updateCRC(uint8_t crc, const uint8_t* data, int32_t length); static int32_t objectTransaction(UAVObjHandle objectId, uint16_t instId, uint8_t type, int32_t timeout); static int32_t sendObject(UAVObjHandle obj, uint16_t instId, uint8_t type); static int32_t sendSingleObject(UAVObjHandle obj, uint16_t instId, uint8_t type); @@ -268,7 +247,7 @@ int32_t UAVTalkProcessInputStream(uint8_t rxbyte) break; // Initialize and update the CRC - cs = updateCRCbyte(0, rxbyte); + cs = PIOS_CRC_updateByte(0, rxbyte); rxPacketLength = 1; @@ -278,7 +257,7 @@ int32_t UAVTalkProcessInputStream(uint8_t rxbyte) case STATE_TYPE: // update the CRC - cs = updateCRCbyte(cs, rxbyte); + cs = PIOS_CRC_updateByte(cs, rxbyte); if ((rxbyte & TYPE_MASK) != TYPE_VER) { @@ -297,7 +276,7 @@ int32_t UAVTalkProcessInputStream(uint8_t rxbyte) case STATE_SIZE: // update the CRC - cs = updateCRCbyte(cs, rxbyte); + cs = PIOS_CRC_updateByte(cs, rxbyte); if (rxCount == 0) { @@ -322,7 +301,7 @@ int32_t UAVTalkProcessInputStream(uint8_t rxbyte) case STATE_OBJID: // update the CRC - cs = updateCRCbyte(cs, rxbyte); + cs = PIOS_CRC_updateByte(cs, rxbyte); objId += rxbyte << (8*(rxCount++)); @@ -393,7 +372,7 @@ int32_t UAVTalkProcessInputStream(uint8_t rxbyte) case STATE_INSTID: // update the CRC - cs = updateCRCbyte(cs, rxbyte); + cs = PIOS_CRC_updateByte(cs, rxbyte); instId += rxbyte << (8*(rxCount++)); @@ -413,7 +392,7 @@ int32_t UAVTalkProcessInputStream(uint8_t rxbyte) case STATE_DATA: // update the CRC - cs = updateCRCbyte(cs, rxbyte); + cs = PIOS_CRC_updateByte(cs, rxbyte); rxBuffer[rxCount++] = rxbyte; if (rxCount < length) @@ -681,7 +660,7 @@ static int32_t sendSingleObject(UAVObjHandle obj, uint16_t instId, uint8_t type) txBuffer[3] = (uint8_t)(((dataOffset+length) >> 8) & 0xFF); // Calculate checksum - txBuffer[dataOffset+length] = updateCRC(0, txBuffer, dataOffset+length); + txBuffer[dataOffset+length] = PIOS_CRC_updateCRC(0, txBuffer, dataOffset+length); // Send buffer if (outStream!=NULL) (*outStream)(txBuffer, dataOffset+length+CHECKSUM_LENGTH); @@ -720,7 +699,7 @@ static int32_t sendNack(uint32_t objId) txBuffer[3] = (uint8_t)(((dataOffset) >> 8) & 0xFF); // Calculate checksum - txBuffer[dataOffset] = updateCRC(0, txBuffer, dataOffset); + txBuffer[dataOffset] = PIOS_CRC_updateCRC(0, txBuffer, dataOffset); // Send buffer if (outStream!=NULL) (*outStream)(txBuffer, dataOffset+CHECKSUM_LENGTH); @@ -732,42 +711,6 @@ static int32_t sendNack(uint32_t objId) return 0; } - -/** - * Update the crc value with new data. - * - * Generated by pycrc v0.7.5, http://www.tty1.net/pycrc/ - * using the configuration: - * Width = 8 - * Poly = 0x07 - * XorIn = 0x00 - * ReflectIn = False - * XorOut = 0x00 - * ReflectOut = False - * Algorithm = table-driven - * - * \param crc The current crc value. - * \param data Pointer to a buffer of \a data_len bytes. - * \param length Number of bytes in the \a data buffer. - * \return The updated crc value. - */ -static uint8_t updateCRCbyte(uint8_t crc, const uint8_t data) -{ - return crc_table[crc ^ data]; -} -static uint8_t updateCRC(uint8_t crc, const uint8_t* data, int32_t length) -{ - // use registers for speed - register int32_t len = length; - register uint8_t crc8 = crc; - register const uint8_t *p = data; - - while (len--) - crc8 = crc_table[crc8 ^ *p++]; - - return crc8; -} - /** * @} * @} From 599483d5ac0c31a4bbc108508c714ff4ef26b6c2 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Sat, 4 Jun 2011 09:41:47 -0500 Subject: [PATCH 3/5] OP-152: Save CRC for object and header into flash and only load object if CRC matches. Read the flash first bytewise to compute CRC instead of buffering which is more RAM efficient but very inefficient as it sets up many one byte SPI transfers. Also incremented the filesystem magic flag to trigger an automatic flash wipe on this upgrade. --- flight/PiOS/Common/pios_flashfs_objlist.c | 42 ++++++++++++++++++++--- flight/UAVObjects/uavobjectmanager.c | 26 +++++++------- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/flight/PiOS/Common/pios_flashfs_objlist.c b/flight/PiOS/Common/pios_flashfs_objlist.c index 5c8248f54..937cdaadf 100644 --- a/flight/PiOS/Common/pios_flashfs_objlist.c +++ b/flight/PiOS/Common/pios_flashfs_objlist.c @@ -56,7 +56,7 @@ struct fileHeader { } __attribute__((packed)); -#define OBJECT_TABLE_MAGIC 0x85FB3C33 +#define OBJECT_TABLE_MAGIC 0x85FB3C34 #define OBJ_MAGIC 0x3015AE71 #define OBJECT_TABLE_START 0x00000010 #define OBJECT_TABLE_END 0x00001000 @@ -194,6 +194,7 @@ int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId) int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data) { uint32_t objId = UAVObjGetID(obj); + uint8_t crc = 0; int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId); @@ -215,14 +216,23 @@ int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data) return -2; // Save header - // This information IS redundant with the object table id. Oh well. Better safe than sorry. - + // This information IS redundant with the object table id. Oh well. Better safe than sorry. if(PIOS_Flash_W25X_WriteData(addr, (uint8_t *) &header, sizeof(header)) != 0) return -3; - + + // Update CRC + crc = PIOS_CRC_updateCRC(0, (uint8_t *) &header, sizeof(header)); + // Save data if(PIOS_Flash_W25X_WriteData(addr + sizeof(header), data, UAVObjGetNumBytes(obj)) != 0) return -4; + + // Update CRC + crc = PIOS_CRC_updateCRC(crc, (uint8_t *) data, UAVObjGetNumBytes(obj)); + + // Save CRC (written so will work when CRC changes to uint16) + if(PIOS_Flash_W25X_WriteData(addr + sizeof(header) + UAVObjGetNumBytes(obj), (uint8_t *) &crc, sizeof(crc)) != 0) + return -4; return 0; } @@ -236,12 +246,16 @@ int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data) * @retval -2 if unable to retrieve object header * @retval -3 if loaded data instId or objId don't match * @retval -4 if unable to retrieve instance data + * @retval -5 if unable to read CRC + * @retval -6 if CRC doesn't match * @note This uses one sector on the flash chip per object so that no buffering in ram * must be done when erasing the sector before a save */ int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data) { uint32_t objId = UAVObjGetID(obj); + uint8_t crc = 0; + uint8_t crcFlash = 0; int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId); @@ -256,13 +270,31 @@ int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data) if(PIOS_Flash_W25X_ReadData(addr, (uint8_t *) &header, sizeof(header)) != 0) return -2; + // Update CRC + crc = PIOS_CRC_updateCRC(0, (uint8_t *) &header, sizeof(header)); + if((header.id != objId) || (header.instId != instId)) return -3; + + // To avoid having to allocate the RAM for a copy of the object, we read once bytewise + // and compute the CRC (inefficient) + for(uint32_t i = 0; i < UAVObjGetNumBytes(obj); i++) { + uint8_t byte; + PIOS_Flash_W25X_ReadData(addr + sizeof(header) + i, &byte, 1); + crc = PIOS_CRC_updateByte(crc, byte); + } + + // Read CRC (written so will work when CRC changes to uint16) + if(PIOS_Flash_W25X_ReadData(addr + sizeof(header) + UAVObjGetNumBytes(obj), (uint8_t *) &crcFlash, sizeof(crcFlash)) != 0) + return -5; + if(crc != crcFlash) + return -6; + // Read the instance data if (PIOS_Flash_W25X_ReadData(addr + sizeof(header), data, UAVObjGetNumBytes(obj)) != 0) return -4; - + return 0; } diff --git a/flight/UAVObjects/uavobjectmanager.c b/flight/UAVObjects/uavobjectmanager.c index ef1774628..b6d3cf8d0 100644 --- a/flight/UAVObjects/uavobjectmanager.c +++ b/flight/UAVObjects/uavobjectmanager.c @@ -705,24 +705,24 @@ UAVObjHandle UAVObjLoadFromFile(FILEINFO * file) int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId) { #if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) - ObjectList *objEntry = (ObjectList *) obj; + ObjectList *objEntry = (ObjectList *) obj; - if (objEntry == NULL) - return -1; + if (objEntry == NULL) + return -1; - ObjectInstList *instEntry = getInstance(objEntry, instId); + ObjectInstList *instEntry = getInstance(objEntry, instId); - if (instEntry == NULL) - return -1; + if (instEntry == NULL) + return -1; - if (instEntry->data == NULL) - return -1; + if (instEntry->data == NULL) + return -1; - // Fire event on success - if (PIOS_FLASHFS_ObjLoad(obj, instId, instEntry->data) == 0) - sendEvent(objEntry, instId, EV_UNPACKED); - else - return -1; + // Fire event on success + if (PIOS_FLASHFS_ObjLoad(obj, instId, instEntry->data) == 0) + sendEvent(objEntry, instId, EV_UNPACKED); + else + return -1; #endif #if defined(PIOS_INCLUDE_SDCARD) From e02aa1b8181c073b6ac0e7673ac7838275aa94cc Mon Sep 17 00:00:00 2001 From: James Cotton Date: Sat, 4 Jun 2011 09:47:09 -0500 Subject: [PATCH 4/5] OP-152: Make the zeroing of LSB of has occur after hash is computed so that the LSB of individual field values still influences the hash Note: This update changes ALL object IDs. A new GCS is required to match the firmware. --- ground/uavobjgenerator/uavobjectparser.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ground/uavobjgenerator/uavobjectparser.cpp b/ground/uavobjgenerator/uavobjectparser.cpp index 149520cbf..2ab246ae8 100644 --- a/ground/uavobjgenerator/uavobjectparser.cpp +++ b/ground/uavobjgenerator/uavobjectparser.cpp @@ -237,6 +237,7 @@ QString UAVObjectParser::parseXML(QString& xml, QString& filename) * Calculate the unique object ID based on the object information. * The ID will change if the object definition changes, this is intentional * and is used to avoid connecting objects with incompatible configurations. + * The LSB is set to zero and is reserved for metadata */ void UAVObjectParser::calculateID(ObjectInfo* info) { @@ -252,7 +253,7 @@ void UAVObjectParser::calculateID(ObjectInfo* info) hash = updateHash(info->fields[n]->type, hash); } // Done - info->id = hash; + info->id = hash & 0xFFFFFFFE; } /** @@ -263,7 +264,7 @@ void UAVObjectParser::calculateID(ObjectInfo* info) */ quint32 UAVObjectParser::updateHash(quint32 value, quint32 hash) { - return (hash ^ ((hash<<5) + (hash>>2) + value)) & 0xFFFFFFFE; + return (hash ^ ((hash<<5) + (hash>>2) + value)); } /** From 0a56129b35d98da706e595ae3a62e0377a9fda97 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Sun, 5 Jun 2011 09:05:33 -0500 Subject: [PATCH 5/5] OP-452: Made the CRC calculation run in chunks to balance efficiency and ram usage, because Stac caught me being lazy :) --- flight/PiOS/Common/pios_flashfs_objlist.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/flight/PiOS/Common/pios_flashfs_objlist.c b/flight/PiOS/Common/pios_flashfs_objlist.c index 937cdaadf..ee3abe6f9 100644 --- a/flight/PiOS/Common/pios_flashfs_objlist.c +++ b/flight/PiOS/Common/pios_flashfs_objlist.c @@ -254,8 +254,11 @@ int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data) int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data) { uint32_t objId = UAVObjGetID(obj); + uint16_t objSize = UAVObjGetNumBytes(obj); uint8_t crc = 0; uint8_t crcFlash = 0; + const uint8_t crc_read_step = 8; + uint8_t crc_read_buffer[crc_read_step]; int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId); @@ -276,23 +279,23 @@ int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data) if((header.id != objId) || (header.instId != instId)) return -3; - // To avoid having to allocate the RAM for a copy of the object, we read once bytewise - // and compute the CRC (inefficient) - for(uint32_t i = 0; i < UAVObjGetNumBytes(obj); i++) { - uint8_t byte; - PIOS_Flash_W25X_ReadData(addr + sizeof(header) + i, &byte, 1); - crc = PIOS_CRC_updateByte(crc, byte); + // To avoid having to allocate the RAM for a copy of the object, we read by chunks + // and compute the CRC + for(uint32_t i = 0; i < objSize; i += crc_read_step) { + PIOS_Flash_W25X_ReadData(addr + sizeof(header) + i, crc_read_buffer, crc_read_step); + uint8_t valid_bytes = ((i + crc_read_step) >= objSize) ? objSize - i : crc_read_step; + crc = PIOS_CRC_updateCRC(crc, crc_read_buffer, valid_bytes); } // Read CRC (written so will work when CRC changes to uint16) - if(PIOS_Flash_W25X_ReadData(addr + sizeof(header) + UAVObjGetNumBytes(obj), (uint8_t *) &crcFlash, sizeof(crcFlash)) != 0) + if(PIOS_Flash_W25X_ReadData(addr + sizeof(header) + objSize, (uint8_t *) &crcFlash, sizeof(crcFlash)) != 0) return -5; if(crc != crcFlash) return -6; // Read the instance data - if (PIOS_Flash_W25X_ReadData(addr + sizeof(header), data, UAVObjGetNumBytes(obj)) != 0) + if (PIOS_Flash_W25X_ReadData(addr + sizeof(header), data, objSize) != 0) return -4; return 0;