ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
22 июля
1067237 Топик полностью
evgeniy1294 (06.01.2021 10:22, просмотров: 366) ответил VladislavS. на Я вижу тут много проблем.
1. Есть такое, да. На cortex-m0 можно словить HardFault, так как он не умеет невыровненный доступ. На этот случай, а также для быстрой обработки небольших пакетов, написана отдельная функция: 
template< typename T >
static void CalculateByByte( CRC_TypeDef* crc, const T* first, const T* last ) noexcept(true)
{
   const std::uint8_t* pu8 = reinterpret_cast< const std::uint8_t* >(first);
          
   while ( pu8 < reinterpret_cast<const std::uint8_t*>(last) )
      *reinterpret_cast< volatile std::uint8_t* >(&crc->DR) = *pu8++;
        
    return;
}

 

У st есть 3 версии аппаратных калькуляторов crc: v1, v2 и v2.2. первые две сильно зарезаны по функционалу. На версиях v1 и v2 скорее всего по байтам посчитать не получится, они аппаратно заточены для работы с массивами данных длиной, кратной 4. Результат просто не сойдется с работой программных калькуляторов.


Раз уж на версиях v1 и v2 можно работать только по словам, в этом случае компилятор сам позаботится о выравнивании (актуально для F0, например). Соответственно, шаблон в этом случае тоже не нужен.

static void Calculate( CRC_TypeDef* crc, const std::uint32_t* data, const std::uint32_t* end ) noexcept(true)

   while ( data < end )
      crc->DR = *data++;
        
   return;

}

Аппаратный калькулятор очень уж нестандартный, работает в Big Endian режиме, хотя ядро LittleEndian. Функция CalculateEther - попытка хоть как то применить аппаратный калькулятор в соответствии со стандартными алгоритмами. Скорее всего выпилю её и напишу реализацию алгоритма аппаратного калькулятора для PC на питоне и С++.


Для версии IP-ядра v2.2 таких ограничений уже нет, это полноценный калькулятор. И работать с данными он может как угодно, хоть байтами, хоть словами, но работать словами может быть быстрее за счет меньшего количества операций инкремента. Это может быть актуально для применений, требующих регулярной проверки целостности прошивки. Сейчас планирую сравнить скорость работы разных реализаций функции Calculate, возможно оставлю просто расчет по байтам, а всё остальное повыкидываю.

Скорее все сделаю так - для контроля целостности прошивки буду исползовать упрощенный режим, как для версии v1 и v2, как раз пригодится реализация алгоритма на питоне для расчетов на хосте. Для специальных применений оставлю функцию с побайтовым расчетом.


2. Видимо std::_Array_iterator<uint8_t, 9U> неявно кастуется к обычному указателю. Спасибо, что обратили внимание, изучу тему подробнее.