forked from test34/can_wizard
added linked list and control of adv filters + some fixes + finished
simple filtering
This commit is contained in:
parent
a841d5c44b
commit
c86191a104
6 changed files with 210 additions and 18 deletions
4
components/C-Linked-List/CMakeLists.txt
Normal file
4
components/C-Linked-List/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
idf_component_register(
|
||||
INCLUDE_DIRS .
|
||||
SRCS list.c
|
||||
)
|
111
components/C-Linked-List/list.c
Normal file
111
components/C-Linked-List/list.c
Normal 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
|
46
components/C-Linked-List/list.h
Normal file
46
components/C-Linked-List/list.h
Normal 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
|
|
@ -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);
|
||||
|
|
10
main/can.h
10
main/can.h
|
@ -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
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue