Skip to content

Commit

Permalink
get_session_status, additional callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
RainerZ committed Sep 4, 2024
1 parent 878576c commit e47d1af
Show file tree
Hide file tree
Showing 26 changed files with 233 additions and 615 deletions.
7 changes: 2 additions & 5 deletions CANape/xcp_lite_autodetect.a2l
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@

/end DAQ

/begin XCP_ON_UDP_IP 0x104 5555 ADDRESS "192.168.179.2" /end XCP_ON_UDP_IP
/begin XCP_ON_UDP_IP 0x104 5555 ADDRESS "172.19.11.24" /end XCP_ON_UDP_IP

/end IF_DATA

Expand Down Expand Up @@ -220,11 +220,8 @@
/begin MEASUREMENT mainloop_map "2D map on heap" A_UINT64 NO_COMPU_METHOD 0 0 0 1000000000000 PHYS_UNIT "" ECU_ADDRESS 0x10000 ECU_ADDRESS_EXTENSION 2 MATRIX_DIM 16 16 /begin IF_DATA XCP /begin DAQ_EVENT FIXED_EVENT_LIST EVENT 1 /end DAQ_EVENT /end IF_DATA /end MEASUREMENT

/begin GROUP mainloop "" /begin REF_MEASUREMENT mainloop_counter1 mainloop_counter2 /end REF_MEASUREMENT /end GROUP
/begin GROUP mainloop_map "" /begin REF_MEASUREMENT mainloop_map /end REF_MEASUREMENT /end GROUP
/begin GROUP static_event "" /begin REF_MEASUREMENT /end REF_MEASUREMENT /end GROUP
/begin GROUP task1 "" /begin REF_MEASUREMENT array1 counter counter_u16 counter_u32 counter_u64 counter_u8 /end REF_MEASUREMENT /end GROUP
/begin GROUP task2_inst "" /begin REF_MEASUREMENT channel_1 channel_2 channel_3 channel_4 channel_5 channel_6 channel_7 channel_8 channel_9 /end REF_MEASUREMENT /end GROUP
/begin GROUP task2_static "" /begin REF_MEASUREMENT channel /end REF_MEASUREMENT /end GROUP
/begin GROUP task2_inst "" /begin REF_MEASUREMENT channel_1 channel_2 channel_3 channel_4 channel_5 channel_6 channel_7 channel_8 channel_9 /end REF_MEASUREMENT /end GROUP

/end MODULE
/end PROJECT
Expand Down
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ derive_builder = "0.20.0"
# Raw FFI bindings to platform libraries like libc
libc = "0.2.153"

# A macro to generate structures which behave like bitflags
bitflags = "2.6.0"

# Logging
log = "0.4.21"
env_logger = "0.11.3"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,13 @@ fn task(calseg: CalSeg<CalPage>) {
fn main() {

// Initialize XCP driver singleton, the transport layer UDP and enable the automatic A2L writer and upload
XcpBuilder::new("xcp_lite").set_log_level(XcpLogLevel::Warn).enable_a2l(true).set_epk("???")
let xcp = XcpBuilder::new("xcp_lite").set_log_level(XcpLogLevel::Warn).enable_a2l(true).set_epk("???")
.start_server(XcpTransportLayer::Udp,[127, 0, 0, 1],5555, 1400,).unwrap();

// Create a calibration parameter set named "calsseg" (struct CalSeg, a MEMORY_SEGMENT in A2L and CANape)
// Calibration segments have 2 pages, a constant default "FLASH" page (CAL_PAGE) and a mutable "RAM" page
// The RAM page can be loaded from a json file (load_json=true)
let calseg = Xcp::create_calseg(
let calseg = xcp.create_calseg(
"calseg", // name of the calibration segment in A2L as MEMORY_SEGMENT and as .json file
&CAL_PAGE, // default calibration values
true, // load RAM page from file "cal_seg1".json
Expand Down
49 changes: 24 additions & 25 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,30 @@ fn main() {
// Generate XCPlite C code bindings
// Uncomment this to regenerate the bindings

// let bindings = bindgen::Builder::default()
// .header("xcplib/wrapper.h")
// .clang_arg("-Ixcplib/src")
// .clang_arg("-Ixcplib")
// // Tell cargo to invalidate the built crate whenever any of the included header files changed.
// .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
// //
// .blocklist_type("T_CLOCK_INFO")
// .allowlist_function("XcpInit")
// .allowlist_function("XcpEvent")
// .allowlist_function("XcpEventExt")
// .allowlist_function("XcpPrint")
// .allowlist_function("XcpEthServerInit")
// .allowlist_function("XcpEthServerShutdown")
// .allowlist_function("XcpEthServerStatus")
// .allowlist_function("ApplXcpSetLogLevel")
// .allowlist_function("ApplXcpSetA2lName")
// .allowlist_function("ApplXcpGetAddr")
// .allowlist_function("ApplXcpRegisterCallbacks")
// //
// .generate()
// .expect("Unable to generate bindings");
// bindings
// .write_to_file("src/xcplite.rs")
// .expect("Couldn't write bindings!");
let bindings = bindgen::Builder::default()
.header("xcplib/wrapper.h")
.clang_arg("-Ixcplib/src")
.clang_arg("-Ixcplib")
// Tell cargo to invalidate the built crate whenever any of the included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
//
.blocklist_type("T_CLOCK_INFO")
.allowlist_function("XcpInit")
.allowlist_function("XcpGetSessionStatus")
.allowlist_function("XcpEvent")
.allowlist_function("XcpEventExt")
.allowlist_function("XcpPrint")
.allowlist_function("XcpEthServerInit")
.allowlist_function("XcpEthServerShutdown")
.allowlist_function("XcpEthServerStatus")
.allowlist_function("ApplXcpSetLogLevel")
.allowlist_function("ApplXcpSetA2lName")
.allowlist_function("ApplXcpGetAddr")
.allowlist_function("ApplXcpRegisterCallbacks")
//
.generate()
.expect("Unable to generate bindings");
bindings.write_to_file("src/xcplite.rs").expect("Couldn't write bindings!");

// Build a XCP on ETH version of XCPlite as a library
Build::new()
Expand Down
4 changes: 2 additions & 2 deletions examples/hello_xcp/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ fn main() {

env_logger::Builder::new().filter_level(log::LevelFilter::Debug).init();

XcpBuilder::new("xcp_demo")
let xcp = XcpBuilder::new("xcp_demo")
.set_log_level(XcpLogLevel::Debug)
.enable_a2l(true)
.set_epk("EPK_")
.start_server(XcpTransportLayer::Udp, [127, 0, 0, 1], 5555, 1464)
.unwrap();

let calseg = Xcp::create_calseg("calseg", &CAL_PAGE, true);
let calseg = xcp.create_calseg("calseg", &CAL_PAGE, true);

let mut counter: u16 = calseg.min;

Expand Down
2 changes: 1 addition & 1 deletion examples/multi_thread_demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ fn main() {
// Calibration segments have 2 pages, a constant default "FLASH" page and a mutable "RAM" page
// FLASH or RAM can be selected runtime (XCP set_cal_page), saves to json (XCP freeze) freeze, reinitialized from FLASH (XCP copy_cal_page)
// RAM page can be loaded from json in new
let calseg = Xcp::create_calseg(
let calseg = xcp.create_calseg(
"calseg", // name of the calibration segment and the .json file
&CAL_PAGE, // default calibration values
true, // load RAM page from file "cal_seg1".json
Expand Down
2 changes: 1 addition & 1 deletion examples/point_cloud_demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ fn main() {
.start_server(XcpTransportLayer::Udp, BIND_ADDR, 5555, 8000 - 20 - 8)
.unwrap();

let params = Xcp::create_calseg("Params", &PARAMS, true);
let params = xcp.create_calseg("Params", &PARAMS, true);

let mut point_cloud = create_point_cloud();
let mut event_point_cloud = daq_create_event!("point_cloud", POINT_COUNT * 12 + 8);
Expand Down
2 changes: 1 addition & 1 deletion examples/rayon_demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ fn main() {
.start_server(XcpTransportLayer::Udp, BIND_ADDR, 5555, 8000 - 20 - 8)
.unwrap();

let mandelbrot = Xcp::create_calseg("mandelbrot", &MANDELBROT, true);
let mandelbrot = xcp.create_calseg("mandelbrot", &MANDELBROT, true);

// The pixel array on heap
let mut pixels = vec![0; X_RES * Y_RES];
Expand Down
2 changes: 1 addition & 1 deletion examples/scoped_threads/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn main() {
.start_server(XcpTransportLayer::Udp, [127, 0, 0, 1], 5555, 1464)
.unwrap();

let calseg = Xcp::create_calseg("calseg", &CAL_PAGE, true);
let calseg = xcp.create_calseg("calseg", &CAL_PAGE, true);

thread::scope(|s| {
for _ in 0..2 {
Expand Down
2 changes: 1 addition & 1 deletion examples/single_thread_demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ fn main() {
// FLASH or RAM can be switched during runtime (XCP set_cal_page), saved to json (XCP freeze) freeze, reinitialized from FLASH (XCP copy_cal_page)
// The RAM page can be reloaded from a json file (load_json==true)
// If A2L is enabled (enable_a2l), the A2L description will be generated and provided for upload by CANape
let calseg = Xcp::create_calseg(
let calseg = xcp.create_calseg(
"calseg", // name of the calibration segment and the .json file
&CAL_PAGE, // default calibration values
true, // load RAM page from file "cal_seg".json
Expand Down
29 changes: 14 additions & 15 deletions src/cal/cal_seg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ mod cal_tests {

#[test]
fn test_calibration_segment_basics() {
xcp_test::test_setup(log::LevelFilter::Info);
let xcp = xcp_test::test_setup(log::LevelFilter::Info);

is_sync::<Xcp>();
is_sync::<XcpEvent>();
Expand All @@ -529,7 +529,7 @@ mod cal_tests {
const CAL_PAGE: CalPage0 = CalPage0 { stop: true };

// Intended use
let cal_seg1 = Xcp::create_calseg("calseg1", &CAL_PAGE, false);
let cal_seg1 = xcp.create_calseg("calseg1", &CAL_PAGE, false);
cal_seg1.sync();
assert!(cal_seg1.stop);
let c1 = CalSeg::clone(&cal_seg1);
Expand Down Expand Up @@ -559,7 +559,7 @@ mod cal_tests {
const CAL_PAGE2: CalPage4 = CalPage4 { test: 0x55 }; // FLASH
let cal_page2 = CalPage4 { test: 0xAA }; // RAM
cal_page2.save_to_file("calseg2.json");
let cal_seg2 = Xcp::create_calseg("calseg2", &CAL_PAGE2, true);
let cal_seg2 = xcp.create_calseg("calseg2", &CAL_PAGE2, true);
Xcp::get().set_ecu_cal_page(XcpCalPage::Ram);
let r = &cal_seg2.test;
assert_eq!(*r, 0xAA); // RAM page
Expand Down Expand Up @@ -605,7 +605,7 @@ mod cal_tests {
mut_page.save_to_file("test_cal_seg.json");

// Create a cal_seg with a mut_page from file test_cal_seg.json aka CAL_PAR_RAM, and a default page from CAL_PAR_FLASH
let cal_seg = &Xcp::create_calseg("test_cal_seg", &CAL_PAR_FLASH, true);
let cal_seg = &xcp.create_calseg("test_cal_seg", &CAL_PAR_FLASH, true);
let cal_seg1 = cal_seg.clone();
let cal_seg2 = cal_seg.clone();

Expand Down Expand Up @@ -681,7 +681,7 @@ mod cal_tests {
let mut_page: CalPage2 = CalPage2 { a: 1, b: 3, c: 5 };
mut_page.save_to_file("test1.json");
mut_page.save_to_file("test2.json");
let cal_seg = Xcp::create_calseg("test1", &FLASH_PAGE2, true); // active page is RAM from test1.json
let cal_seg = xcp.create_calseg("test1", &FLASH_PAGE2, true); // active page is RAM from test1.json
assert_eq!(xcp.get_ecu_cal_page(), XcpCalPage::Ram, "XCP should be on RAM page here, there is no independant page switching yet");
test_is_mut!(cal_seg); // Default page must be mut_page
xcp.set_ecu_cal_page(XcpCalPage::Flash); // Simulate a set cal page to default from XCP master
Expand Down Expand Up @@ -713,8 +713,7 @@ mod cal_tests {
// @@@@ Bug: Test fails occasionally
#[test]
fn test_cal_page_freeze() {
xcp_test::test_setup(log::LevelFilter::Warn);
let _xcp = Xcp::get();
let xcp = xcp_test::test_setup(log::LevelFilter::Warn);

assert!(std::mem::size_of::<CalPage1>() == 12);
assert!(std::mem::size_of::<CalPage2>() == 12);
Expand All @@ -724,7 +723,7 @@ mod cal_tests {
mut_page1.save_to_file("test1.json");

// Create calseg1 from def
let calseg1 = Xcp::create_calseg("test1", &FLASH_PAGE1, true);
let calseg1 = xcp.create_calseg("test1", &FLASH_PAGE1, true);
test_is_mut!(calseg1);

// Freeze calseg1 to new test1.json
Expand All @@ -734,7 +733,7 @@ mod cal_tests {

// Create calseg2 from freeze file test1.json of calseg1
std::fs::copy("test1.json", "test2.json").unwrap();
let calseg2 = Xcp::create_calseg("test2", &FLASH_PAGE2, true);
let calseg2 = xcp.create_calseg("test2", &FLASH_PAGE2, true);
test_is_mut!(calseg2);

std::fs::remove_file("test1.json").ok();
Expand All @@ -746,7 +745,7 @@ mod cal_tests {

#[test]
fn test_cal_page_trait() {
xcp_test::test_setup(log::LevelFilter::Info);
let xcp = xcp_test::test_setup(log::LevelFilter::Info);

#[derive(Debug, Copy, Clone, Serialize, Deserialize, XcpTypeDescription)]
struct Page1 {
Expand All @@ -767,9 +766,9 @@ mod cal_tests {

const PAGE3: Page3 = Page3 { c: 1 };

let s1 = &Xcp::create_calseg("test1", &PAGE1, true);
let s2 = &Xcp::create_calseg("test2", &PAGE2, true);
let s3 = &Xcp::create_calseg("test3", &PAGE3, true);
let s1 = &xcp.create_calseg("test1", &PAGE1, true);
let s2 = &xcp.create_calseg("test2", &PAGE2, true);
let s3 = &xcp.create_calseg("test3", &PAGE3, true);

info!("s1: {}", s1.get_name());
info!("s2: {}", s2.get_name());
Expand Down Expand Up @@ -814,7 +813,7 @@ mod cal_tests {

#[test]
fn test_attribute_macros() {
xcp_test::test_setup(log::LevelFilter::Info);
let xcp = xcp_test::test_setup(log::LevelFilter::Info);

#[derive(Debug, Copy, Clone, Serialize, Deserialize, XcpTypeDescription)]
struct CalPage {
Expand Down Expand Up @@ -843,7 +842,7 @@ mod cal_tests {
],
};

let calseg = &Xcp::create_calseg("calseg", &CAL_PAGE, false);
let calseg = xcp.create_calseg("calseg", &CAL_PAGE, false);
let c: RegistryCharacteristic = Xcp::get().get_registry().lock().unwrap().find_characteristic("CalPage.a").unwrap().clone();

assert_eq!(calseg.get_name(), "calseg");
Expand Down
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub use xcp::XcpBuilder;
pub use xcp::XcpCalPage;
pub use xcp::XcpEvent;
pub use xcp::XcpLogLevel;
pub use xcp::XcpSessionStatus;
pub use xcp::XcpTransportLayer;

// Submodule cal
Expand Down Expand Up @@ -134,9 +135,9 @@ macro_rules! daq_register_static {
#[macro_export]
macro_rules! xcp_println {
( $fmt:expr ) => {
Xcp::print(&format!($fmt));
Xcp::get().print(&format!($fmt));
};
( $fmt:expr, $( $arg:expr ),* ) => {
Xcp::print(&format!($fmt, $( $arg ),*));
Xcp::get().print(&format!($fmt, $( $arg ),*));
};
}
18 changes: 13 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ fn main() {
// The initial RAM page can be loaded from a json file (load_json=true) or set to the default FLASH page (load_json=false)

// Create a alibration segment wrapper for CAL_PAGE, add fields manually to registry
let calseg = Xcp::add_calseg(
let calseg = xcp.add_calseg(
"CalPage", // name of the calibration segment and the .json file
&CAL_PAGE, // default calibration values with static lifetime, trait bound from CalPageTrait must be possible
);
Expand All @@ -408,8 +408,8 @@ fn main() {
.add_field(calseg_field!(CAL_PAGE.cycle_time_us, "us", "main task cycle time"));

// Create calibration segments for CAL_PAGE1 and CAL_PAGE2, add fields with macro derive(XcpTypeDescription))
let calseg1 = Xcp::create_calseg("CalPage1", &CAL_PAGE1, true);
let calseg2 = Xcp::create_calseg("CalPage2", &CAL_PAGE2, true);
let calseg1 = xcp.create_calseg("CalPage1", &CAL_PAGE1, true);
let calseg2 = xcp.create_calseg("CalPage2", &CAL_PAGE2, true);

// Task2 - 9 instances
// To demonstrate the difference between single instance and multi instance events and measurement values
Expand Down Expand Up @@ -449,6 +449,7 @@ fn main() {
daq_register_static!(static_vars.test_u32, static_event, "Test static u32");
daq_register_static!(static_vars.test_f64, static_event, "Test static f64");

let mut current_session_status = xcp.get_session_status();
while RUN.load(Ordering::Acquire) {
// @@@@ Dev: Terminate mainloop for shutdown if calibration parameter run is false, for test automation
if !calseg.run {
Expand Down Expand Up @@ -480,11 +481,18 @@ fn main() {

// Check if the XCP server is still alive
// Optional
if !Xcp::check_server() {
if !xcp.check_server() {
warn!("XCP server shutdown!");
break;
}

// Check if the XCP session status has changed and print info
let session_status = xcp.get_session_status();
if session_status != current_session_status {
info!("XCP session status: {:?}", session_status);
current_session_status = session_status;
}

// @@@@ Dev:
// Finalize A2l after 2s delay
// This is just for testing, to force immediate creation of A2L file
Expand Down Expand Up @@ -514,5 +522,5 @@ fn main() {
info!("All tasks finished");

// Stop and shutdown the XCP server
Xcp::stop_server();
xcp.stop_server();
}
Loading

0 comments on commit e47d1af

Please sign in to comment.