Parece que tiene un bloque de registros que se deben leer o escribir de forma atómica (es decir, leerlos o escribirlos todos o leerlos / escribirlos ninguno). Tradicionalmente, cómo lidiar con esto es tener un conjunto de registros sombra; el ISR llena o usa una tabla, y las subrutinas UART usan otra. Las rutinas que actualizan las estructuras de datos bloquean el conjunto de trabajo para que otras rutinas no obtengan una actualización parcial. Las rutinas que deben acceder a las tablas comprueban el bloqueo y "saltan su turno" o esperan a que se libere el bloqueo.
Usted hace estas "secciones críticas" (secciones donde no se permite acceder a la tabla) lo más rápido posible, por lo que recomendé un "conjunto de sombras" para las rutinas de UART ya que probablemente sean las cosas más lentas para acceder a las tablas y, de hecho, pueden ser las únicas rutinas que deben acceder a todo el conjunto como una sola unidad. No bloquee la tabla hasta que esté absolutamente seguro de que necesita hacerlo, y luego la bloquea solo durante el tiempo necesario para copiar los datos.
Algo como esto:
if (command_is_good && cmd_is_request) {
lock_working_table();
memcpy(serial_copy, working_copy, sizeof(*working_copy);
unlock_working_table();
prepare_response(serial_copy);
}
if (command_is_good && cmd_is_update) {
if (verify_table(serial_copy)) {
lock_working_table();
memcpy(working_copy, serial_copy, sizeof(*working_copy));
unlock_working_table();
prepare_response();
}
}
Puede obtener resultados similares al deshabilitar la interrupción de ADC, pero a lo largo de los años he encontrado que, en general, hay muy, muy pocas veces las que desea atornillar con la función de interrupción, y esto casi nunca es una de ellas. El bloqueo y un mejor diseño son casi siempre la forma correcta de manejar esto, por lo que agregué el comentario a la publicación de @kvegaoro. Se confunde con su tiempo, que puede o no ser importante, y si deshabilita el ISR de UART podría desbordar su FIFO.
Si encuentra que tiene un gran conjunto de registros que deben actualizarse de forma atómica, es posible que también desee dividirlos en grupos atómicos más pequeños y limitar su tamaño o límites de solicitud.
Editar para abordar el comentario de @ DaveTweed:
En cuanto a una convención utilizada por los dispositivos ModBus ... Lo mejor de ModBus es también lo peor de ModBus; Eres libre de hacer las cosas como quieras. La especificación es muy "floja" a ese respecto. No hay ninguna convención que yo sepa, pero los dispositivos ModBus que tienen tal requisito sobre bloques de registros tendrían que implementar cosas similares a como describí la solución anterior. Casi todos los dispositivos triviales lo limitan a un solo registro para operaciones de lectura / escritura, evitando cuidadosamente el problema. :-)