added linked list and control of adv filters + some fixes + finished

simple filtering
This commit is contained in:
Данила Горнушко 2023-11-29 11:27:23 +03:00
parent a841d5c44b
commit c86191a104
6 changed files with 210 additions and 18 deletions

View file

@ -0,0 +1,4 @@
idf_component_register(
INCLUDE_DIRS .
SRCS list.c
)

View file

@ -0,0 +1,111 @@
#ifndef LIST_DEF
#define LIST_DEF 1
/*
File: list.c
Description: Implementation of linked list object functionality.
Created: March 21, 2017
Author: Matt Mumau
*/
// System dependencies
#include <stdlib.h>
// Header
#include "list.h"
void list_push(List** head, void* data) {
List* node = malloc(sizeof(List));
if (node == NULL) {
return;
}
node->data = data;
node->next = NULL;
if (*head == NULL) {
*head = node;
return;
}
while ((*head)->next != NULL) {
head = &(*head)->next;
}
(*head)->next = node;
}
void* list_pop(List** head) {
void* data = NULL;
if (*head == NULL) {
return data;
}
List** last = head;
while ((*head)->next != NULL) {
last = head;
head = &(*head)->next;
}
data = (void*) (*head)->data;
(*last)->next = NULL;
free(*head);
*head = NULL;
return data;
}
void list_insert(List** head, void* data) {
List* node = malloc(sizeof(List));
node->data = data;
node->next = *head;
*head = node;
}
unsigned int list_sizeof(List* head) {
if (head == NULL) {
return 0;
}
unsigned int size = 1;
while (head->next != NULL) {
size++;
head = head->next;
}
return size;
}
List* list_get(List* head, unsigned int index) {
for (unsigned int i = 0; i < index; i++) {
head = head->next;
}
return head;
}
void list_remove(List** head, unsigned int index) {
if (!head || !*head || index >= list_sizeof(*head)) return;
if (index == 0) {
List* prev_head = (*head);
(*head) = (*head)->next;
free(prev_head);
} else {
List* a_cursor = (*head);
for (unsigned int i = 1; i < index; i++) {
a_cursor = a_cursor->next;
}
List* tmp_cursor = a_cursor->next;
tmp_cursor = tmp_cursor->next;
free(a_cursor->next);
a_cursor->next = tmp_cursor;
}
}
#endif

View file

@ -0,0 +1,46 @@
#ifndef LIST_H_DEF
#define LIST_H_DEF 1
/*
File: list.h
Description: Linked list library definition
Created: March 21, 2017
Author: Matt Mumau
*/
typedef struct List {
void* data;
struct List* next;
} List;
/*
Push data to the end of the list.
*/
void list_push(List** head, void* data);
/*
Remove the final element of the list and return its data.
*/
void* list_pop(List** head);
/*
Insert the data object to the beginning of the list.
*/
void list_insert(List** head, void* data);
/*
Get the size of the list.
*/
unsigned int list_sizeof(List* head);
/*
Get the data of the node at the given ordinal number in the list.
*/
List* list_get(List* head, unsigned int index);
/*
Delete the item in the list at the given ordinal location (1 is the first).
*/
void list_remove(List** head, unsigned int index);
#endif

View file

@ -13,7 +13,11 @@
bool is_error_passive = false; bool is_error_passive = false;
bool auto_recovery = false; bool auto_recovery = false;
bool advanced_filtering = false; adv_filt_t adv_filters = {
.filters = NULL,
.enabled = false,
.sw_filtering = false,
};
SemaphoreHandle_t can_mutex; SemaphoreHandle_t can_mutex;
volatile can_status_t curr_can_state = { 0 }; volatile can_status_t curr_can_state = { 0 };
@ -112,7 +116,7 @@ void can_task(void* arg) {
sem_res = xSemaphoreTake(can_mutex, 0); sem_res = xSemaphoreTake(can_mutex, 0);
if (sem_res == pdTRUE) { if (sem_res == pdTRUE) {
while ((ret = twai_receive(&rx_msg, can_task_timeout)) == ESP_OK) { while ((ret = twai_receive(&rx_msg, can_task_timeout)) == ESP_OK) {
if (advanced_filtering) { if (adv_filters.sw_filtering) {
if (!matches_filters(&rx_msg)) continue; if (!matches_filters(&rx_msg)) continue;
} }
can_msg_to_str(&rx_msg, "recv ", data_bytes_str); can_msg_to_str(&rx_msg, "recv ", data_bytes_str);

View file

@ -6,6 +6,7 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include <stdint.h> #include <stdint.h>
#include <list.h>
typedef struct { typedef struct {
char status[30]; char status[30];
@ -24,6 +25,12 @@ typedef enum {
CAN_RECOVERING = 5, CAN_RECOVERING = 5,
} can_state_e; } can_state_e;
typedef struct {
bool enabled;
List* filters;
bool sw_filtering;
} adv_filt_t;
typedef struct { typedef struct {
can_state_e state; can_state_e state;
uint32_t msgs_to_tx; /**< Number of messages queued for transmission or awaiting transmission completion */ uint32_t msgs_to_tx; /**< Number of messages queued for transmission or awaiting transmission completion */
@ -39,10 +46,9 @@ typedef struct {
extern SemaphoreHandle_t can_mutex; extern SemaphoreHandle_t can_mutex;
extern volatile can_status_t curr_can_state; extern volatile can_status_t curr_can_state;
extern bool timestamp_enabled;
extern bool auto_recovery; extern bool auto_recovery;
extern bool is_error_passive; extern bool is_error_passive;
extern bool advanced_filtering; extern adv_filt_t adv_filters;
// functions // functions

View file

@ -42,7 +42,7 @@ static struct {
} cansend_args; } cansend_args;
static int send_can_frame(int argc, char **argv) { static int send_can_frame(int argc, char **argv) {
twai_message_t msg = {.extd = 1}; twai_message_t msg = { 0 };
char printf_str[70]; char printf_str[70];
int nerrors = arg_parse(argc, argv, (void **) &cansend_args); int nerrors = arg_parse(argc, argv, (void **) &cansend_args);
if (nerrors != 0) { if (nerrors != 0) {
@ -56,7 +56,7 @@ static int send_can_frame(int argc, char **argv) {
if ((id_substr == NULL) || (strtok(NULL, "#") != NULL)) goto invalid_args; if ((id_substr == NULL) || (strtok(NULL, "#") != NULL)) goto invalid_args;
int id_l = strlen(id_substr); int id_l = strlen(id_substr);
int dt_l = data_substr == NULL ? 0 : strlen(data_substr); int dt_l = data_substr == NULL ? 0 : strlen(data_substr);
if ((id_l > 8) || (dt_l > 16) || (id_l % 2) || (dt_l % 2)) goto invalid_args; if ((id_l > 8) || (dt_l > 16) || (dt_l % 2)) goto invalid_args;
for (int i = 0; i < id_l; i++) if(!isxdigit((int) id_substr[i])) goto invalid_args; for (int i = 0; i < id_l; i++) if(!isxdigit((int) id_substr[i])) goto invalid_args;
for (int i = 0; i < dt_l; i++) if(!isxdigit((int) data_substr[i])) goto invalid_args; for (int i = 0; i < dt_l; i++) if(!isxdigit((int) data_substr[i])) goto invalid_args;
int msg_id; int msg_id;
@ -72,6 +72,7 @@ static int send_can_frame(int argc, char **argv) {
} }
msg.data_length_code = dt_l / 2; msg.data_length_code = dt_l / 2;
msg.identifier = msg_id; msg.identifier = msg_id;
msg.extd = (id_l > 3);
esp_err_t res = twai_transmit(&msg, pdMS_TO_TICKS(1000)); esp_err_t res = twai_transmit(&msg, pdMS_TO_TICKS(1000));
switch(res) { switch(res) {
case ESP_OK: case ESP_OK:
@ -91,7 +92,7 @@ static int send_can_frame(int argc, char **argv) {
free(can_msg_str_buf); free(can_msg_str_buf);
return 0; return 0;
invalid_args: invalid_args:
printf("Invalid arguments!\n"); print_w_clr_time("Invalid arguments!", LOG_COLOR_RED, true);
free(can_msg_str_buf); free(can_msg_str_buf);
return 1; return 1;
} }
@ -115,7 +116,7 @@ static const char* can_states_str[] = {
static int canstats(int argc, char **argv) { static int canstats(int argc, char **argv) {
if (curr_can_state.state == CAN_NOT_INSTALLED) { if (curr_can_state.state == CAN_NOT_INSTALLED) {
printf("CAN driver is not installed!\n"); print_w_clr_time("CAN driver is not installed!", LOG_COLOR_RED, true);
return 0; return 0;
} else { } else {
const char *state_str = can_states_str[curr_can_state.state]; const char *state_str = can_states_str[curr_can_state.state];
@ -156,10 +157,10 @@ static int canup(int argc, char **argv) {
} }
if (canup_args.filters->count) { if (canup_args.filters->count) {
f_config = my_filters; f_config = my_filters;
print_w_clr_time("Using predefined filters.", LOG_COLOR_GREEN, true); printf("Using %s filters.\n", adv_filters.enabled ? "smart" : "basic hw");
} else { } else {
f_config = (twai_filter_config_t) TWAI_FILTER_CONFIG_ACCEPT_ALL(); f_config = (twai_filter_config_t) TWAI_FILTER_CONFIG_ACCEPT_ALL();
print_w_clr_time("Using accept all filters.", LOG_COLOR_GREEN, true); printf("Using accept all filters.\n");
} }
esp_log_level_t prev_gpio_lvl = esp_log_level_get("gpio"); esp_log_level_t prev_gpio_lvl = esp_log_level_get("gpio");
int mode = 0; int mode = 0;
@ -360,9 +361,9 @@ static void register_canrecover(void) {
} }
static struct { static struct {
struct arg_lit *dual; struct arg_lit *dual_arg;
struct arg_str *code; struct arg_str *code_arg;
struct arg_str *mask; struct arg_str *mask_arg;
struct arg_end *end; struct arg_end *end;
} canfilter_args; } canfilter_args;
@ -372,20 +373,40 @@ static int canfilter(int argc, char **argv) {
arg_print_errors(stderr, canfilter_args.end, argv[0]); arg_print_errors(stderr, canfilter_args.end, argv[0]);
return 1; return 1;
} }
if (canfilter_args.dual->count) { const char* mask_s = canfilter_args.mask_arg->sval[0];
const char* code_s = canfilter_args.code_arg->sval[0];
int m_l = strlen(mask_s);
int c_l = strlen(code_s);
if (m_l != 8 || c_l != 8) goto invalid_args;
for (int i = 0; i < m_l; i++) if(!isxdigit((int) mask_s[i])) goto invalid_args;
for (int i = 0; i < c_l; i++) if(!isxdigit((int) code_s[i])) goto invalid_args;
uint32_t mask = 0;
uint32_t code = 0;
if (sscanf(mask_s, "%" PRIX32, &mask) < 1) goto invalid_args;
if (sscanf(code_s, "%" PRIX32, &code) < 1) goto invalid_args;
if (canfilter_args.dual_arg->count) {
my_filters.single_filter = false; my_filters.single_filter = false;
print_w_clr_time("Setting hw filters in dual mode.", LOG_COLOR_GREEN, true);
} else { } else {
my_filters.single_filter = true; my_filters.single_filter = true;
print_w_clr_time("Setting hw filters in single mode.", LOG_COLOR_GREEN, true);
} }
printf("mask: %" PRIX32 ", code: %" PRIX32 "\n", mask, code);
my_filters.acceptance_code = code;
my_filters.acceptance_mask = mask;
adv_filters.enabled = false;
adv_filters.sw_filtering = false;
return 0; return 0;
invalid_args:
print_w_clr_time("Invalid arguments!", LOG_COLOR_RED, true);
return 1;
} }
static void register_canfilter(void) { static void register_canfilter(void) {
canfilter_args.mask = arg_str1("m", "mask", "<mask>", "Acceptance mask (as in esp-idf docs), uint32_t in hex form, 8 symbols."); canfilter_args.mask_arg = arg_str1("m", "mask", "<mask>", "Acceptance mask (as in esp-idf docs), uint32_t in hex form, 8 symbols.");
canfilter_args.code = arg_str1("c", "code", "<code>", "Acceptance code (as in esp-idf docs), uint32_t in hex form, 8 symbols."); canfilter_args.code_arg = arg_str1("c", "code", "<code>", "Acceptance code (as in esp-idf docs), uint32_t in hex form, 8 symbols.");
canfilter_args.dual = arg_lit0("d", NULL, "Use Dual Filter Mode."); canfilter_args.dual_arg = arg_lit0("d", NULL, "Use Dual Filter Mode.");
const esp_console_cmd_t cmd = { const esp_console_cmd_t cmd = {
.command = "canfilter", .command = "canfilter",