-
Hi guys, I'm using the CMake extensions and the languages are C and C++. If you need more parts of the programm, just ask for them :) |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 7 replies
-
Hey there! I'm not an ESP32 expert, maybe @GwnDaan knows more since he is the main author of the ESP32 integration, but I would definitely question how the ESP32's file streaming works. That helper function in Either way, I have a suggestion you could try! I've attached a cpp file that contains the content of that IOP file as a It's a bit weird, but this is fairly similar to how I'd expect someone to load an object pool on a platform with onboard flash memory as well, like Teensy (some day). There is one downside, and that is that you may need to cast it if you want to use Let me know if you run into compilation issues with the library, or if you have to change things in the library to make everything happy, as we will want to make sure it's as compatible with ESP32 as we can. |
Beta Was this translation helpful? Give feedback.
-
Hey @thiagozf1! I only have experience with using ESP in combination with PlatformIO, but the following might be useful to you as well. I don't use any file system on my ESP but instead compile the binary pool file together with the rest of the program and then flash it all together. For PlatformIO to do this I have to specify the following in the board_build.embed_txtfiles = src/vtpooldata.iop In your case, where you use CMake with ESP, I think it is a different setting, but similar. Your best bet I feel like is to read the following: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/build-system.html#embedding-binary-data How I load in an embedded object pool which is compiled together with the program: // Load object pool from embedded vtpooldata.iop file
extern const std::uint8_t iopStart[] asm("_binary_vtpooldata_iop_start");
extern const std::uint8_t iopEnd[] asm("_binary_vtpooldata_iop_end");
const size_t objectPoolSize = (iopEnd - iopStart) - 1;
if (0 == objectPoolSize)
{
ESP_LOGI("UI Controller", "Failed to load object pool from vtpooldata.iop");
}
virtualTerminalClient->set_object_pool(0, isobus::VirtualTerminalClient::VTVersion::Version3, iopStart, objectPoolSize); I think this should work in your case as well! I hope this helps! 😄 |
Beta Was this translation helpful? Give feedback.
-
Hi guys, I made it work a while ago. Now that I understand a bit more of the code, I'll leave here my experience with your library :) void IsobusPP_vInit(void)
{
InitializeEnumCases();
if(xTaskCreate(taskIsobusPP, "IsobusPP", 5000, NULL, TASK_ISOBUS_PP_PRIORITY, NULL) != pdTRUE)
{
ESP_LOGE(TAG, "Failed to create IsobusPP task!");
}
} The function static void taskIsobusPP(void* pvParameters)
{
//==========CONFIG INIT START========
std::shared_ptr<CANHardwarePlugin> canDriver = nullptr;
#if defined(ISOBUS_TWAI_AVAILABLE)
canDriver = std::make_shared<TWAIPlugin>(&g_config, &t_config_250K, &f_config);
#endif
if (nullptr == canDriver)
{
ESP_LOGE(TAG, "Unable to find a CAN driver. Please make sure you have one of the drivers installed with the library.");
}
isobus::CANStackLogger::set_can_stack_logger_sink(&logger);
isobus::CANStackLogger::set_log_level(isobus::CANStackLogger::LoggingLevel::Debug); // Change this to Debug to see more information
CANHardwareInterface::set_number_of_can_channels(1);
CANHardwareInterface::assign_can_channel_frame_handler(0, canDriver);
.
.
. In this first part above, I set the CAN driver to work with the twai interface, as it was already being used in others parts of my code. It's important to set the values of static twai_timing_config_t t_config_250K = TWAI_TIMING_CONFIG_250KBITS();
// static twai_timing_config_t t_config_500K = TWAI_TIMING_CONFIG_500KBITS();
static twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
static twai_general_config_t g_config = {
.mode = TWAI_MODE_LISTEN_ONLY,
.tx_io = GPIO_NUM_NC,
.rx_io = GPIO_NUM_NC,
.clkout_io = TWAI_IO_UNUSED,
.bus_off_io = TWAI_IO_UNUSED,
.tx_queue_len = 16,
.rx_queue_len = 32,
.alerts_enabled = (TWAI_ALERT_ALL & ~(TWAI_ALERT_TX_IDLE | TWAI_ALERT_TX_SUCCESS)),
.clkout_divider = 0,
.intr_flags = 0,
}; Continuing .
.
.
// Enable transceiver
gpio_set_level(xBoardPins.xStandby, 0);
gpio_reset_pin(xBoardPins.xStandby);
gpio_set_direction(xBoardPins.xStandby, GPIO_MODE_OUTPUT);
g_config.rx_io = xBoardPins.xCan1Rx;
g_config.tx_io = xBoardPins.xCan1Tx;
g_config.mode = TWAI_MODE_NORMAL;
if ((!CANHardwareInterface::start()) || (!canDriver->get_is_valid()))
{
ESP_LOGE(TAG, "Failed to start hardware interface. The CAN driver might be invalid.");
}
CANHardwareInterface::add_can_lib_update_callback(update_CAN_network, nullptr);
CANHardwareInterface::add_raw_can_message_rx_callback(raw_can_glue, nullptr);
std::this_thread::sleep_for(std::chrono::milliseconds(250));
.
.
. Then we define the ISO NAME and load the .
.
.
isobus::NAME DeviceNAME(0);
//! Make sure you change these for your device!!!!
//! This is an example device that is using a manufacturer code that is currently unused at time of writing
DeviceNAME.set_arbitrary_address_capable(true);
DeviceNAME.set_industry_group(1);
DeviceNAME.set_device_class(0);
DeviceNAME.set_function_code(static_cast<std::uint8_t>(isobus::NAME::Function::SteeringControl));
DeviceNAME.set_identity_number(2);
DeviceNAME.set_ecu_instance(0);
DeviceNAME.set_function_instance(0);
DeviceNAME.set_device_class_instance(0);
DeviceNAME.set_manufacturer_code(64);
const std::string &filename = "/outTemplate1.iop";
EmbedFs_File_t xFsFile;
if(EmbedFs_xGetFile(filename.c_str(), &xFsFile) != ESP_OK)
{
ESP_LOGE(TAG, "File '%s' not exist", filename.c_str());
}
else ESP_LOGI(TAG, "File '%s' loaded", filename.c_str());
.
.
.
After this we create the control functions and the VT client to set the objectpool from the .
.
.
const isobus::NAMEFilter filterVirtualTerminal(isobus::NAME::NAMEParameters::FunctionCode, static_cast<std::uint8_t>
(isobus::NAME::Function::VirtualTerminal));
const std::vector<isobus::NAMEFilter> vtNameFilters = { filterVirtualTerminal };
std::shared_ptr<isobus::InternalControlFunction> TestInternalECU = std::make_shared<isobus::InternalControlFunction>
(DeviceNAME, 0x1C, 0);
std::shared_ptr<isobus::PartneredControlFunction> TestPartnerVT = std::make_shared<isobus::PartneredControlFunction>(0,
vtNameFilters);
TestVirtualTerminalClient = std::make_shared<isobus::VirtualTerminalClient>(TestPartnerVT, TestInternalECU);
TestVirtualTerminalClient->set_object_pool(0, isobus::VirtualTerminalClient::VTVersion::Version3, xFsFile.pu8FileData,
xFsFile.u32FileLength);
// auto softKeyListener = TestVirtualTerminalClient->add_vt_soft_key_event_listener(handleVTKeyEvents);
auto buttonListener = TestVirtualTerminalClient->add_vt_button_event_listener(handleVTKeyEvents);
auto changeStringListener = TestVirtualTerminalClient->add_vt_change_string_value_event_listener(handleVTChangeStringEvents);
if (0 == xFsFile.u32FileLength)
{
ESP_LOGE(TAG, "Failed to load object pool from outTemplate1.iop");
}
else
{
TestVirtualTerminalClient->initialize(true);
}
//==========CONFIG INIT END==========
esp_task_wdt_reset();
vTaskDelay(pdMS_TO_TICKS(100));
std::this_thread::sleep_for(std::chrono::milliseconds(20000));
while(1)
{
// CAN stack runs in other threads. Do nothing forever.
ESP_LOGW(TAG, "10 segundos para alarme");
std::this_thread::sleep_for(std::chrono::milliseconds(15000));
// TestVirtualTerminalClient->send_change_active_mask(WorkingSet_0, amAlarme);
}
TestVirtualTerminalClient->terminate();
CANHardwareInterface::stop();
// Remove this task from watchdog
esp_task_wdt_delete(NULL);
} // end of taskIsobusPP And that is it :) I'll be leaving the code here if I wasn't clear in my explanations. Thanks for the support @ad3154 and @GwnDaan !!!! I wish a good luck to both of you, and please continue with the good work!! |
Beta Was this translation helpful? Give feedback.
Hi guys, I made it work a while ago. Now that I understand a bit more of the code, I'll leave here my experience with your library :)
My objective here was to create a task capable of sending objectpools and dealing with the TCs. So basically my
main.c
runs this function to start up the task:The function
taskIsobusPP
is declared asstatic void taskIsobusPP(void* pvParameters)
, and it is basically the same main function of the examples, with only…