Darth Vader 0 25 марта, 2021 Опубликовано 25 марта, 2021 · Жалоба 9 часов назад, MasterElectric сказал: и ты чтобы сбросить CRC предлагаешь создавать новый экземпляр класса? Я этого нигде не предлагал. Подход в стиле С++ предполагает описание класса CRC32 с некоторым набором публичных методов и приватных данных. Для расчета создаем объект класса (локально), вызываем нужные нам методы, получаем результат. При выходе из области видимости, объект автоматически освобождает занимаемую им в стеке память. Понадобилось посчитать CRC в другом месте - создали там локальный объект, использовали его, он снова разрушился при выходе из области видимости и т.д. 9 часов назад, MasterElectric сказал: чем это локальная статическая отличается от глобальной кроме зоны видимости? Областью видимости, очевидно. Глобальную переменную может поменять кто угодно в любой момент времени. Никто не может гарантировать её неизменности между вызовами функции. Кто мешает поменять её, например, в обработчике прерывания или в любой другой функции? А локальную статическую переменную может изменить только та функция, в которой она определена. Она гарантированно останется неизменной от выхода из функции до следующего входа в неё. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tpeck 0 25 марта, 2021 Опубликовано 25 марта, 2021 · Жалоба 24 minutes ago, Darth Vader said: Подход в стиле С++ предполагает описание класса CRC32 с некоторым набором публичных методов и приватных данных. Для расчета создаем объект класса (локально), вызываем нужные нам методы, получаем результат. При выходе из области видимости, объект автоматически освобождает занимаемую им в стеке память. Понадобилось посчитать CRC в другом месте - создали там локальный объект, использовали его, он снова разрушился при выходе из области видимости и т.д. А почему это нельзя сделать простой функцией? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 25 марта, 2021 Опубликовано 25 марта, 2021 · Жалоба 14 минут назад, Tpeck сказал: А почему это нельзя сделать простой функцией? Можно, я даже пример выше привёл полного расчёта одной функцией. Но, иногда требуется большая гибкость в расчёте. Самый простой пример - посчитать СRC области памяти с разрывами. Т.е надо посчитать от А до Б, потом, не сбрасывая расчет, продолжить с В до Г и т.д. И вот тогда одной функцией уже не обойдешься. Нужно семейство взаимосвязанных функций, имеющих доступ к общему набору данных, скрытому от всей другой программы. А это уже класс С++ в чистом виде. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ivan24190 0 25 марта, 2021 Опубликовано 25 марта, 2021 · Жалоба Когда требуется считать CRC данных с "разрывами", то в функцию, выполняющую расчёт CRC, дополнительным параметром можно передать CRC, которое было рассчитано для предыдущего блока данных. И так повторить для требуемого количества блоков. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 25 марта, 2021 Опубликовано 25 марта, 2021 · Жалоба 7 минут назад, ivan24190 сказал: в функцию, выполняющую расчёт CRC, дополнительным параметром можно передать CRC, которое было рассчитано для предыдущего блока данных. Можно и так. Я просто обратил внимание автора топика на то, что делать так, как он некрасиво. Общие для его функций данные не должны быть видны никому, кроме этих функций. Их надо скрыть. И вот мы не спеша приходим к концепции класса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 27 марта, 2021 Опубликовано 27 марта, 2021 · Жалоба Слегка модифицировав предыдущий пример функции расчета, можно получить такую, которой можно считать данные с разрывами #include <stdint.h> //-------------------------------------------------------------------------------------------------------------------------- // Тип расчёта: начать новый или продолжить старый //-------------------------------------------------------------------------------------------------------------------------- typedef enum { CALC_NEW, CALC_CONTINUE } CalcVariant_t; //-------------------------------------------------------------------------------------------------------------------------- // Функция расчёта КС CRC-32 // obj_p - указатель на объект // len - размер объекта в байтах // variant - тип расчёта: начать новый или продолжить старый //-------------------------------------------------------------------------------------------------------------------------- uint32_t calc(const void *obj_p, uint32_t len, CalcVariant_t variant) { // Таблица предвычисленных констант для быстрого расчёта static const uint32_t Crc32Table[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; static uint32_t CurrVal = 0xFFFFFFFF; // текущее накопленное значение суммы const uint8_t *CurrByte_p = (const uint8_t*)obj_p; // указатель на текущий байт данных if(variant==CALC_NEW) { CurrVal = 0xFFFFFFFF; // для нового расчёта сбрасываем накопленную сумму } while (len--) { CurrVal = (CurrVal >> 8) ^ Crc32Table[(CurrVal ^ *CurrByte_p++) & 0xFF]; } return ~CurrVal; // возвращаем значение CRC32, как инверсии накопленной суммы }; Хорошо видно, зачем нужны локальные статические константы и переменные. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 27 марта, 2021 Опубликовано 27 марта, 2021 (изменено) · Жалоба 4 hours ago, Darth Vader said: для нового расчёта сбрасываем накопленную сумму Я бы просто начальное значение передавал... Избавив себя от головной боли про хранимое состояние. И про thread-safe. Оно или начальное или результат расчета про предидущему сегменту. Изменено 27 марта, 2021 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 28 марта, 2021 Опубликовано 28 марта, 2021 · Жалоба Перемудрил)... нужно еще улучшать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 28 марта, 2021 Опубликовано 28 марта, 2021 · Жалоба 3 часа назад, MasterElectric сказал: нужно еще улучшать #include "crc32.h" //-------------------------------------------------------------------------------------------------------------------------- // Функция расчёта КС CRC-32 // obj_p - указатель на объект // len - размер объекта в байтах // start_val - начальное значение для расчёта: // - для начала нового надо передать 0 // - для продолжения предыдущего надо передать предыдущее значение КС //-------------------------------------------------------------------------------------------------------------------------- uint32_t calc(const void *obj_p, uint32_t len, uint32_t start_val) { // Таблица предвычисленных констант для быстрого расчёта static const uint32_t Crc32Table[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; start_val = ~start_val; // начальное значение суммы для расчёта const uint8_t *CurrByte_p = (const uint8_t*)obj_p; // указатель на текущий байт данных // Накапливаем значение while (len--) { start_val = (start_val >> 8) ^ Crc32Table[(start_val ^ *CurrByte_p++) & 0xFF]; } return ~start_val; // возвращаем значение CRC32, как инверсии накопленной суммы }; Это потоково-безопасный вариант, за счет отказа от статической локальной переменной, хранящей предыдущее рассчитанное значение. Теперь оно передаётся параметром. Собственно, это главное достоинство именно такой реализации перед предыдущей. Стоит заметить, что вариант реализации через класс С++, о котором я говорил ранее, изначально по-определению потоково-безопасный. Там накапливаемая сумма является приватным членом класса. Если надо посчитать КС, то каждый поток создает свой локальный экземпляр класса. В результате потоки никак не влияют друг на друга, каждый из них использует и меняет только свои данные. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 28 марта, 2021 Опубликовано 28 марта, 2021 · Жалоба On 3/25/2021 at 11:02 AM, Eddy_Em said: А можно задать нескромный вопрос: что за камень используется, если у него нет блока аппаратного вычисления CRC? Зачем на STM32 вычислять CRC программно? Хороший вопрос ! Присоединяюсь. Только почему-то его все, включая топик-стартера, проигнорировали :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 28 марта, 2021 Опубликовано 28 марта, 2021 · Жалоба 2 минуты назад, dimka76 сказал: Только почему-то его все, включая топик-стартера, проигнорировали :( Не всегда возможно использовать встроенный, даже если он есть. Может быть полином не устраивает, а может например - аппаратный блок нереентерабелен. Или аппаратный CRC занят в данный момент. Мало ли почему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Михась 2 29 марта, 2021 Опубликовано 29 марта, 2021 · Жалоба У меня например софтовый CRC потому что уже есть программа для формирования криптованных образов прошивок для раздачи заказчикам. И сразу закладываюсь что возможно новая версия изделия будет на другом процессоре (с отсутствующим или другим блоком CRC), чтобы не менять ПО у себя и Программу-загрузчик на ПК у заказчика. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 29 марта, 2021 Опубликовано 29 марта, 2021 · Жалоба Ну я сразу давал ссылку на статью про аппаратный блок CRC, но судя по всему ТС нужен CRC для обновления прошивки, а свободного времени в бутлоадере 99%, тем более с аппаратным CRC при расчете CRC32 не все нормально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться