TESTABLE_STATIC int flush_logfile(struct logging_status *ls)
{
        if (ls->writing_status != WRITING_ACTIVE)
                return -1;

        if (!isTimeoutMs(ls->flush_tick, FLUSH_INTERVAL_MS))
                return -2;

        pr_debug("Logging: flush\r\n");
        const int res = f_sync(g_logfile);
        if (0 != res)
                pr_debug_int_msg("Logging: flush err ", res);

        ls->flush_tick = xTaskGetTickCount();
        return res;
}
int OBD2_request_PID(unsigned char pid, int *value, size_t timeout)
{
    CAN_msg msg;
    msg.addressValue = 0x7df;
    msg.data[0] = 2;
    msg.data[1] = 1;
    msg.data[2] = pid;
    msg.data[3] = 0x55;
    msg.data[4] = 0x55;
    msg.data[5] = 0x55;
    msg.data[6] = 0x55;
    msg.data[7] = 0x55;
    msg.dataLength = 8;
    msg.isExtendedAddress = 0;

    int pid_request_success = 0;

    if (CAN_tx_msg(0, &msg, timeout)) {
        size_t start_time = xTaskGetTickCount();
        while (!isTimeoutMs(start_time, OBD2_PID_DEFAULT_TIMEOUT_MS)) {
            int result = CAN_rx_msg(0, &msg, OBD2_PID_DEFAULT_TIMEOUT_MS);
            if (result) {
                result = decode_pid(pid, &msg, value);
                if (result) {
                    pid_request_success = 1;
                    if (DEBUG_LEVEL) {
                        pr_debug("read OBD2 PID ");
                        pr_debug_int(pid);
                        pr_debug("=")
                        pr_debug_int(*value);
                        pr_debug("\r\n");
                    }
                    break;
                }
            }
        }
    }
    return pid_request_success;
}