Пример #1
0
/**
 * clean all log which in flash and ram buffer
 */
void elog_flash_clean(void) {
    EfErrCode clean_result = EF_NO_ERR;

    /* must be call this function after initialize OK */
    ELOG_ASSERT(init_ok);
    /* lock flash log buffer */
    log_buf_lock();
    /* clean all log which in flash */
    clean_result = ef_log_clean();

#ifdef ELOG_FLASH_USING_BUF_MODE
    /* reset position */
    cur_buf_size = 0;
#endif

    /* unlock flash log buffer */
    log_buf_unlock();

    if(clean_result == EF_NO_ERR) {
        log_i("All logs which in flash is clean OK.");
    } else {
        log_e("Clean logs which in flash has an error!");
    }
}
Пример #2
0
/**
 * Find the log store start address and end address.
 * It's like a ring buffer which implement by flash.
 * The flash log area has two state when find start address and end address.
 *                       state 1                                state 2
 *                   |============|                         |============|
 * log area start--> |############| <-- start address       |############| <-- end address
 *                   |############|                         |   empty    |
 *                   |------------|                         |------------|
 *                   |############|                         |############| <-- start address
 *                   |############|                         |############|
 *                   |------------|                         |------------|
 *                   |     .      |                         |     .      |
 *                   |     .      |                         |     .      |
 *                   |     .      |                         |     .      |
 *                   |------------|                         |------------|
 *                   |############| <-- end address         |############|
 *                   |   empty    |                         |############|
 *  log area end --> |============|                         |============|
 *
 *  LOG_AREA_SIZE = log area end - log area star
 *
 */
static void find_start_and_end_addr(void) {
    size_t cur_size = 0;
    EfSecrorStatus cur_sec_status, last_sec_status;
    uint32_t cur_using_sec_addr = 0;
    /* all status sector counts */
    size_t empty_sec_counts = 0, using_sec_counts = 0, full_sector_counts = 0;
    /* total sector number */
    size_t total_sec_num = LOG_AREA_SIZE / EF_ERASE_MIN_SIZE;
    /* see comment of find_start_and_end_addr function */
    uint8_t cur_log_sec_state = 0;

    /* get the first sector status */
    cur_sec_status = ef_get_sector_status(log_area_start_addr, EF_ERASE_MIN_SIZE);
    last_sec_status = cur_sec_status;

    for (cur_size = EF_ERASE_MIN_SIZE; cur_size < LOG_AREA_SIZE; cur_size += EF_ERASE_MIN_SIZE) {
        /* get current sector status */
        cur_sec_status = ef_get_sector_status(log_area_start_addr + cur_size, EF_ERASE_MIN_SIZE);
        /* compare last and current status */
        switch (last_sec_status) {
        case EF_SECTOR_EMPTY: {
            switch (cur_sec_status) {
            case EF_SECTOR_EMPTY:
                break;
            case EF_SECTOR_USING:
                EF_DEBUG("Error: Log area error! Now will clean all log area.\n");
                ef_log_clean();
                return;
            case EF_SECTOR_FULL:
                EF_DEBUG("Error: Log area error! Now will clean all log area.\n");
                ef_log_clean();
                return;
            }
            empty_sec_counts++;
            break;
        }
        case EF_SECTOR_USING: {
            switch (cur_sec_status) {
            case EF_SECTOR_EMPTY:
                /* like state 1 */
                cur_log_sec_state = 1;
                log_start_addr = log_area_start_addr;
                cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE;
                break;
            case EF_SECTOR_USING:
                EF_DEBUG("Error: Log area error! Now will clean all log area.\n");
                ef_log_clean();
                return;
            case EF_SECTOR_FULL:
                /* like state 2 */
                cur_log_sec_state = 2;
                log_start_addr = log_area_start_addr + cur_size;
                cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE;
                break;
            }
            using_sec_counts++;
            break;
        }
        case EF_SECTOR_FULL: {
            switch (cur_sec_status) {
            case EF_SECTOR_EMPTY:
                /* like state 1 */
                if (cur_log_sec_state == 2) {
                    EF_DEBUG("Error: Log area error! Now will clean all log area.\n");
                    ef_log_clean();
                    return;
                } else {
                    cur_log_sec_state = 1;
                    log_start_addr = log_area_start_addr;
                    /* word alignment */
                    log_end_addr = log_area_start_addr + cur_size - 4;
                    cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE;
                }
                break;
            case EF_SECTOR_USING:
                if(total_sec_num <= 2) {
                    /* like state 1 */
                    cur_log_sec_state = 1;
                    log_start_addr = log_area_start_addr;
                    cur_using_sec_addr = log_area_start_addr + cur_size;
                } else {
                    /* like state 2 when the sector is the last one */
                    if (cur_size + EF_ERASE_MIN_SIZE >= LOG_AREA_SIZE) {
                        cur_log_sec_state = 2;
                        log_start_addr = log_area_start_addr + cur_size;
                        cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE;
                    }
                }
                break;
            case EF_SECTOR_FULL:
                break;
            }
            full_sector_counts++;
            break;
        }
        }
        last_sec_status = cur_sec_status;
    }

    /* the last sector status counts */
    if (cur_sec_status == EF_SECTOR_EMPTY) {
        empty_sec_counts++;
    } else if (cur_sec_status == EF_SECTOR_USING) {
        using_sec_counts++;
    } else if (cur_sec_status == EF_SECTOR_FULL) {
        full_sector_counts++;
    }

    if (using_sec_counts > 1) {
        EF_DEBUG("Error: Log area error! Now will clean all log area.\n");
        ef_log_clean();
        return;
    } else if (empty_sec_counts == total_sec_num) {
        log_start_addr = log_end_addr = log_area_start_addr;
    } else if (full_sector_counts == total_sec_num) {
        /* this state is almost impossible */
        EF_DEBUG("Error: Log area error! Now will clean all log area.\n");
        ef_log_clean();
        return;
    } else if (((cur_log_sec_state == 1) && (cur_using_sec_addr != 0))
            || (cur_log_sec_state == 2)) {
        /* find the end address */
        log_end_addr = ef_find_sec_using_end_addr(cur_using_sec_addr, EF_ERASE_MIN_SIZE);
    }
}