Tengo un par de barras de cortina eléctricas Akko: AM82TV. Este modelo se destaca de sus hermanos con el conjunto más completo de interfaces de administración. Las cortinas se pueden controlar por radio, hay "contactos secos", control fase por fase (mediante el cortocircuito de los cables de control a la red). Hay una interfaz RS485, esto es si desea conectar las cortinas a la "casa inteligente". También puede abrir / cerrar las cortinas simplemente tirando de ellas con la mano en la dirección deseada. "Fuera de la caja" falta, quizás, solo la interfaz basada en web, bueno, y MQTT.
Durante mucho tiempo tuve barras de cortina eléctricas que funcionan de manera confiable, pero de vez en cuando comenzó a aparecer el deseo de desarmarlas, por curiosidad para ver qué hay dentro y si es posible colocar un ESP8266 (o ESP32) para agregar los que faltan. Por supuesto, puede conectar todo desde el exterior, pero es mejor si la apariencia sigue siendo la misma y todo está oculto por dentro.
No repares lo que no está roto, no se trata de mí. Al principio traté de alejarme de las malas ideas, pero con el tiempo, la picazón se intensificó y ahora, llegó el momento en que ya era imposible luchar contra ella. Quité el motor del alero y lo desmantelé. Se suponía que la inspección inicial respondería a dos preguntas: ¿hay espacio para el ESP8266 y es posible utilizar la fuente de alimentación incorporada? Todo se resolvió simplemente. Es suficiente desenroscar algunos tornillos de los extremos del motor. Lo único es que las ranuras de los tornillos no están hechas con un destornillador, sino con una llave hexagonal torx. Después de eso, puede extraer el contenido: un motor colector en una carcasa con una caja de cambios y un sensor del eje del motor, una fuente de alimentación de 24 voltios y un tablero de control.
Hay un lugar para ESP, la fuente de alimentación está diseñada para un motor potente y no notará una pequeña carga adicional. Comencé a considerar el tablero de control y los pensamientos sobre ESP comenzaron a desvanecerse en el fondo: el microcontrolador atmega168 era el corazón del tablero. Si no hubiera contactos en la placa para instalar el conector ISP (interfaz de programación en circuito del microcontrolador), esto no me detendría, pero estaban allí. Para que me entiendas correctamente, no soy fanático de avr en absoluto. No tengo un programador y no he escrito una sola línea de código para los microcontroladores atmega. Necesitaba urgentemente un programador para intentar leer el firmware, pero era por la tarde y no había forma de comprar algo en la tienda en este momento. Para no esperar hasta la mañana, reuní al programador Gromov. Luego soldaba el conector ISP en la placa de control, conectaba el programador e intentaba leer el firmware, y se contaba.
Es imposible tratar de entender algo en el firmware del microcontrolador sin comprender el diagrama del circuito. Por lo tanto, en una placa de circuito impreso, restauré el circuito. A menudo no tengo que dibujar diagramas. Para no dibujar los elementos que están en la pizarra, pero no en la biblioteca estándar, dibujé un diagrama en easyeda. Sí, resulta que no está de acuerdo con GOST (pero el microcontrolador se dibuja como en la documentación, lo cual es conveniente). Un fragmento es suficiente para comprender:

En lo sucesivo, se puede hacer clic en la mayoría de las imágenes.
Si lo desea, puede familiarizarse con el
esquema completo .
Después de eso, estaba listo para investigar el firmware. Simplemente traducir códigos de máquina a mnemónicos de ensamblador no es suficiente para el análisis. Necesita ver el estado de los registros y la memoria en cualquier punto del programa. Desafortunadamente, la depuración en el microcontrolador en sí no es posible con atmega168, pero puede cargar el firmware en el simulador. No es muy conveniente si quieres "sentir" el verdadero hierro del fleje del microcontrolador, pero vamos a superar lo que tenemos. No instalé Atmel Studio 7. Decidí que un AVR Studio 4 más compacto sería suficiente. En principio, un Studio es suficiente para el análisis, pero es posible transferir algunas de las operaciones de rutina a otro software. En marzo
, se publicó la
herramienta de ingeniería inversa
, Ghidra . Necesitaba una razón, alguna tarea práctica, para conocerlo. Esto es solo una oportunidad. Cada herramienta individualmente - AVR Studio 4 y Ghidra me dieron un poco de error. AVR Studio, con varias transiciones de subprograma anidadas, podría dejar de mostrar las direcciones de transición correctas en los comandos (la dirección se convirtió en cero). Ghidra a veces se extravió en su análisis de indexación. Pero el uso de ambas herramientas a la vez permitió identificar rápidamente la causa de estas rarezas.
Excavar sin rumbo en el firmware no es demasiado interesante. Es mejor si hay alguna tarea específica. Por fuera, curioso puede ser el análisis del protocolo de intercambio para RS485 y el protocolo de control por aire. Decidí profundizar en el protocolo de radio.
Érase una vez, ya había tomado una señal transmitida por un control remoto por radio y la analicé.
El canal de radio es unidireccional. El motor solo puede recibir una señal y no confirma la recepción de un comando. Es imposible interrogar el estado de la cornisa eléctrica en el aire. A nivel físico, solo hay un receptor de señal de radio. No hay transmisor en el motor. La señal es transmitida por el control remoto por radio a una frecuencia de 433.92 MHz. Codificado por manipulación de amplitud. El comando consiste en un bit de inicio de forma especial, dirección + canal y el comando en sí. Gráficamente, la señal completa se puede representar de la siguiente manera:

Un canal puede considerarse como parte de una dirección. Si transmite un comando en el canal cero, será ejecutado por todos los dispositivos con una dirección dada, pero con diferentes canales. Es conveniente si necesita transferir el comando inmediatamente al grupo de barras de cortina eléctricas.
Lea más sobre el protocolo de radio .
Analizando cómo el control remoto transmite comandos, ya conocía los códigos de los cuatro equipos. No demasiado, en comparación con las posibilidades de controlar la cortina eléctrica a través de RS485. Quería asegurarme de que todos los equipos estuvieran identificados y que no hubiera "huevos de Pascua" o equipos de servicio.
El enfoque de análisis es simple. El diagrama del circuito muestra qué puertos del microcontrolador están conectados a dispositivos físicos. El archivo de firmware se analiza en Ghidra. Esto es conveniente: muchas operaciones de rutina se realizan automáticamente. Después de analizar el funcionamiento de un fragmento de código o subprograma en particular, se le da un nombre significativo. Además, fragmentos de código y capturas de pantalla que traeré de Ghidra. Cuando esté aburrido, ejecute el código en el simulador. En situaciones especialmente complicadas, tienes que hacer dibujos.
Para garantizar que los nombres de los registros periféricos atmega168 se muestren correctamente durante el desmontaje, corregí el archivo avr8.pspec. En el buen sentido, sería necesario crear un archivo con un nombre diferente, pero no necesitaba este archivo en su forma original y corregí el que estaba.
El firmware comienza con los vectores de interrupción. El primero es el vector de transición al comienzo del programa. Se ve así:

La mayoría de las interrupciones no se usan. Si por alguna razón se produce tal interrupción, se ejecutará un comando de retorno de inmediato. Además de procesar las interrupciones para restablecer, también se procesan las interrupciones por desbordar el temporizador 0, la finalización de la recepción y la disposición para transmitir el siguiente byte de datos a USART. El intercambio RS485 no nos interesa ahora, pero se debe revisar el desbordamiento del temporizador.
Por supuesto, antes de que se active la interrupción del temporizador, el temporizador en sí debe estar configurado. No comencé a buscar en el código desmontado el lugar donde tiene lugar la inicialización. En el simulador, configuro un punto de interrupción en la dirección 0x1fc: esta es la dirección registrada en el controlador de interrupciones. Comencé el programa, obtuve un pico y solo miré lo que estaba escrito en los registros. lock select para timr0 se establece en clk / 8. Con el cuarzo en una placa de 8 MHz, los pulsos con una frecuencia de 1 MHz llegan al temporizador.
Inicio del manejador de interrupciones:

Gráfico de las funciones del controlador de interrupción de observación de aves El temporizador se desborda cada 107 μs. Entre otras cosas, el manejador de interrupciones procesa la señal desde la salida del receptor de señal de radio. Si la señal pasa la prueba con éxito, los datos recibidos se escriben en el búfer en 0x4af. El tamaño del búfer es de 6 bytes. Este es un byte más de lo necesario para recibir cuatro bytes de la dirección + canal y byte de comando. Quizás el sexto byte del protocolo de radio estaba destinado a la suma de comprobación, pero atrofiado. A veces sucede Quizás destinado a datos que complementen algunos de los comandos. En el protocolo de control de cornisa eléctrica RS485, hay un comando para cerrar parcialmente las cortinas. En este caso, se transmite un byte adicional con datos sobre la cantidad de cierre en porcentaje. Un equipo similar podría existir en el protocolo de radio. El programa principal se informa sobre la disponibilidad de los datos mediante el establecimiento de un indicador: una unidad se escribe en la dirección 0x4bd.
Esto completa el análisis de las interrupciones y pasa al programa principal.
El gráfico de funciones al navegar a la dirección 0x1304 es conciso y simple:

Necesitamos en el "principal". Ya hemos analizado las interrupciones y entendemos que si por alguna razón volvemos repentinamente de main y entramos en "go_to_sleep", entonces este sueño será letárgico: la cortina eléctrica dejará de hacer algo útil. Probablemente, al escribir el firmware, se usó una plantilla preparada y quedaron artefactos después.
En general, necesitamos encontrar el lugar donde se accede al búfer 0x4af. No tendrá que buscar por mucho tiempo. Literalmente, después de algunos comandos, se llama a una subrutina, que comienza con la dirección 0x11b3, donde se copia y procesa este búfer.
Gráfico de las funciones del procedimiento rf_signal_buffer_processing (0x11b3):

Este es exactamente el lugar que necesitamos, pero parece un poco complicado. Para entender, comencé a dibujar. Algo así como un diagrama de flujo.
Lo primero que sucede aquí es que los datos del búfer 0x4af se copian en la nueva dirección: 0x49f y se restablece el indicador 0x4bd:

El siguiente fragmento es el más interesante:

De hecho, esta es la verificación completa del comando recibido por el aire. Si bien esto no es obvio, un análisis posterior mostró que la transición a las siguientes ramas es el procesamiento de los siguientes comandos de radio si el comando 0xcc se recibió antes de eso, cambiando al modo de configuración. Estaba interesado en los nuevos códigos de los propios equipos. ¿Hay algo además de los códigos de comando 0x11, 0x33, 0x55 y 0xcc.
Ni aquí ni más allá pude encontrar el procesamiento del último sexto byte del comando. En la figura, está tachado en rojo. Por lo tanto, todos los equipos constan de cinco bytes. Al menos en el firmware de la AM82TV.
Lo primero que vemos es verificar el quinto byte del búfer: el código del comando en sí. Aquí, al parecer, había nuevos códigos de comando: 0xad y 0xda. El comando del búfer pasa la prueba con éxito si el campo de dirección coincide con una de las direcciones ya registradas en eeprom, o si el código del comando es 0xad, o 0xda y el campo de dirección == 0xaaaaaaaa.
Bueno, consideraremos que pasamos con éxito la próxima prueba. Ahora el código de comando se encuentra en 0x4bf. Necesitamos encontrar cómo se procesan los contenidos de este byte. Hay varias formas de hacer esto. La más simple es una búsqueda de texto en código desmontado en Ghidra. Queda por ver exactamente dónde se leen los contenidos de este byte. Esta no es una forma garantizada de encontrar todas las llamadas, pero en este caso particular funcionará. Entonces, primero, veremos una lectura de bytes en el procedimiento que comienza en 0x1262:

El acceso al mismo proviene de un solo lugar: un equipo ubicado en 0x5e0.
Gráfico de funciones:

Es una pena, pero todos los códigos de comando, excepto los ya conocidos: 0x11, 0x33, 0x55 y 0xcc se descartan en este procedimiento. Incluso los códigos 0xad y 0xda encontrados en el paso anterior. Al menos no pude encontrar nuevos códigos de comandos de radio en el firmware de la cornisa eléctrica AM82TV.
Sin embargo, hay acceso al firmware, se puede desmontar, ver cómo se implementan funciones específicas y cambiar algo usted mismo. O incluso agregar algo.
El firmware y el archivo avr8.pspec modificado para atmega168 se publican en
GitHub .