#include #include struct measurement_payload_t { /* Absolute humidity percentage. */ uint8_t abs_humidity; /* Temperature in Kelvin * 10. */ uint16_t temperature; /* Barometric pressure in hPa. */ uint32_t bar_pressure; /* Timestamp. */ uint32_t timestamp; }; struct env_measurement_t { struct measurement_payload_t payload; /* Fletcher-16 checksum over payload. */ uint16_t checksum; }; /* Computes a Fletcher-16 checksum over 'message' with given 'length'. */ extern uint16_t fletcher16(const void* message, uint16_t length); /* Deep-copies 'message' and puts it into message queue. */ extern void send_measurement(const struct env_measurement_t* message); /* Gets a message from the message queue and copies it into 'message'. */ extern void receive_measurement(struct env_measurement_t* message); /* Returns the current absolute humidity sensor reading. */ extern uint8_t get_abs_humidity(void); /* Returns the current temperature sensor reading. */ extern uint16_t get_temperature(void); /* Returns the current Barometric pressure sensor reading. */ extern uint32_t get_bar_pressure(void); /* Returns the current system time in ticks. */ extern uint32_t get_sys_ticks(void); const uint8_t MAX_FAILURE_COUNT = 3; const struct measurement_payload_t INVALID_MEASUREMENT = { 0xFF, /* abs_humidity invalid value. */ 0xFFFE, /* temperature invalid value. */ 0xFFFFFFFE, /* bar_pressure invalid value. */ 0x00000000 /* timestamp invalid value. */ }; uint8_t g_failure_count = 0; void produce_env_measurement() { struct env_measurement_t measurement; measurement.payload.abs_humidity = get_abs_humidity(); measurement.payload.temperature = get_temperature(); measurement.payload.bar_pressure = get_bar_pressure(); measurement.payload.timestamp = get_sys_ticks(); /* Calculate checksum over data. */ measurement.checksum = fletcher16(&measurement.payload, sizeof(measurement.payload)); /* Transmit message. */ send_measurement(&measurement); } void process_env_measurement() { struct env_measurement_t measurement; /* Get measurement data. */ receive_measurement(&measurement); /* If checksum doesn't match. */ if (fletcher16(&measurement.payload, sizeof(measurement.payload)) != measurement.checksum) { ++g_failure_count; /* If too many checksum errors. */ if (g_failure_count > MAX_FAILURE_COUNT) { /* ... measurement failure handling ... */ } /* Checksum correct. */ } else { /* If there is not even a single valid measurement. */ if (memcmp(&measurement.payload, &INVALID_MEASUREMENT, sizeof(measurement.payload)) == 0) { /* Ignore this measurement. */ } else { /* ... process measurement data ... */ } } }