Сделана независимость .h библиотек от таргета и HAL (насколько возможно)
This commit is contained in:
@@ -13,8 +13,14 @@
|
||||
- Мутацию для поиска оптимальных параметров
|
||||
- Несколько независимых оптимизаторов в одной программе
|
||||
|
||||
Если библиотека отключена @ref ENABLE_EVOLVE_OPTIMIZATION, то вставляются
|
||||
заглушки, никак не влияющие на параметры и остальную программу
|
||||
|
||||
Параметры для конфигурации:
|
||||
- @ref ENABLE_EVOLVE_OPTIMIZATION - Включить оптимизацию параметров
|
||||
Если библиотека отключена @ref ENABLE_EVOLVE_OPTIMIZATION, то вставляются
|
||||
заглушки, никак не влияющие на параметры и остальную программу
|
||||
- @ref EVOLVE_MAX_PARAMS - Максимальное количество параметров
|
||||
- @ref EVOLVE_MAX_CANDIDATES - Максимальное количество кандидатов для обучения
|
||||
|
||||
|
||||
@par Пример использования:
|
||||
@code
|
||||
@@ -71,6 +77,9 @@ param_i16 = PARAM_UNSCALE_Q16(params[3], 500, 5000);
|
||||
#define PARAM_UNSCALE_Q16(q16_val, min_val, max_val) \
|
||||
(((float)(q16_val) / 65536.0f) * ((float)(max_val) - (float)(min_val)) + (float)(min_val))
|
||||
|
||||
#ifndef local_time
|
||||
#define local_time() HAL_GetTick() ///< Локальное время
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Структура эволюционного оптимизатора
|
||||
@@ -117,31 +126,33 @@ static int cmp_idx(const void *a, const void *b) {
|
||||
* @param n_best Количество лучших, усредняемых
|
||||
* @param iq_mutation Амплитуда мутации в Q16.16
|
||||
* @param start_params Начальные параметры (Q16.16)
|
||||
* @return 0 — если окей,
|
||||
* -1 — если ошибка
|
||||
*/
|
||||
__STATIC_INLINE HAL_StatusTypeDef EvolveOptimizer_Init(EvolveOptimizer_t* opt,
|
||||
__STATIC_INLINE int EvolveOptimizer_Init(EvolveOptimizer_t* opt,
|
||||
uint16_t n_params,
|
||||
uint16_t n_cand,
|
||||
uint16_t n_best,
|
||||
uint16_t iq_mutation,
|
||||
int32_t* start_params)
|
||||
{
|
||||
if(check_null_ptr_2(opt, start_params))
|
||||
return HAL_ERROR;
|
||||
if((opt = NULL) || (start_params == NULL))
|
||||
return -1;
|
||||
|
||||
if(n_params > EVOLVE_MAX_PARAMS)
|
||||
return HAL_ERROR;
|
||||
return -1;
|
||||
opt->n_params = n_params;
|
||||
|
||||
if(n_cand > EVOLVE_MAX_CANDIDATES)
|
||||
return HAL_ERROR;
|
||||
return -1;
|
||||
opt->n_cand = n_cand;
|
||||
|
||||
if(n_best > EVOLVE_MAX_CANDIDATES/2)
|
||||
return HAL_ERROR;
|
||||
return -1;
|
||||
opt->n_best = n_best;
|
||||
|
||||
if(iq_mutation > 32768)
|
||||
return HAL_ERROR;
|
||||
return -1;
|
||||
opt->iq_mutation = iq_mutation;
|
||||
|
||||
for (uint16_t i = 0; i < n_cand; i++) {
|
||||
@@ -150,10 +161,10 @@ __STATIC_INLINE HAL_StatusTypeDef EvolveOptimizer_Init(EvolveOptimizer_t* opt,
|
||||
}
|
||||
opt->loss[i] = 0;
|
||||
}
|
||||
uint32_t seed = HAL_GetTick() + (ADC1->DR & 0xFF);
|
||||
uint32_t seed = local_time() + (ADC1->DR & 0xFF);
|
||||
srand(seed);
|
||||
|
||||
return HAL_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +173,8 @@ __STATIC_INLINE HAL_StatusTypeDef EvolveOptimizer_Init(EvolveOptimizer_t* opt,
|
||||
* @param opt Указатель на структуру оптимизатора
|
||||
* @param params Массив параметров, которые будут обновлены (на выходе — новые параметры)
|
||||
* @param loss Loss текущего кандидата (Q16.16)
|
||||
* @return 0 — если окей,
|
||||
* -1 — если ошибка
|
||||
* @details
|
||||
* Сохраняет loss текущего кандидата и формирует параметры следующего кандидата.
|
||||
* Если накоплено n_cand кандидатов, генерируется новое поколение.
|
||||
@@ -171,28 +184,28 @@ __STATIC_INLINE HAL_StatusTypeDef EvolveOptimizer_Init(EvolveOptimizer_t* opt,
|
||||
* @note Функция использует глобальную внутреннюю переменную для сортировки.
|
||||
* Надо убедится что только один экземпляр функции запущен в момент времени
|
||||
*/
|
||||
__STATIC_INLINE HAL_StatusTypeDef EvolveOptimizer_Step(EvolveOptimizer_t* opt,
|
||||
__STATIC_INLINE int EvolveOptimizer_Step(EvolveOptimizer_t* opt,
|
||||
int32_t* params,
|
||||
int32_t loss)
|
||||
{
|
||||
if(check_null_ptr_2(opt, params))
|
||||
return HAL_ERROR;
|
||||
if((opt = NULL) || (params == NULL))
|
||||
return -1;
|
||||
|
||||
uint16_t n_params = opt->n_params;
|
||||
if(n_params > EVOLVE_MAX_PARAMS)
|
||||
return HAL_ERROR;
|
||||
return -1;
|
||||
|
||||
uint16_t n_cand = opt->n_cand;
|
||||
if(n_cand > EVOLVE_MAX_CANDIDATES)
|
||||
return HAL_ERROR;
|
||||
return -1;
|
||||
|
||||
uint16_t n_best = opt->n_best;
|
||||
if(n_best > EVOLVE_MAX_CANDIDATES/2)
|
||||
return HAL_ERROR;
|
||||
return -1;
|
||||
|
||||
uint16_t mut = opt->iq_mutation;
|
||||
if(mut > 32768)
|
||||
return HAL_ERROR;
|
||||
return -1;
|
||||
|
||||
// 1. Сохраняем loss текущего кандидата
|
||||
opt->loss[opt->cand_index] = loss;
|
||||
@@ -248,7 +261,7 @@ __STATIC_INLINE HAL_StatusTypeDef EvolveOptimizer_Step(EvolveOptimizer_t* opt,
|
||||
for (uint16_t i = 0; i < opt->n_params; i++)
|
||||
params[i] = opt->candidates[opt->cand_index][i];
|
||||
|
||||
return HAL_OK;
|
||||
return 0;
|
||||
}
|
||||
#else // ENABLE_EVOLVE_OPTIMIZATION
|
||||
//заглушки
|
||||
|
||||
@@ -16,9 +16,14 @@
|
||||
* @addtogroup TRACE_SERIAL Serial trace defines
|
||||
* @ingroup TRACE
|
||||
* @brief Дефайны для работы с serial трассировкой (SWO, RTT)
|
||||
* @details Определяется дефайн @ref my_printf() и @ref log_printf() для работы с serial трассировкой:
|
||||
- для RTT это будет вызов функции SEGGER_RTT_printf(), с подключением библиотеки SEGGER_RTT.h
|
||||
- для SWO это будет просто printf()
|
||||
* @details В зависимости от настроек определяется дефайн @ref my_printf() и @ref log_printf() для работы с трассировкой:
|
||||
- @ref SERIAL_TRACE_ENABLE - Если трассировка отключена, то все дефайны определяются как 'ничего'
|
||||
и на производительность кода не влияют
|
||||
|
||||
- @ref RTT_TRACE_ENABLE - для RTT это будет вызов функции SEGGER_RTT_printf(), с подключением библиотеки SEGGER_RTT.h
|
||||
Предварительно надо подключить библиотеку SEGGER RTT и вызвать функцию SEGGER_RTT_Init()
|
||||
|
||||
- @ref SWO_TRACE_ENABLE для SWO это будет просто printf()
|
||||
|
||||
Но библиотеку STDOUT надо подключить самостоятельно:
|
||||
|
||||
@@ -39,8 +44,7 @@
|
||||
- Выставить Trace Port = SWO
|
||||
- ITM - выбрать нужный порт (для Keil нулевой порт)
|
||||
|
||||
- Если трассировка @ref SERIAL_TRACE_ENABLE отключена, то все дефайны определяются как 'ничего'
|
||||
и на производительность кода не влияют
|
||||
|
||||
* @{
|
||||
*
|
||||
* @def my_printf(...)
|
||||
@@ -159,6 +163,13 @@ my_printf("\n[%lu] [%s] (%s:%d) " fmt, \
|
||||
* если слот с таким тегом уже занят, запись не выполняется.
|
||||
* - Автоинкремент позволяет хранить несколько последовательных записей в пределах одного базового тега,
|
||||
* без необходимости вручную отслеживать адреса Flash или позиции буферов.
|
||||
*
|
||||
* Параметры:
|
||||
* - @ref RTT_FLASH_BUFFER_SIZE - Размер буфера RTT в Flash
|
||||
* - @ref RTT_FLASH_SECTOR - Сектор FLASH куда положится RTT буфер
|
||||
* - @ref RTT_FLASH_SECTOR_START - Начало сектора RTT_FLASH_SECTOR
|
||||
* - @ref RTT_FLASH_SECTOR_END - Конец сектора RTT_FLASH_SECTOR
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
@@ -198,6 +209,7 @@ __STATIC_FORCEINLINE void RTT_FlashPrepare(void)
|
||||
* - Если базовый (младший байт == 0) — будет выбран первый свободный слот с автоинкрементом.
|
||||
* Автоинкремент формируется в пределах от 0x1 до 0xFF
|
||||
* - Если конкретный (младший байт != 0) — запись выполняется только с этим тегом, иначе ошибка.
|
||||
*
|
||||
*/
|
||||
__STATIC_FORCEINLINE int RTT_SaveToFlash(uint32_t tag, uint32_t tail_size)
|
||||
{
|
||||
@@ -410,6 +422,16 @@ __STATIC_FORCEINLINE int RTT_EraseFlash(void)
|
||||
* 1. Читает запись во Flash по базовому тегу.
|
||||
* 2. Выводит сохранённый RTT буфер и контекст регистров.
|
||||
* 3. Опционально стирает Flash после восстановления.
|
||||
*
|
||||
* Параметры:
|
||||
* - @ref HARDFAULT_SERIAL_TRACE - Включить обработку и serial трассировку Hardfault
|
||||
* Если отключена то вставляются заглушки, никак не влияющие на параметры и остальную программу
|
||||
* - @ref HF_RTT_TAG_BASE - Базовый тег RTT Flash для HardFault
|
||||
* - @ref HF_RTT_TAIL_SIZE - Размер буфера RTT, который сохранится при Hardfault
|
||||
* - @ref HF_STACK_DUMP_WORDS - Сколько слов стека будет проанализировано во время Hardfault
|
||||
* - @ref HF_FLASH_ADDR - Адрес FLASH куда положится RTT буфер
|
||||
* - @ref HF_RAM_END - Конец RAM памяти (чтобы во время анализа стека не выйти за пределы)
|
||||
*
|
||||
@code
|
||||
void Hardfault()
|
||||
{
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
- user[num_user_vars]
|
||||
Также есть ряд функций (дефайнов) для обращения к элементам этой структуры.
|
||||
|
||||
|
||||
Если трекеры @ref TRACKERS_ENABLE отключены, то все дефайны определяются как ничего
|
||||
и на производительность кода не влияют
|
||||
Параметры для конфигурации:
|
||||
- @ref TRACKERS_ENABLE - Включить трекеры
|
||||
Если трекеры @ref TRACKERS_ENABLE отключены, то все дефайны определяются как ничего
|
||||
и на производительность кода не влияют
|
||||
|
||||
@par Пример:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user