Estoy buscando abstracciones en C ++ para puntos o pines de E / S de hardware. Cosas como in_pin, out_pin, inout_pin, quizás open_collector_pin, etc.
Seguramente puedo encontrarme con un conjunto de abstracciones, así que no estoy buscando el tipo de respuestas 'hey, podrías hacerlo de esta manera', sino más bien 'mira esta biblioteca que se ha utilizado en esto y esto y este proyecto'.
Google no apareció nada, tal vez porque no sé cómo otros llamarían esto.
Mi objetivo es construir bibliotecas de E / S que se basen en dichos puntos, pero también proporcionen dichos puntos, por lo que sería fácil, por ejemplo, conectar un HD44780 LCd a los pines IO del chip o a un I2C (o SPI) Extensor de E / S, o cualquier otro punto que de alguna manera se pueda controlar, sin ningún cambio en la clase de LCD.
Sé que esto está en el borde de la electrónica / software, lo siento si no pertenece aquí.
@leon: cableado Esa es una gran bolsa de software, tendré que mirar más de cerca. Pero parece que no usan una abstracción pin como yo quiero. Por ejemplo, en la implementación del teclado veo
digitalWrite(columnPins[c], LOW); // Activate the current column.
Esto implica que hay una función (digitalWrite) que sabe cómo escribir en un pin de E / S. Esto hace que sea imposible agregar un nuevo tipo de pin de E / S (por ejemplo, uno que esté en un MCP23017, por lo que debe escribirse a través de I2C) sin reescribir la función digitalWrite.
@Oli: busqué en Google un ejemplo de Arduino IO, pero parece que usan el mismo enfoque que la biblioteca Wiring:
int ledPin = 13; // LED connected to digital pin 13
void setup(){
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}
fuente
Respuestas:
Respuesta corta: lamentablemente, no hay una biblioteca para hacer lo que quieres. Lo he hecho muchas veces, pero siempre en proyectos que no son de código abierto. Estoy considerando poner algo en Github, pero no estoy seguro de cuándo puedo.
¿Por qué C ++?
fuente
Permítanme conectar descaradamente mi proyecto de código abierto https://Kvasir.io . La porción Kvasir :: Io proporciona funciones de manipulación de pin. Primero debe definir su pin usando un Kvasir :: Io :: PinLocation de esta manera:
Tenga en cuenta que esto en realidad no usa RAM porque estas son variables constexpr.
A lo largo de su código, puede usar estas ubicaciones de pin en funciones de 'fábrica de acciones' como makeOpenDrain, set, clear, makeOutput, etc. Una 'fábrica de acciones' en realidad no ejecuta la acción, sino que devuelve un Kvasir :: Register :: Action que se puede ejecutar usando Kvasir :: Register :: apply (). La razón de esto es que apply () fusiona las acciones que se le pasan cuando actúan en un mismo registro para que haya una ganancia de eficiencia.
Dado que la creación y fusión de acciones se realiza en tiempo de compilación, esto debería generar el mismo código de ensamblador que el equivalente codificado a mano típico:
fuente
El proyecto Wiring usa abstracción así:
http://wiring.org.co/
y el compilador está escrito en C ++. Debería encontrar muchos ejemplos en el código fuente. El software Arduino se basa en el cableado.
fuente
En C ++, es posible escribir una clase para que pueda usar los puertos de E / S como si fueran variables, p. Ej.
sin tener en cuenta la implementación subyacente. Por ejemplo, si uno usa una plataforma de hardware que no admite operaciones de nivel de bit pero admite operaciones de registro de nivel de byte, uno podría (probablemente con la ayuda de algunas macros) definir una clase estática IO_PORTS con una lectura-escritura en línea propiedades llamadas bbRB3 y bbLATB4, de modo que la última declaración anterior se convertiría en
que a su vez se procesaría en algo como:
Un compilador debe poder notar la expresión constante en el operador?: Y simplemente incluir la parte "verdadera". Es posible reducir la cantidad de propiedades creadas haciendo que las macros se expandan a algo como:
o
pero no estoy seguro de que un compilador pueda alinear el código tan bien.
De ninguna manera deseo implicar que usar puertos de E / S como si fueran variables es necesariamente una buena idea, pero como mencionas C ++ es un truco útil para saber. Mi preferencia en C o C ++, si no fuera necesaria la compatibilidad con el código que usa el estilo mencionado anteriormente, probablemente sería definir algún tipo de macro para cada bit de E / S, y luego definir macros para "readBit", "writeBit", "setBit" y "clearBit" con la condición de que el argumento de identificación de bits pasado a esas macros debe ser el nombre de un puerto de E / S destinado a usarse con tales macros. El ejemplo anterior, por ejemplo, se escribiría como
y traducido como
Eso sería un poco más de trabajo para el preprocesador que el estilo C ++, pero sería menos trabajo para el compilador. También permitiría la generación óptima de código para muchas implementaciones de E / S y una implementación de código decente para casi todos.
fuente
Si está buscando algo realmente increíble para abstraer el hardware, y está seguro de sus habilidades en C ++, entonces debería probar este patrón:
https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Lo he usado en un intento de abstraer hardware para un chip Cortex-M0. Todavía no he escrito nada sobre esta experiencia (lo haré algún día), pero créanme que ha sido muy útil debido a su naturaleza polimórfica estática: el mismo método para diferentes chips, sin costo (en comparación con el polimorfismo dinámico).
fuente