/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-05-19 armink the first version */ #include #include #include #include #include #include #include /* EasyFlash partition name on FAL partition table */ #define FAL_EF_PART_NAME "env" /* default ENV set for user */ static const ef_env default_env_set[] = { {"stay_in_bootloader","0"}, {"check_upgrade","0"}, {"bootdelay","1"}, }; static char log_buf[RT_CONSOLEBUF_SIZE]; static struct rt_semaphore env_cache_lock; static const struct fal_partition *part = NULL; /** * Flash port for hardware initialize. * * @param default_env default ENV set for user * @param default_env_size default ENV size * * @return result */ EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size) { EfErrCode result = EF_NO_ERR; *default_env = default_env_set; *default_env_size = sizeof(default_env_set) / sizeof(default_env_set[0]); rt_sem_init(&env_cache_lock, "env lock", 1, RT_IPC_FLAG_PRIO); part = fal_partition_find(FAL_EF_PART_NAME); EF_ASSERT(part); return result; } /** * Read data from flash. * @note This operation's units is word. * * @param addr flash address * @param buf buffer to store read data * @param size read bytes size * * @return result */ EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size) { EfErrCode result = EF_NO_ERR; EF_ASSERT(size % 4 == 0); fal_partition_read(part, addr, (uint8_t *)buf, size); return result; } /** * Erase data on flash. * @note This operation is irreversible. * @note This operation's units is different which on many chips. * * @param addr flash address * @param size erase bytes size * * @return result */ EfErrCode ef_port_erase(uint32_t addr, size_t size) { EfErrCode result = EF_NO_ERR; /* make sure the start address is a multiple of FLASH_ERASE_MIN_SIZE */ EF_ASSERT(addr % EF_ERASE_MIN_SIZE == 0); if (fal_partition_erase(part, addr, size) < 0) { result = EF_ERASE_ERR; } return result; } /** * Write data to flash. * @note This operation's units is word. * @note This operation must after erase. @see flash_erase. * * @param addr flash address * @param buf the write data buffer * @param size write bytes size * * @return result */ EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size) { EfErrCode result = EF_NO_ERR; EF_ASSERT(size % 4 == 0); if (fal_partition_write(part, addr, (uint8_t *)buf, size) < 0) { result = EF_WRITE_ERR; } return result; } /** * lock the ENV ram cache */ void ef_port_env_lock(void) { rt_sem_take(&env_cache_lock, RT_WAITING_FOREVER); } /** * unlock the ENV ram cache */ void ef_port_env_unlock(void) { rt_sem_release(&env_cache_lock); } /** * This function is print flash debug info. * * @param file the file which has call this function * @param line the line number which has call this function * @param format output format * @param ... args * */ void ef_log_debug(const char *file, const long line, const char *format, ...) { #ifdef PRINT_DEBUG va_list args; /* args point to the first variable parameter */ va_start(args, format); ef_print("[Flash] (%s:%ld) ", file, line); /* must use vprintf to print */ rt_vsprintf(log_buf, format, args); ef_print("%s", log_buf); va_end(args); #endif } /** * This function is print flash routine info. * * @param format output format * @param ... args */ void ef_log_info(const char *format, ...) { va_list args; /* args point to the first variable parameter */ va_start(args, format); ef_print("[Flash] "); /* must use vprintf to print */ rt_vsprintf(log_buf, format, args); ef_print("%s", log_buf); va_end(args); } /** * This function is print flash non-package info. * * @param format output format * @param ... args */ void ef_print(const char *format, ...) { va_list args; /* args point to the first variable parameter */ va_start(args, format); /* must use vprintf to print */ rt_vsprintf(log_buf, format, args); rt_kprintf("%s", log_buf); va_end(args); }