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 auto_recovery = false;
bool advanced_filtering = false;
adv_filt_t adv_filters = {
.filters = NULL,
.enabled = false,
.sw_filtering = false,
};
SemaphoreHandle_t can_mutex;
volatile can_status_t curr_can_state = { 0 };
@ -112,7 +116,7 @@ void can_task(void* arg) {
sem_res = xSemaphoreTake(can_mutex, 0);
if (sem_res == pdTRUE) {
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;
}
can_msg_to_str(&rx_msg, "recv ", data_bytes_str);

View file

@ -6,6 +6,7 @@
#include "sdkconfig.h"
#include "freertos/semphr.h"
#include <stdint.h>
#include <list.h>
typedef struct {
char status[30];
@ -24,6 +25,12 @@ typedef enum {
CAN_RECOVERING = 5,
} can_state_e;
typedef struct {
bool enabled;
List* filters;
bool sw_filtering;
} adv_filt_t;
typedef struct {
can_state_e state;
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 volatile can_status_t curr_can_state;
extern bool timestamp_enabled;
extern bool auto_recovery;
extern bool is_error_passive;
extern bool advanced_filtering;
extern adv_filt_t adv_filters;
// functions

View file

@ -42,7 +42,7 @@ static struct {
} cansend_args;
static int send_can_frame(int argc, char **argv) {
twai_message_t msg = {.extd = 1};
twai_message_t msg = { 0 };
char printf_str[70];
int nerrors = arg_parse(argc, argv, (void **) &cansend_args);
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;
int id_l = strlen(id_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 < dt_l; i++) if(!isxdigit((int) data_substr[i])) goto invalid_args;
int msg_id;
@ -72,6 +72,7 @@ static int send_can_frame(int argc, char **argv) {
}
msg.data_length_code = dt_l / 2;
msg.identifier = msg_id;
msg.extd = (id_l > 3);
esp_err_t res = twai_transmit(&msg, pdMS_TO_TICKS(1000));
switch(res) {
case ESP_OK:
@ -91,7 +92,7 @@ static int send_can_frame(int argc, char **argv) {
free(can_msg_str_buf);
return 0;
invalid_args:
printf("Invalid arguments!\n");
print_w_clr_time("Invalid arguments!", LOG_COLOR_RED, true);
free(can_msg_str_buf);
return 1;
}
@ -115,7 +116,7 @@ static const char* can_states_str[] = {
static int canstats(int argc, char **argv) {
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;
} else {
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) {
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 {
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");
int mode = 0;
@ -360,9 +361,9 @@ static void register_canrecover(void) {
}
static struct {
struct arg_lit *dual;
struct arg_str *code;
struct arg_str *mask;
struct arg_lit *dual_arg;
struct arg_str *code_arg;
struct arg_str *mask_arg;
struct arg_end *end;
} canfilter_args;
@ -372,20 +373,40 @@ static int canfilter(int argc, char **argv) {
arg_print_errors(stderr, canfilter_args.end, argv[0]);
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;
print_w_clr_time("Setting hw filters in dual mode.", LOG_COLOR_GREEN, true);
} else {
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;
invalid_args:
print_w_clr_time("Invalid arguments!", LOG_COLOR_RED, true);
return 1;
}
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.code = 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.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 = arg_str1("c", "code", "<code>", "Acceptance code (as in esp-idf docs), uint32_t in hex form, 8 symbols.");
canfilter_args.dual_arg = arg_lit0("d", NULL, "Use Dual Filter Mode.");
const esp_console_cmd_t cmd = {
.command = "canfilter",