19 #include "freertos/FreeRTOS.h"
20 #include "freertos/task.h"
24 #include <NMEA2000_esp32-c6.h>
26 #include <N2kMessages.h>
28 #include "esp_pthread.h"
29 #include <NMEA2000_mcp.h>
31 #include "driver/gpio.h"
32 #include "bi-inc/attr_container.h"
34 #include "wasm_export.h"
35 #include "bh_read_file.h"
36 #include "bh_getopt.h"
37 #include "bh_platform.h"
43 #include "driver/spi_master.h"
46 #include "nmea_attack.h"
48 #define NATIVE_STACK_SIZE (32*1024)
49 #define NATIVE_HEAP_SIZE (32*1024)
50 #define PTHREAD_STACK_SIZE 4096
51 #define MAX_DATA_LENGTH_BTYES 223
52 #define MSG_BUFFER_SIZE (10 + 223*2)
53 #define MODE_BUFFER_SIZE 1
54 #define MY_ESP_LOG_LEVEL ESP_LOG_INFO
56 #define STATS_TASK_PRIO tskIDLE_PRIORITY
57 #define STATS_TICKS pdMS_TO_TICKS(1000)
58 #define ARRAY_SIZE_OFFSET 5
59 #define TX_QUEUE_SIZE 100
60 #define RX_QUEUE_SIZE 100
62 #define MCP0_TX GPIO_NUM_22
63 #define MCP0_RX GPIO_NUM_23
69 #define ESP_INTR_FLAG_DEFAULT 0
77 #define MODE_SETTING_PIN_LSB GPIO_NUM_18
78 #define MODE_SETTING_PIN_MSB GPIO_NUM_19
79 #define MODE_SETTING_MASK ((1ULL<<MODE_SETTING_PIN_LSB) | (1ULL<<MODE_SETTING_PIN_MSB))
84 static const char* TAG_TWAI =
"TWAI";
85 static const char* TAG_WASM =
"WASM";
86 static const char* TAG_MCP1 =
"MCP1";
87 static const char* TAG_MCP2 =
"MCP2";
88 static const char* TAG_STATUS =
"STATUS";
93 tNMEA2000_esp32c6
C0(MCP0_TX, MCP0_RX);
94 tNMEA2000_mcp C1(&
spi1,MCP1_CS,MCP_8MHZ,MCP1_INT,50);
95 tNMEA2000_mcp C2(&
spi2,MCP2_CS,MCP_8MHZ,MCP2_INT,50);
100 static TaskHandle_t C0_send_task_handle = NULL;
101 static TaskHandle_t C0_receive_task_handle = NULL;
102 static TaskHandle_t C1_send_task_handle = NULL;
103 static TaskHandle_t C1_receive_task_handle = NULL;
104 static TaskHandle_t C2_send_task_handle = NULL;
105 static TaskHandle_t C2_receive_task_handle = NULL;
106 static TaskHandle_t stats_task_handle = NULL;
107 static TaskHandle_t modes_task_handle = NULL;
113 static QueueHandle_t gpio_evt_queue = NULL;
118 static unsigned long C0_MsgSentCount=0;
119 static unsigned long C0_MsgFailCount=0;
120 static unsigned long C1_MsgSentCount=0;
121 static unsigned long C1_MsgFailCount=0;
122 static unsigned long C2_MsgSentCount=0;
123 static unsigned long C2_MsgFailCount=0;
137 void uintArrToCharrArray(uint8_t (&data_uint8_arr)[MAX_DATA_LENGTH_BTYES],
unsigned char (&data_char_arr)[MAX_DATA_LENGTH_BTYES]);
146 uint32_t
alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_TX_FAILED | TWAI_ALERT_RX_QUEUE_FULL;
149 int C0_rx_task_count = 0;
150 int C0_tx_task_count = 0;
151 int C1_rx_task_count = 0;
152 int C1_tx_task_count = 0;
153 int C2_rx_task_count = 0;
154 int C2_tx_task_count = 0;
155 int wasm_pthread_count = 0;
156 int stats_task_count = 0;
157 double wasm_main_duration;
171 void PrintStr(wasm_exec_env_t exec_env,uint8_t* input, int32_t length){
172 printf(
"PrintStr: ");
173 for (int32_t i = 0; i < length;i++ ) {
174 printf(
"%u ", *(input+i));
189 void PrintInt32(wasm_exec_env_t exec_env,int32_t number,int32_t hex){
191 printf(
"PrintInt32: %lx \n", number);
194 printf(
"PrintInt32: %li \n", number);
215 int32_t SendMsg(wasm_exec_env_t exec_env, int32_t controller_number, int32_t priority, int32_t PGN, int32_t source, uint8_t* data, int32_t data_length_bytes ){
216 ESP_LOGD(TAG_WASM,
"SendMsg called \n");
218 msg.controller_number = controller_number;
219 msg.priority = priority;
222 msg.data_length_bytes = data_length_bytes;
225 for (
size_t i = 0; i < data_length_bytes; ++i) {
226 uint8_t value =
static_cast<uint8_t
>(data[i]);
231 if (controller_number == C0_NUM){
233 ESP_LOGD(TAG_WASM,
"Added a msg to ctrl0_q with PGN %u \n", msg.PGN);
234 if (xQueueSendToBack(
C0_tx_queue, &msg, pdMS_TO_TICKS(10))){
238 else if(controller_number == C1_NUM)
241 ESP_LOGD(TAG_WASM,
"Added a msg to ctrl1_q with PGN %u \n", msg.PGN);
242 if (xQueueSendToBack(
C1_tx_queue, &msg, pdMS_TO_TICKS(10))){
246 else if(controller_number == C2_NUM)
249 ESP_LOGD(TAG_WASM,
"Added a msg to ctrl2_q with PGN %u \n", msg.PGN);
250 if (xQueueSendToBack(
C2_tx_queue, &msg, pdMS_TO_TICKS(10))){
255 ESP_LOGE(TAG_WASM,
"Invalid controller number: %" PRIu32
"", controller_number);
273 std::stringstream ss;
274 ss << std::hex << std::setw(1) << std::setfill('0') << static_cast<int>(msg.controller_number);
275 ss << std::hex << std::setw(1) << std::setfill('0') << static_cast<int>(msg.priority);
276 ss << std::hex << std::setw(5) << std::setfill(
'0') << msg.PGN;
277 ss << std::hex << std::setw(1) << std::setfill('0') << static_cast<int>(msg.source);
278 ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(msg.data_length_bytes);
279 for (uint8_t d : msg.data){
281 sprintf(hex_num,
"%X", d);
282 ss << std::setw(2) << hex_num;
284 const std::string s = ss.str();
296 void uint8ArrayToCharrArray(uint8_t (&data_uint8_arr)[MAX_DATA_LENGTH_BTYES],
unsigned char (&data_char_arr)[MAX_DATA_LENGTH_BTYES]){
297 for (
size_t i = 0; i < MAX_DATA_LENGTH_BTYES; ++i) {
298 data_char_arr[i] =
static_cast<unsigned char>(data_uint8_arr[i]);
306 static void IRAM_ATTR gpio_isr_handler(
void* arg)
308 uint32_t gpio_num = (uint32_t) arg;
309 xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
318 gpio_config_t io_conf = {};
320 io_conf.intr_type = GPIO_INTR_ANYEDGE;
322 io_conf.mode = GPIO_MODE_INPUT;
324 io_conf.pin_bit_mask = MODE_SETTING_MASK;
326 io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
328 io_conf.pull_up_en = GPIO_PULLUP_DISABLE ;
330 gpio_config(&io_conf);
333 gpio_evt_queue = xQueueCreate(10,
sizeof(uint32_t));
336 gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
338 gpio_isr_handler_add(MODE_SETTING_PIN_LSB, gpio_isr_handler, (
void*) MODE_SETTING_PIN_LSB);
340 gpio_isr_handler_add(MODE_SETTING_PIN_MSB, gpio_isr_handler, (
void*) MODE_SETTING_PIN_MSB);
356 if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
357 ESP_LOGD(
"MODE: ",
"GPIO[%" PRIu32
"] intr, val: %i\n", io_num, gpio_get_level(GPIO_NUM_18));
358 ESP_LOGD(
"MODE: ",
"GPIO[%" PRIu32
"] intr, val: %i\n", io_num, gpio_get_level(GPIO_NUM_19));
359 int msb = gpio_get_level(GPIO_NUM_19);
360 int lsb = gpio_get_level(GPIO_NUM_18);
361 int mode = (msb << 1) | lsb;
362 tc_mode = std::to_string(mode);
363 ESP_LOGD(
"MODE: ",
"%i",mode);
378 N2kMsg.Priority = msg.priority;
379 N2kMsg.PGN = msg.PGN;
380 N2kMsg.Source = msg.source;
381 N2kMsg.Destination = 0xff;
383 N2kMsg.DataLen = msg.data_length_bytes;
387 N2kMsg.MsgTime = N2kMillis64();
389 if(controller_num == C0_NUM){
390 if (
C0.SendMsg(N2kMsg) ) {
391 ESP_LOGD(TAG_TWAI,
"sent a message \n");
395 ESP_LOGW(TAG_TWAI,
"failed to send a message \n");
399 else if(controller_num == C1_NUM){
400 if ( C1.SendMsg(N2kMsg) ) {
401 ESP_LOGD(TAG_MCP1,
"sent a message \n");
405 ESP_LOGW(TAG_MCP1,
"failed to send a message \n");
409 else if(controller_num == C2_NUM){
410 if ( C2.SendMsg(N2kMsg) ) {
411 ESP_LOGD(TAG_MCP2,
"sent a message \n");
442 static esp_err_t print_real_time_stats(TickType_t xTicksToWait)
444 TaskStatus_t *start_array = NULL, *end_array = NULL;
445 UBaseType_t start_array_size, end_array_size;
446 uint32_t start_run_time, end_run_time;
450 start_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET;
451 start_array =
reinterpret_cast<TaskStatus_t*
>(std::malloc(
sizeof(TaskStatus_t) * start_array_size));
452 if (start_array == NULL) {
453 ret = ESP_ERR_NO_MEM;
459 start_array_size = uxTaskGetSystemState(start_array, start_array_size, &start_run_time);
460 if (start_array_size == 0) {
461 ret = ESP_ERR_INVALID_SIZE;
467 vTaskDelay(xTicksToWait);
470 end_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET;
471 end_array =
reinterpret_cast<TaskStatus_t*
>(std::malloc(
sizeof(TaskStatus_t) * end_array_size));
472 if (end_array == NULL) {
473 ret = ESP_ERR_NO_MEM;
479 end_array_size = uxTaskGetSystemState(end_array, end_array_size, &end_run_time);
480 if (end_array_size == 0) {
481 ret = ESP_ERR_INVALID_SIZE;
488 uint32_t total_elapsed_time = (end_run_time - start_run_time);
489 if (total_elapsed_time == 0) {
490 ret = ESP_ERR_INVALID_STATE;
496 printf(
"| Task | Run Time | Percentage\n");
498 for (
int i = 0; i < start_array_size; i++) {
500 for (
int j = 0; j < end_array_size; j++) {
501 if (start_array[i].xHandle == end_array[j].xHandle) {
504 start_array[i].xHandle = NULL;
505 end_array[j].xHandle = NULL;
511 uint32_t task_elapsed_time = end_array[k].ulRunTimeCounter - start_array[i].ulRunTimeCounter;
512 uint32_t percentage_time = (task_elapsed_time * 100UL) / (total_elapsed_time * portNUM_PROCESSORS);
513 printf(
"| %s | %" PRIu32
" | %" PRIu32
"%%\n", start_array[i].pcTaskName, task_elapsed_time, percentage_time);
518 for (
int i = 0; i < start_array_size; i++) {
519 if (start_array[i].xHandle != NULL) {
520 printf(
"| %s | Deleted\n", start_array[i].pcTaskName);
523 for (
int i = 0; i < end_array_size; i++) {
524 if (end_array[i].xHandle != NULL) {
525 printf(
"| %s | Created\n", end_array[i].pcTaskName);
545 C0.ReadAlerts(alerts, pdMS_TO_TICKS(1));
546 if (alerts & TWAI_ALERT_RX_QUEUE_FULL){
547 ESP_LOGW(TAG,
"TWAI rx queue full");
549 twai_status_info_t status;
550 C0.GetTwaiStatus(status);
551 ESP_LOGI(TAG,
"TWAI Msgs queued for transmission: %" PRIu32
" Unread messages in rx queue: %" PRIu32, status.msgs_to_tx, status.msgs_to_rx);
552 ESP_LOGI(TAG,
"Msgs lost due to TWAI RX FIFO overrun: %" PRIu32
"", status.rx_overrun_count);
553 ESP_LOGI(TAG,
"Msgs lost due to full TWAI RX queue: %" PRIu32
"", status.rx_missed_count);
555 UBaseType_t msgs_in_rx_q = uxQueueMessagesWaiting(
rx_queue);
556 ESP_LOGI(TAG,
"Received Messages queue size: %d \n", msgs_in_rx_q);
557 UBaseType_t msgs_in_q0 = uxQueueMessagesWaiting(
C0_tx_queue);
558 UBaseType_t msgs_in_q1 = uxQueueMessagesWaiting(
C1_tx_queue);
559 UBaseType_t msgs_in_q2 = uxQueueMessagesWaiting(
C2_tx_queue);
560 ESP_LOGI(TAG,
"Controller 0 send queue size: %d \n", msgs_in_q0);
561 ESP_LOGI(TAG,
"Controller 1 send queue size: %d \n", msgs_in_q1);
562 ESP_LOGI(TAG,
"Controller 2 send queue size: %d \n", msgs_in_q2);
565 ESP_LOGI(TAG,
"RX task count: %d", C0_rx_task_count);
566 ESP_LOGI(TAG,
"TX task count: %d", C0_tx_task_count);
567 ESP_LOGI(TAG,
"MCP1 RX task count: %d", C1_rx_task_count);
568 ESP_LOGI(TAG,
"MCP1 TX task count: %d", C1_tx_task_count);
569 ESP_LOGI(TAG,
"MCP2 RX task count: %d", C2_rx_task_count);
570 ESP_LOGI(TAG,
"MCP2 TX task count: %d", C2_tx_task_count);
571 ESP_LOGI(TAG,
"Wasm pthread count: %d", wasm_pthread_count);
572 ESP_LOGI(TAG,
"Stats task count: %d", stats_task_count);
575 ESP_LOGI(TAG,
"Duration of wasm task (ms): %f",wasm_main_duration/1000000);
584 static void stats_task(
void *arg)
588 printf(
"\n\nGetting real time stats over %" PRIu32
" ticks\n", STATS_TICKS);
589 if (print_real_time_stats(STATS_TICKS) == ESP_OK) {
590 printf(
"Real time stats obtained\n");
592 printf(
"Error getting real time stats\n");
596 vTaskDelay(pdMS_TO_TICKS(1000));
614 esp_log_level_set(TAG_TWAI, MY_ESP_LOG_LEVEL);
615 C0.SetN2kCANMsgBufSize(8);
616 C0.SetN2kCANReceiveFrameBufSize(250);
617 C0.EnableForward(
false);
619 C0.SetMode(tNMEA2000::N2km_ListenAndSend);
643 esp_log_level_set(TAG_TWAI, MY_ESP_LOG_LEVEL);
644 ESP_LOGI(TAG_TWAI,
"Starting C0_send_task");
650 if( xQueueReceive(
C0_tx_queue, &msg, (100 / portTICK_PERIOD_MS) ))
656 ESP_LOGV(TAG_TWAI,
"Send task called");
676 esp_log_level_set(TAG_MCP1, MY_ESP_LOG_LEVEL);
677 C1.SetN2kCANMsgBufSize(8);
678 C1.SetN2kCANReceiveFrameBufSize(250);
679 C1.EnableForward(
false);
681 C1.SetMode(tNMEA2000::N2km_ListenAndSend);
688 if( xSemaphoreTake(
x_sem_mcp1, (100 / portTICK_PERIOD_MS) ) == pdTRUE )
694 vTaskDelay(10 / portTICK_PERIOD_MS);
697 vTaskDelay(10 / portTICK_PERIOD_MS);
713 esp_log_level_set(TAG_MCP1, MY_ESP_LOG_LEVEL);
714 ESP_LOGI(TAG_TWAI,
"Starting C1_send_task");
720 if( xQueueReceive(
C1_tx_queue, &msg, (100 / portTICK_PERIOD_MS) ))
722 if( xSemaphoreTake(
x_sem_mcp1, portMAX_DELAY ) == pdTRUE )
725 ESP_LOGD(TAG_MCP1,
"About to send message with PGN: %i", msg.PGN);
734 ESP_LOGD(TAG_TWAI,
"Send task called");
754 esp_log_level_set(TAG_MCP2, MY_ESP_LOG_LEVEL);
756 C2.SetN2kCANMsgBufSize(8);
757 C2.SetN2kCANReceiveFrameBufSize(250);
758 C2.EnableForward(
false);
760 C2.SetMode(tNMEA2000::N2km_ListenAndSend);
766 if( xSemaphoreTake(
x_sem_mcp2, (100 / portTICK_PERIOD_MS) ) == pdTRUE )
772 vTaskDelay(100 / portTICK_PERIOD_MS);
775 vTaskDelay(10 / portTICK_PERIOD_MS);
791 esp_log_level_set(TAG_MCP2, MY_ESP_LOG_LEVEL);
792 ESP_LOGI(TAG_TWAI,
"Starting C2_send_task");
798 if( xQueueReceive(
C2_tx_queue, &msg, (100 / portTICK_PERIOD_MS) ))
800 if( xSemaphoreTake(
x_sem_mcp2, portMAX_DELAY ) == pdTRUE )
803 ESP_LOGD(TAG_MCP2,
"About to send message with PGN: %i", msg.PGN);
810 ESP_LOGD(TAG_TWAI,
"Send task called");
825 if (N2kMsg.Source == 14){
826 ESP_LOGD(TAG_TWAI,
"source is 14");
829 ESP_LOGV(TAG_TWAI,
"Message Handler called");
831 msg.controller_number = 0;
832 msg.priority = N2kMsg.Priority;
834 msg.PGN = N2kMsg.PGN;
835 ESP_LOGD(TAG_TWAI,
"PGN %u", msg.PGN);
836 msg.source = N2kMsg.Source;
837 msg.data_length_bytes = N2kMsg.DataLen;
838 size_t size =
sizeof(N2kMsg.Data) /
sizeof(N2kMsg.Data[0]);
840 for (
size_t i = 0; i < size; i++) {
841 if (N2kMsg.Data[i] <=
static_cast<unsigned char>(CHAR_MAX)) {
842 msg.data[i] =
static_cast<signed char>(N2kMsg.Data[i]);
846 ESP_LOGE(
"Message Handle",
"data out of range for signed array");
850 if(xQueueSendToBack(
rx_queue, &msg, pdMS_TO_TICKS(10)) == 0){
851 ESP_LOGW(TAG_TWAI,
"Could not add received message to RX queue");
854 ESP_LOGV(TAG_TWAI,
" added msg to received queue");
867 static void * app_instance_main(wasm_module_inst_t module_inst)
869 const char *exception;
871 wasm_application_execute_main(module_inst, 0, NULL);
872 if ((exception = wasm_runtime_get_exception(module_inst)))
873 ESP_LOGW(TAG_WASM,
"%s\n", exception);
889 esp_log_level_set(TAG_WASM, MY_ESP_LOG_LEVEL);
892 uint8_t *wasm_file_buf = NULL;
893 unsigned wasm_file_buf_size = 0;
894 wasm_exec_env_t exec_env = NULL;
895 wasm_module_t wasm_module = NULL;
896 wasm_module_inst_t wasm_module_inst = NULL;
899 wasm_function_inst_t func = NULL;
900 RuntimeInitArgs init_args;
902 uint32_t buffer_for_wasm = 0;
903 uint32_t buffer_for_wasm_mode = 0;
906 memset(&init_args, 0,
sizeof(RuntimeInitArgs));
909 static NativeSymbol native_symbols[] = {
924 reinterpret_cast<void*
>(SendMsg),
929 #if WASM_ENABLE_GLOBAL_HEAP_POOL == 0
930 init_args.mem_alloc_type = Alloc_With_Allocator;
931 init_args.mem_alloc_option.allocator.malloc_func = (
void *)os_malloc;
932 init_args.mem_alloc_option.allocator.realloc_func = (
void *)os_realloc;
933 init_args.mem_alloc_option.allocator.free_func = (
void *)os_free;
935 #error The usage of a global heap pool is not implemented yet for esp-idf.
939 init_args.n_native_symbols =
sizeof(native_symbols) /
sizeof(NativeSymbol);
940 init_args.native_module_name =
"env";
941 init_args.native_symbols = native_symbols;
944 ESP_LOGI(TAG_WASM,
"Initialize WASM runtime");
946 if (!wasm_runtime_full_init(&init_args)) {
947 ESP_LOGE(TAG_WASM,
"Init runtime failed.");
950 ESP_LOGI(TAG_WASM,
"Run wamr with interpreter");
952 wasm_file_buf = (uint8_t *)nmea_attack_wasm;
953 wasm_file_buf_size =
sizeof(nmea_attack_wasm);
956 if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_buf_size,
957 error_buf,
sizeof(error_buf)))) {
958 ESP_LOGE(TAG_WASM,
"Error in wasm_runtime_load: %s", error_buf);
962 ESP_LOGI(TAG_WASM,
"Instantiate WASM runtime");
963 if (!(wasm_module_inst =
964 wasm_runtime_instantiate(wasm_module, NATIVE_STACK_SIZE,
966 error_buf,
sizeof(error_buf)))) {
967 ESP_LOGE(TAG_WASM,
"Error while instantiating: %s", error_buf);
972 exec_env = wasm_runtime_create_exec_env(wasm_module_inst, NATIVE_STACK_SIZE);
974 ESP_LOGW(TAG_WASM,
"Create wasm execution environment failed.\n");
979 ESP_LOGI(TAG_WASM,
"Malloc buffer in wasm function");
980 buffer_for_wasm = wasm_runtime_module_malloc(wasm_module_inst, 100, (
void **)&
wasm_buffer);
981 if (buffer_for_wasm == 0) {
982 ESP_LOGI(TAG_WASM,
"Malloc failed");
986 argv[0] = buffer_for_wasm;
987 argv[1] = MSG_BUFFER_SIZE;
988 ESP_LOGI(TAG_WASM,
"Call wasm function");
992 if (!(func = wasm_runtime_lookup_function(wasm_module_inst,
"link_msg_buffer",
995 "The wasm function link_msg_buffer wasm function is not found.\n");
999 if (wasm_runtime_call_wasm(exec_env, func, 2, argv)) {
1000 ESP_LOGI(TAG_WASM,
"Native finished calling wasm function: link_msg_buffer, "
1001 "returned a formatted string: %s\n",
1005 ESP_LOGW(TAG_WASM,
"call wasm function link_msg_buffer failed. error: %s\n",
1006 wasm_runtime_get_exception(wasm_module_inst));
1011 ESP_LOGI(TAG_WASM,
"Malloc buffer in wasm function");
1012 buffer_for_wasm_mode = wasm_runtime_module_malloc(wasm_module_inst, 100, (
void **)&
wasm_mode_buffer);
1013 if (buffer_for_wasm_mode == 0) {
1014 ESP_LOGI(TAG_WASM,
"Malloc failed");
1017 uint32 argv_mode[2];
1018 argv_mode[0] = buffer_for_wasm_mode;
1019 argv_mode[1] = MODE_BUFFER_SIZE;
1020 ESP_LOGI(TAG_WASM,
"Call wasm function");
1024 if (!(func = wasm_runtime_lookup_function(wasm_module_inst,
"link_mode_buffer",
1027 "The wasm function link_mode_buffer wasm function is not found.\n");
1031 if (wasm_runtime_call_wasm(exec_env, func, 2, argv_mode)) {
1032 ESP_LOGI(TAG_WASM,
"Native finished calling wasm function: link_mode_buffer, "
1033 "returned a formatted string: %s\n",
1037 ESP_LOGW(TAG_WASM,
"call wasm function link_mode_buffer failed. error: %s\n",
1038 wasm_runtime_get_exception(wasm_module_inst));
1045 ESP_LOGV(TAG_WASM,
"run main() of the application");
1046 auto start = std::chrono::high_resolution_clock::now();
1048 if (xQueueReceive(
rx_queue, &msg, (100 / portTICK_PERIOD_MS) == 1)){
1050 strncpy(
wasm_buffer, str_msg.c_str(), str_msg.size());
1052 ret = app_instance_main(wasm_module_inst);
1055 vTaskDelay(10 / portTICK_PERIOD_MS);
1058 auto end = std::chrono::high_resolution_clock::now();
1059 auto ns_duration = duration_cast<std::chrono::nanoseconds>(end-start);
1060 wasm_main_duration =
static_cast<double>(ns_duration.count());
1062 wasm_pthread_count++;
1070 ESP_LOGI(TAG_WASM,
"Deinstantiate WASM runtime");
1071 wasm_runtime_deinstantiate(wasm_module_inst);
1075 wasm_runtime_destroy_exec_env(exec_env);
1076 if (wasm_module_inst) {
1077 if (buffer_for_wasm){
1078 wasm_runtime_module_free(wasm_module_inst, buffer_for_wasm);}
1079 if (buffer_for_wasm_mode)
1081 wasm_runtime_module_free(wasm_module_inst, buffer_for_wasm_mode);
1083 wasm_runtime_deinstantiate(wasm_module_inst);
1087 ESP_LOGI(TAG_WASM,
"Unload WASM module");
1088 wasm_runtime_unload(wasm_module);
1097 ESP_LOGI(TAG_WASM,
"Destroy WASM runtime");
1098 wasm_runtime_destroy();
1117 esp_err_t result = ESP_OK;
1121 printf(
"create task");
1122 xTaskCreatePinnedToCore(
1131 if (stats_task_handle == NULL)
1133 printf(
"Unable to create task.");
1134 result = ESP_ERR_NO_MEM;
1139 printf(
"create task");
1140 xTaskCreatePinnedToCore(
1149 if (modes_task_handle == NULL)
1151 printf(
"Unable to create task.");
1152 result = ESP_ERR_NO_MEM;
1156 ESP_LOGV(TAG_WASM,
"create task");
1157 xTaskCreatePinnedToCore(
1163 &C0_send_task_handle,
1166 if (C0_send_task_handle == NULL)
1168 ESP_LOGE(TAG_TWAI,
"Unable to create task.");
1169 result = ESP_ERR_NO_MEM;
1173 ESP_LOGV(TAG_TWAI,
"create task");
1174 xTaskCreatePinnedToCore(
1180 &C0_receive_task_handle,
1183 if (C0_receive_task_handle == NULL)
1185 ESP_LOGE(TAG_TWAI,
"Unable to create task.");
1186 result = ESP_ERR_NO_MEM;
1192 ESP_LOGV(TAG_MCP1,
"create task");
1193 xTaskCreatePinnedToCore(
1199 &C1_send_task_handle,
1202 if (C1_send_task_handle == NULL)
1204 ESP_LOGE(TAG_MCP1,
"Unable to create task.");
1205 result = ESP_ERR_NO_MEM;
1209 ESP_LOGV(TAG_MCP1,
"create task");
1210 xTaskCreatePinnedToCore(
1216 &C1_receive_task_handle,
1219 if (C1_receive_task_handle == NULL)
1221 ESP_LOGE(TAG_MCP1,
"Unable to create task.");
1222 result = ESP_ERR_NO_MEM;
1226 ESP_LOGV(TAG_MCP2,
"create task");
1227 xTaskCreatePinnedToCore(
1233 &C2_send_task_handle,
1236 if (C2_send_task_handle == NULL)
1238 ESP_LOGE(TAG_MCP2,
"Unable to create task.");
1239 result = ESP_ERR_NO_MEM;
1243 ESP_LOGV(TAG_MCP2,
"create task");
1244 xTaskCreatePinnedToCore(
1250 &C2_receive_task_handle,
1253 if (C2_receive_task_handle == NULL)
1255 ESP_LOGE(TAG_MCP2,
"Unable to create task.");
1256 result = ESP_ERR_NO_MEM;
1263 esp_pthread_cfg_t esp_pthread_cfg;
1267 pthread_attr_t tattr;
1268 pthread_attr_init(&tattr);
1269 pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
1270 pthread_attr_setstacksize(&tattr, PTHREAD_STACK_SIZE);
1273 esp_pthread_cfg = esp_pthread_get_default_config();
1274 ESP_LOGI(TAG_WASM,
"Pthread priority: %d", esp_pthread_cfg.prio);
1275 ESP_LOGI(TAG_WASM,
"Pthread core: %d", esp_pthread_cfg.pin_to_core);
1276 esp_pthread_cfg.prio = tskIDLE_PRIORITY+1;
1277 esp_pthread_cfg.pin_to_core = 1;
1278 ESP_ERROR_CHECK( esp_pthread_set_cfg(&esp_pthread_cfg) );
1280 res = pthread_create(&t, &tattr,
iwasm_main, (
void *)NULL);
1283 esp_pthread_get_cfg(&esp_pthread_cfg);
1284 ESP_LOGI(TAG_WASM,
"Pthread priority: %d", esp_pthread_cfg.prio);
1285 res = pthread_join(t, NULL);
1289 if (result != ESP_OK)
1291 if (C0_send_task_handle != NULL || C0_receive_task_handle != NULL || C1_send_task_handle != NULL || C1_receive_task_handle != NULL || C2_send_task_handle != NULL || C2_receive_task_handle != NULL|| stats_task_handle != NULL)
1293 vTaskDelete(C0_send_task_handle);
1294 vTaskDelete(C0_receive_task_handle);
1295 vTaskDelete(C1_send_task_handle);
1296 vTaskDelete(C1_receive_task_handle);
1297 vTaskDelete(C2_send_task_handle);
1298 vTaskDelete(C2_receive_task_handle);
1299 vTaskDelete(stats_task_handle);
1300 C0_send_task_handle = NULL;
1301 C0_receive_task_handle = NULL;
1302 C1_send_task_handle = NULL;
1303 C1_receive_task_handle = NULL;
1304 C2_send_task_handle = NULL;
1305 C2_receive_task_handle = NULL;
1306 stats_task_handle = NULL;
Represents a NMEA 2000 messages.
QueueHandle_t C0_tx_queue
Queue that stores messages to be sent out on controller 0.
void uint8ArrayToCharrArray(uint8_t(&data_uint8_arr)[MAX_DATA_LENGTH_BTYES], unsigned char(&data_char_arr)[MAX_DATA_LENGTH_BTYES])
Fills a char array with values from a uint8_t array.
QueueHandle_t rx_queue
Queue that stores all messages received on all controllers.
int app_main(void)
Creates a FreeRTOS task for sending and receiving to and from CAN Controller and creates a pthread to...
SemaphoreHandle_t x_sem_mcp2
Semaphore handle for MCP2.
std::string tc_mode
Contains the T Connector mode-> 0 - OFF, 1 - PASSIVE, 2 - GPS_ATTACK, 3 - TBD.
void C1_receive_task(void *pvParameters)
FreeRTOS task for receiving messages from MCP CAN controller 1.
void get_mode_task(void *pvParameters)
Task to get the Controller Mode set by the Raspberry Pi.
void configTConnectorModes()
Configures GPIO used to read mode settings from the Raspberry Pi.
void * iwasm_main(void *arg)
WASM pthread to host wasm app.
void C1_send_task(void *pvParameters)
FreeRTOS task for processing and sending messages from MCP CAN controller 1 with NMEA2000 library.
char * wasm_buffer
buffer allocated for wasm app, used to hold received messages so app can access them
CONTROLLER
enum to store identifiers for each controller
bool SendN2kMsg(NMEA_msg msg, int controller_num)
Sends a message.
void PrintStr(wasm_exec_env_t exec_env, uint8_t *input, int32_t length)
prints a uint8_t array to terminal
tNMEA2000_esp32c6 C0(MCP0_TX, MCP0_RX)
Controller 0 -> TWAI, (TX_PIN, RX_PIN)
void C0_send_task(void *pvParameters)
FreeRTOS task for processing and sending messages from CAN controller with NMEA2000 library.
int send_msg_count
Used to track messages sent.
void HandleNMEA2000Msg(const tN2kMsg &N2kMsg)
Creates a NMEA_msg object and adds it to.data the received messages queue.
void C0_receive_task(void *pvParameters)
FreeRTOS task for receiving messages from CAN controller.
SemaphoreHandle_t x_sem_mcp1
Semaphore handle for MCP1.
QueueHandle_t C2_tx_queue
Queue that stores messages to be sent out on controller 2.
std::string nmea_to_string(NMEA_msg &msg)
converts a NMEA_msg to a string
void C2_receive_task(void *pvParameters)
FreeRTOS task for receiving messages from MCP CAN controller 2.
void C2_send_task(void *pvParameters)
FreeRTOS task for processing and sending messages from MCP CAN controller 2 with NMEA2000 library.
int read_msg_count
Used to track messages read.
spi_device_handle_t spi2
MCP controller 2 spi handle.
uint32_t alerts_to_enable
Sets which alerts to enable for TWAI controller.
spi_device_handle_t spi1
MCP controller 1 spi handle.
void PrintInt32(wasm_exec_env_t exec_env, int32_t number, int32_t hex)
prints a integer to terminal
QueueHandle_t C1_tx_queue
Queue that stores messages to be sent out on controller 1.
char * wasm_mode_buffer
buffer allocated for wasm app, used to hold current t connector mode set by Raspberry Pi
void GetStatus(const char *TAG)
Retrieves twai status and alerts.