ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
22 июля
1067224 Топик полностью
VladislavS. (06.01.2021 09:07, просмотров: 435) ответил evgeniy1294 на Похоже, я таки наговнокодил. Исходные данные: МК GD32VF103 (RV32IMAC), тулчейн от klen'a, оптимизация -Os. Проблема заключается в некорректной работе функции подсчета crc с использованием аппаратного блока. Листинги кода и ассемблерный дамп в приложенном файле
Я вижу тут много проблем. 

1. Упаковка и невыровненый доступ. Вот тут *pu32 вы всенепременно когда-нибудь да огребёте. Даже если процессор умеет невыровненый доступ. Лучше соберите слово из четырёх (или меньше в хвосте) байт. Компилятор допетрит сам как это оптимально сделать.

2. TestSequence.data() это (uint8_t *). TestSequence.end() это std::_Array_iterator<uint8_t, 9U>. Не знаю почему компилятор такое молча пропускает, я бы на его месте обиделся.

std::array<std::uint8_t, 9> TestSequence;
  
template< typename T >
static std::uint32_t CalculateEther( const T* first, const T* last );
  
HardwareLogic::CalculateEther(TestSequence.data(), TestSequence.end());

3. Всё равно с ЛЮБЫМ типом этот код работать не будет. По хорошему, надо обкладывать его концептами, которые будут отсекать неподобающие типы. Так зачем их тянуть внутрь функции расчёта CRC? Для её работы нужен адрес (uint8_t *) и размер в байтах. Тогда будет работать железобетонно, если с невыровненым доступом не накосячить. Все вопросы преобразования типов и упаковки данных надо решать извне.

static std::uint32_t CalculateEther(const std::uint8_t *data, const std::uint32_t size);

Всё что сможет, компилятор и так оптимизирует.