Mais uma vez sobre os modelos C ++ em microcontroladores

Introdução

A ideia de usar templates C ++ para controladores de programação não é nova, há muito material disponível na web. Deixe-me relembrar brevemente as principais vantagens: transferir uma parte significativa dos erros do tempo de execução para o tempo de compilação devido ao controle de tipo estrito, bem como uma aproximação a uma abordagem orientada a objetos, que é próxima e conveniente para muitos, sem a necessidade de armazene campos em uma classe estática (todos os campos são parâmetros de modelo). Porém, é importante notar que quase todos os autores em geral se limitam em seus trabalhos a exemplos de trabalho com registradores e portas de E / S. No meu artigo, quero dar continuidade a essas idéias.





Você não pode estar um pouco grávida

A programação orientada a objetos implica na presença de classes em um programa que interagem umas com as outras. A interação é expressa pela dependência de algumas classes de outras. E aqui a essência do cabeçalho aparece: para passar uma classe de modelo B com métodos estáticos para a classe A como um parâmetro , então a classe B também deve ser transformada em modelo, e assim por diante ao longo de toda a cadeia.





Por exemplo, USART pelo menos depende de seus registros, então a declaração da classe correspondente será parecida com isto (o código associado à declaração de registros é retirado daqui para garantir a consistência dos artigos, obrigado @lamerok pelos materiais legais e exemplos. Não passei os invólucros, mas pretendo.):





template <typename _Regs>
class Usart
{
public:
  static void Init()
  {
    _Regs::CR1Pack<_Regs::CR1::UE, _Regs::CR1::RE, _Regs::CR1::TE>::Set();
    //  - .
  }
}
      
      



Nós descobrimos os registradores para declarar uma instância UART específica, você precisa especializar o modelo





using Usart1 = Usart<USART1>;
      
      



Tudo parece ótimo, mas, na verdade, uma interface USART específica tem dependências diferentes:





  1. Registro do relógio (RCC_APB2).





  2. Número de interrupção.





  3. Um conjunto de pinos possíveis (Tx e Rx).





  4. Dma (Tx e Rx).





- - , . ,





template <typename _Regs, typename _ClockCtrl>
class Usart
{
public:
  static void Init()
  {
    //       
    _ClockCtrl::Enable()
    _Regs::CR1Pack<_Regs::CR1::UE, _Regs::CR1::RE, _Regs::CR1::TE>::Set();
    ...
  }
}
      
      



. , Init / RCC_ARB2, ?





-, , . , USART






//   TX UART  SPL.
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure); //

      
      



: , , , , . :





//   Tx  Rx .
template<typename _Regs, IRQn_Type _IRQNumber, typename _ClockCtrl, typename _TxPins, typename _RxPins, typename _DmaTx, typename _DmaRx>
template<typename TxPin, typename RxPin>
void Usart<_Regs, _IRQNumber, _ClockCtrl, _TxPins, _RxPins, _DmaTx, _DmaRx>::SelectTxRxPins()
{
  const int8_t txPinIndex = TypeIndex<TxPin, _TxPins>::value;
  const int8_t rxPinIndex = !std::is_same_v<RxPin, IO::NullPin>
        ? TypeIndex<RxPin, typename _RxPins>::value
        : -1; //    ,    NullPin   
  static_assert(txPinIndex >= 0);
  //    Rx 
  static_assert(rxPinIndex >= -1);
  SelectTxRxPins<txPinIndex, rxPinIndex>();
}
      
      



USART SelectTxRxPins , , - static_assert.





, , C++ GPIO, , .





//     DS1307
template <typename _I2CBus>
class Ds1307
{
  ...
  static Time GetDateTime()
  {
    Time time;
    _I2CBus::Read(Ds1307Address, 0x00, &time, sizeof(time));
    ...
      
      



, , :





using Rtc = Ds1307<I2c1>;
      
      



, , ( neiver, - ++ easyelectronics.ru) "". github "Mcucpp", . , , , , , ( , 2019, ). , , , , , Doxy-, , . Zhele, Stm32. , , , .





" , " © ..





, , gpio, , i2c/spi/uart/one-wire, , .





, . custom- CubeIDE. , , , , , , , , , , . .





  1. - ++





  2. Pin. ++ ( CortexM)





  3. ++ ( CortexM)





  4. AVR
















All Articles