Use singly linked list to store profile commands.

This commit is contained in:
Mario Hüttel 2021-05-15 21:58:00 +02:00
parent 174bf4220e
commit 6322c3728b
4 changed files with 77 additions and 12 deletions

View File

@ -23,6 +23,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <fatfs/ff.h> #include <fatfs/ff.h>
#include <linklist-lib/singly-linked-list.h>
struct pl_command_list_map { struct pl_command_list_map {
enum pl_command_type command; enum pl_command_type command;
@ -155,9 +156,20 @@ static int parse_line(char *line, struct pl_command *cmd)
return 0; return 0;
} }
static SlList *copy_and_append_command_to_list(SlList *list, const struct pl_command *cmd)
{
struct pl_command *alloced_cmd;
alloced_cmd = (struct pl_command *)malloc(sizeof(struct pl_command));
memcpy(alloced_cmd, cmd, sizeof(struct pl_command));
list = sl_list_append(list, alloced_cmd);
return list;
}
enum pl_ret_val temp_profile_parse_from_file(const char *filename, enum pl_ret_val temp_profile_parse_from_file(const char *filename,
struct pl_command *cmd_list, SlList **command_list,
uint32_t cmd_list_length, uint32_t max_len,
uint32_t *cmds_parsed) uint32_t *cmds_parsed)
{ {
FIL script_file; FIL script_file;
@ -165,9 +177,10 @@ enum pl_ret_val temp_profile_parse_from_file(const char *filename,
int res; int res;
enum pl_ret_val ret = PL_RET_SUCCESS; enum pl_ret_val ret = PL_RET_SUCCESS;
char workbuff[256]; char workbuff[256];
struct pl_command temp_command;
uint32_t cmd_idx; uint32_t cmd_idx;
if (!filename || !cmd_list || !cmd_list_length || !cmds_parsed) if (!filename || !command_list || !max_len || !cmds_parsed)
return PL_RET_PARAM_ERR; return PL_RET_PARAM_ERR;
@ -189,19 +202,22 @@ enum pl_ret_val temp_profile_parse_from_file(const char *filename,
} }
/* Check if list already full */ /* Check if list already full */
if (cmd_idx >= cmd_list_length) { if (cmd_idx >= max_len) {
ret = PL_RET_LIST_FULL; ret = PL_RET_LIST_FULL;
goto exit_close; goto exit_close;
} }
/* Parse the line */ /* Parse the line */
res = parse_line(workbuff, &cmd_list[cmd_idx]); res = parse_line(workbuff, &temp_command);
if (res < 0) { if (res < 0) {
ret = PL_RET_SCRIPT_ERR; ret = PL_RET_SCRIPT_ERR;
goto exit_close; goto exit_close;
} else if (res == 0) { } else if (res == 0) {
cmd_idx++; cmd_idx++;
*cmds_parsed= cmd_idx; *cmds_parsed = cmd_idx;
/* Append the temp_command to the list */
*command_list = copy_and_append_command_to_list(*command_list, &temp_command);
} }
@ -212,3 +228,15 @@ exit_close:
exit: exit:
return ret; return ret;
} }
static void delete_pl_command(void *cmd)
{
if (cmd)
free(cmd);
}
void temp_profile_free_command_list(SlList **list)
{
sl_list_free_full(*list, delete_pl_command);
*list = NULL;
}

View File

@ -22,6 +22,7 @@
#define __CONFIG_PARSER_TEMP_PROFILE_PARSER_H__ #define __CONFIG_PARSER_TEMP_PROFILE_PARSER_H__
#include <stdint.h> #include <stdint.h>
#include <linklist-lib/singly-linked-list.h>
enum pl_command_type { enum pl_command_type {
PL_PID_CONF = 0, PL_PID_CONF = 0,
@ -49,9 +50,33 @@ struct pl_command {
float params[PROFILE_LANG_MAX_NUM_ARGS]; float params[PROFILE_LANG_MAX_NUM_ARGS];
}; };
/**
* @brief Parse a temperature profile from file and generate the command list
*
* Commands are parsed into the list given by \p command_list. If \p max_len is reached,
* the function returns with @ref PL_RET_LIST_FULL
*
* In any case, the command list not cleared afterwards. The user has to clear the command list manually
* using @ref temp_profile_free_command_list.
*
* @param filename File to parse
* @param[in, out] command_list Command list to output @ref pl_command elements in.
* @param max_len maximum number of commands.
* @param cmds_parsed Number of parsed commands
* @return
*/
enum pl_ret_val temp_profile_parse_from_file(const char *filename, enum pl_ret_val temp_profile_parse_from_file(const char *filename,
struct pl_command *cmd_list, SlList **command_list,
uint32_t cmd_list_length, uint32_t max_len,
uint32_t *cmds_parsed); uint32_t *cmds_parsed);
/**
* @brief Fully free a comamnd list including hte sotred command structures.
*
* \p list's destination is set to NULL to indicate the empty list.
*
* @param[in, out] list Pointer to list.
*/
void temp_profile_free_command_list(SlList **list);
#endif /* __CONFIG_PARSER_TEMP_PROFILE_PARSER_H__ */ #endif /* __CONFIG_PARSER_TEMP_PROFILE_PARSER_H__ */

View File

@ -24,7 +24,7 @@
#include <stdint.h> #include <stdint.h>
#include <reflow-controller/config-parser/temp-profile-parser.h> #include <reflow-controller/config-parser/temp-profile-parser.h>
#define MAX_PROFILE_LENGTH 50 #define MAX_PROFILE_LENGTH 64
enum tpe_status { enum tpe_status {
TPE_OFF, TPE_OFF,

View File

@ -34,7 +34,7 @@ static bool IN_SECTION(.ccm.bss) pid_should_run;
struct pid_controller IN_SECTION(.ccm.bss) pid; struct pid_controller IN_SECTION(.ccm.bss) pid;
bool IN_SECTION(.ccm.bss) cmd_continue; bool IN_SECTION(.ccm.bss) cmd_continue;
static struct pl_command IN_SECTION(.ccm.bss) cmd_list[MAX_PROFILE_LENGTH]; static SlList *command_list = NULL;
static void tpe_abort(void) static void tpe_abort(void)
{ {
@ -59,11 +59,19 @@ enum pl_ret_val temp_profile_executer_start(const char *filename)
state.profile_steps = 0; state.profile_steps = 0;
cmd_continue = false; cmd_continue = false;
res = temp_profile_parse_from_file(filename, cmd_list, MAX_PROFILE_LENGTH, &parsed_count); /* This should never happen... But who knows */
if (command_list) {
temp_profile_free_command_list(&command_list);
}
res = temp_profile_parse_from_file(filename, &command_list, MAX_PROFILE_LENGTH, &parsed_count);
if (res == PL_RET_SUCCESS) { if (res == PL_RET_SUCCESS) {
state.profile_steps = parsed_count; state.profile_steps = parsed_count;
state.status = TPE_RUNNING; state.status = TPE_RUNNING;
state.start_timestamp = systick_get_global_tick(); state.start_timestamp = systick_get_global_tick();
} else {
if (command_list)
temp_profile_free_command_list(&command_list);
} }
return res; return res;
@ -177,7 +185,7 @@ int temp_profile_executer_handle(void)
if (!systick_ticks_have_passed(last_tick, 100)) if (!systick_ticks_have_passed(last_tick, 100))
return 0; return 0;
current_cmd = &cmd_list[state.step]; current_cmd = (struct pl_command *)sl_list_nth(command_list, state.step)->data;
next_step = state.step; next_step = state.step;
switch (current_cmd->cmd) { switch (current_cmd->cmd) {
@ -250,6 +258,10 @@ int temp_profile_executer_stop(void)
oven_pid_stop(); oven_pid_stop();
} }
/* Free the command list */
if (command_list)
temp_profile_free_command_list(&command_list);
loudspeaker_set(0); loudspeaker_set(0);
return 0; return 0;