Estou procurando abstrações em C ++ para pontos ou pinos de E / S de hardware. Coisas como in_pin, out_pin, inout_pin, talvez open_collector_pin, etc.
Certamente eu mesmo posso criar esse conjunto de abstrações, então não estou procurando o tipo de respostas 'ei, você pode fazer desta maneira', mas sim o 'olhar para esta biblioteca que foi usada neste e este projeto'.
O Google não apareceu nada, talvez porque não sei como os outros chamariam isso.
Meu objetivo é criar bibliotecas de E / S baseadas nesses pontos, mas também fornecê-los, por isso seria fácil, por exemplo, conectar um HD44780 LCd aos pinos de E / S do chip ou a um I2C (ou SPI) Extensor de E / S ou qualquer outro ponto que possa ser controlado de alguma forma, sem nenhuma alteração na classe do LCD.
Eu sei que isso está no limite da eletrônica / software, desculpe se ele não pertence aqui.
@leon: fiação Esse é um grande pacote de software, vou precisar olhar mais de perto. Mas parece que eles não usam uma abstração de pinos como eu quero. Por exemplo, na implementação do teclado, vejo
digitalWrite(columnPins[c], LOW); // Activate the current column.
Isso implica que há uma função (digitalWrite) que sabe gravar em um pino de E / S. Isso torna impossível adicionar um novo tipo de pino de E / S (por exemplo, um que esteja em um MCP23017, portanto ele deve ser gravado via I2C) sem reescrever a função digitalWrite.
@Oli: pesquisei no Google um exemplo de IO do Arduino, mas eles parecem usar a mesma abordagem da biblioteca Wiring:
int ledPin = 13; // LED connected to digital pin 13
void setup(){
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}
fonte
Respostas:
Resposta curta: infelizmente, não há biblioteca para fazer o que você deseja. Eu já fiz isso várias vezes, mas sempre em projetos não de código aberto. Estou pensando em colocar algo no github, mas não tenho certeza de quando posso.
Por que C ++?
fonte
Permita-me conectar descaradamente meu projeto de código aberto https://Kvasir.io . A parte Kvasir :: Io fornece funções de manipulação de pinos. Você deve primeiro definir seu pino usando um Kvasir :: Io :: PinLocation da seguinte maneira:
Observe que isso realmente não usa RAM porque essas são variáveis constexpr.
Em todo o seu código, você pode usar esses locais de pinos nas funções de "fábrica de ações", como makeOpenDrain, set, clear, makeOutput e assim por diante. Um 'action factory' não executa a ação, mas retorna um Kvasir :: Register :: Action que pode ser executado usando Kvasir :: Register :: apply (). A razão para isso é que apply () mescla as ações transmitidas a ele quando elas agem em um mesmo registro para que haja um ganho de eficiência.
Como a criação e mesclagem de ações são feitas em tempo de compilação, isso deve produzir o mesmo código do assembler que o equivalente codificado manualmente:
fonte
O projeto Wiring usa abstração assim:
http://wiring.org.co/
e o compilador é escrito em C ++. Você deve encontrar muitos exemplos no código fonte. O software Arduino é baseado em fiação.
fonte
Em C ++, é possível escrever uma classe para que você possa usar portas de E / S como se fossem variáveis, por exemplo
sem considerar a implementação subjacente. Por exemplo, se alguém estiver usando uma plataforma de hardware que não suporta operações no nível de bits, mas suporta operações de registro no nível de bytes, é possível (provavelmente com a ajuda de algumas macros) definir uma classe estática IO_PORTS com leitura / gravação em linha propriedades chamadas bbRB3 e bbLATB4, de modo que a última declaração acima se tornaria
que por sua vez seria processado em algo como:
Um compilador deve ser capaz de perceber a expressão constante no operador?: E simplesmente incluir a parte "true". Pode ser possível reduzir o número de propriedades criadas fazendo com que as macros se expandam para algo como:
ou
mas não tenho certeza se um compilador seria capaz de alinhar o código da mesma forma.
De maneira alguma desejo sugerir que o uso de portas de E / S como se fossem variáveis é necessariamente uma boa idéia, mas como você menciona C ++, é um truque útil para saber. Minha preferência em C ou C ++, se a compatibilidade com o código que usa o estilo mencionado acima não for necessária, provavelmente seria definir algum tipo de macro para cada bit de E / S e depois definir macros para "readBit", "writeBit", "setBit" e "clearBit" com a condição de que o argumento de identificação de bits passado para essas macros deve ser o nome de uma porta de E / S destinada ao uso com essas macros. O exemplo acima, por exemplo, seria escrito como
e traduzido como
Isso seria um pouco mais trabalhoso para o pré-processador do que o estilo C ++, mas seria menos trabalhoso para o compilador. Isso também permitiria a geração ideal de código para muitas implementações de E / S e a implementação decente de código para quase todos.
fonte
Se você está procurando algo realmente impressionante para abstrair o hardware e está confiante em suas habilidades em C ++, tente este padrão:
https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Eu usei-o em uma tentativa de abstrair o hardware de um chip Cortex-M0. Ainda não escrevi nada sobre essa experiência (farei isso algum dia), mas acredite que tem sido muito útil por causa de sua natureza estática polimórfica: o mesmo método para chips diferentes, sem nenhum custo (comparado ao polimorfismo dinâmico).
fonte