Comments (10)
I solved it myself, I omitted iso15765_enqueue()
in description, now it is working without problem, I am able send and receive packets.
Thank you anyway.
from iso15765-canbus.
@devcoons
Reduced polling to 5ms, added some 50ms timeout after sending a CAN command and now everything is working as expected now, thank you for the help!
from iso15765-canbus.
hey @juicebox-evse, i think i have the exact same question as you, can you please check my logic and tell me if it is the correct flow.
I am trying to just send a simple OBD2 command to read the rpm.
So first:
n_req_t frame =
{
.n_ai.n_pr = 0x06, // Network Address Priority
.n_ai.n_sa = 0x7DF, // Network Source Address
.n_ai.n_ta = 0x7E8, // Network Target Address
.n_ai.n_ae = 0x00, // Network Address Extension
.n_ai.n_tt = N_TA_T_PHY, // Network Target Address type
.fr_fmt = CBUS_FR_FRM_STD, // CANFD or CANSTD
.msg = {0x02,0x01,0x0C},
.msg_sz = 3, // Message size
};
iso15765_send(&handler, &frame);
Then I get to send_frame so:
static uint8_t send_frame(cbus_id_type id_type, uint32_t id, cbus_fr_format fr_fmt, uint8_t dlc, uint8_t* dt)
{
// my driver
// CAN_TransmitMessage
// CAN_ReceiveMessage
// Transform my received message to canbus_frame_t and enqueue
canbus_frame_t frame = { .id = 0x7E8, .dlc = 8, .id_type = CBUS_ID_T_STANDARD, .fr_format= CBUS_FR_FRM_STD, .dt = { 0x04, 0x41, 0x0C, 0x0B, 0x68, 0xCC, 0xCC, 0xCC}};
iso15765_enqueue(&handler, &frame);
return 0;
}
And then I should be getting something in usdata_indication callback (Unfortunately I dont)?
Is my approach correct or am I missing something?
Thanks!
from iso15765-canbus.
hey @juicebox-evse, i think i have the exact same question as you, can you please check my logic and tell me if it is the correct flow. I am trying to just send a simple OBD2 command to read the rpm. So first:
n_req_t frame = { .n_ai.n_pr = 0x06, // Network Address Priority .n_ai.n_sa = 0x7DF, // Network Source Address .n_ai.n_ta = 0x7E8, // Network Target Address .n_ai.n_ae = 0x00, // Network Address Extension .n_ai.n_tt = N_TA_T_PHY, // Network Target Address type .fr_fmt = CBUS_FR_FRM_STD, // CANFD or CANSTD .msg = {0x02,0x01,0x0C}, .msg_sz = 3, // Message size }; iso15765_send(&handler, &frame);
Then I get to send_frame so:
static uint8_t send_frame(cbus_id_type id_type, uint32_t id, cbus_fr_format fr_fmt, uint8_t dlc, uint8_t* dt) { // my driver // CAN_TransmitMessage // CAN_ReceiveMessage // Transform my received message to canbus_frame_t and enqueue canbus_frame_t frame = { .id = 0x7E8, .dlc = 8, .id_type = CBUS_ID_T_STANDARD, .fr_format= CBUS_FR_FRM_STD, .dt = { 0x04, 0x41, 0x0C, 0x0B, 0x68, 0xCC, 0xCC, 0xCC}}; iso15765_enqueue(&handler, &frame); return 0; }
And then I should be getting something in usdata_indication callback (Unfortunately I dont)? Is my approach correct or am I missing something? Thanks!
Hi! The first part seems to be fine (as long as you are sure about the addresses and the message you want to send.
However, in the send function you should probably use the CAN transmission function of your HAL (the api of you microcontroller). After verifying that, you need to 'enqueue' any incoming frame by placing the following code in your HAL CAN receive callback
....
canbus_frame_t frame = { .id = id, .dlc = dlc, .id_type = id_type, .fr_format= fr_fmt };
memmove(frame.dt, dt, dlc);
iso15765_enqueue(&handler, &frame);
....
Please share some more info to help you on it.
from iso15765-canbus.
hey @devcoons, thank you for the info, i followed your advice and after some debugging it turns out the enqueue function is doing nothing, because it does not pass
if (_queue->first != _queue->next)
I must add that i am trying to compile this with armcc and I am getting errors in the libqueue library about incompatible pointers here https://github.com/devcoons/iso15765-canbus/blob/4233d5f73866dd866ffef922fc50f05ea20c0212/lib/lib_iqueue.c#L62C28-L63C2.
When I try to compile it with gcc I only get warning, not error. However by trying to fix and do casting between these pointers, i might be breaking the queue itself and that's why I cannot enqueue new message and I cannot get my callback fired.
I also get error about the ALIGNMENT macro that cannot be used, so in the end I think the problem is entirely on my end :)
from iso15765-canbus.
hey @devcoons, thank you for the info, i followed your advice and after some debugging it turns out the enqueue function is doing nothing, because it does not pass
if (_queue->first != _queue->next)
I must add that i am trying to compile this with armcc and I am getting errors in the libqueue library about incompatible pointers here https://github.com/devcoons/iso15765-canbus/blob/4233d5f73866dd866ffef922fc50f05ea20c0212/lib/lib_iqueue.c#L62C28-L63C2. When I try to compile it with gcc I only get warning, not error. However by trying to fix and do casting between these pointers, i might be breaking the queue itself and that's why I cannot enqueue new message and I cannot get my callback fired. I also get error about the ALIGNMENT macro that cannot be used, so in the end I think the problem is entirely on my end :)
Hi @mitkodev, i've made a small update in the i_queue library. Please let me know if now it compiles also in armcc. Regarding the ALIGNMENT, i saw that armcc do support the same gcc macro https://developer.arm.com/documentation/dui0472/m/Compiler-specific-Features/--attribute----aligned---variable-attribute?lang=en , but i'll have a deeper look on that.
Can you please confirm that you do more or less the following?
static iso15765_t handler1 =
{
.addr_md = N_ADM_NORMAL,
.fr_id_type = CBUS_ID_T_STANDARD,
.clbs.send_frame = send_frame1,
.clbs.on_error = on_error,
.clbs.get_ms = getms,
.clbs.indn = indn1,
.config.stmin = 0x3,
.config.bs = 0x0f,
.config.n_bs = 100,
.config.n_cr = 3
};
static uint32_t getms()
{
return GetTickCount(); // Replace this with your sys tick (the function requires ms)
}
static void on_error(n_rslt err_type)
{
// printf("ERROR OCCURED!:%04x", err_type); //
}
static void indn1(n_indn_t* info)
{
// Here you will get the ISO TP reply
}
static uint8_t send_frame1(cbus_id_type id_type, uint32_t id, cbus_fr_format fr_fmt, uint8_t dlc, uint8_t* dt)
{
// Here use your hal can library to transmit the frame
return 0;
}
...
...
...
// Put the following code in your HAL CAN Receive Callback (modify appropriately)
{
canbus_frame_t frame = { .id = id, .dlc = dlc, .id_type = id_type, .fr_format = fr_fmt };
memmove(frame.dt, dt, dlc);
iso15765_enqueue(&handler1, &frame);
}
....
....
....
....
....
....
// Run this just once in your main function
iso15765_init(&handler1);
...
...
...
// Your ISO TP transmit message
n_req_t frame1 =
{
.n_ai.n_pr = 0x06, // Network Address Priority
.n_ai.n_sa = 0x7DF, // Network Source Address
.n_ai.n_ta = 0x7E8, // Network Target Address
.n_ai.n_ae = 0x00, // Network Address Extension
.n_ai.n_tt = N_TA_T_PHY, // Network Target Address type
.fr_fmt = CBUS_FR_FRM_STD, // CANFD or CANSTD
.msg = {0x02,0x01,0x0C},
.msg_sz = 3, // Message size
};
iso15765_send(&handler1, &frame1);
....
....
....
// Call this in a loop to process the outcoming/incoming messages.
iso15765_process(&handler1);
from iso15765-canbus.
@devcoons Thank you very much, now the logic is correct and working!! I can send and receive message, especially multipart like the VIN is also working!
I have one small question if this is the intented behaviour:
I have iso15765_processin a separate thread running every 100ms.
In my main thread I iso15765_send two can messages with same source and target address (basically reading OBD2 rpm and speed) every second, but only the message that I iso15765_send first is being sent on the CAN line. Should I wait somehow for process to send the first message before trying to send new message?
Thanks again for the help!
from iso15765-canbus.
@devcoons Thank you very much, now the logic is correct and working!! I can send and receive message, especially multipart like the VIN is also working!
I have one small question if this is the intented behaviour: I have iso15765_processin a separate thread running every 100ms. In my main thread I iso15765_send two can messages with same source and target address (basically reading OBD2 rpm and speed) every second, but only the message that I iso15765_send first is being sent on the CAN line. Should I wait somehow for process to send the first message before trying to send new message?
Thanks again for the help!
Hi @mitkodev! Happy to hear that now it works.
As a suggestion, try to increase speed of the iso15765_process
thread. Keep in mind that this function is actually calling the CAN frame transmission. I usually put this in a normal-low priority thread with a 2ms delay. Especially if you are going to transmit multiframes it requires a fast loop. To help you understand a bit better, think that every time this function gets called it decides to transmit or not a canbus frame (+ if there is an ISO-TP frame to fire the callback etc..) so in case of a multiframe, this function will be required to run multiple times to transmit the complete ISO-TP frame.
Regarding the send, it suppose to send just one ISO-TP per time. So i suppose that if you increase the speed of the thread i've mentioned before, both of your send commands will be successfully executed.
Let me know when you have any results
from iso15765-canbus.
hey @devcoons
i dont want to open new thread cause it't just a simple question :)
in your opinion during the process of enqueued can_frame, is there some data operation that might cause UNALLIGNED memory access (cortex M4)?
Very rarely I get hard fault right after receiving new CAN interrupt with this info:
[MAIN] SCB->BFAR = 0xe000ed38
[MAIN] SCB->MMFAR = 0xe000ed34
[MAIN] SCB->HFSR = 0x40000000
[MAIN] SCB->CFSR = 0x01000400
[MAIN] r0 = 0x2001ffff
[MAIN] r1 = 0x20000cdc
[MAIN] r2 = 0x00000000
[MAIN] r3 = 0xdeaddead
[MAIN] r12 = 0x12121212
[MAIN] lr = 0xfffffffd
[MAIN] pc = 0x0802028a
[MAIN] psr = 0x6100000e
and
0x08020284: 680a .h LDR r2,[r1,#0]
0x08020286: 6002 .` STR r2,[r0,#0]
0x08020288: 6810 .h LDR r0,[r2,#0]
0x0802028a: e8900ff0 .... LDM r0,{r4-r11}
which is cause by the LDM instruction according to internet.
I made sure that even canbus_frame_t use ALIGNMENT attribute, but still happens from time to time.
from iso15765-canbus.
hey @devcoons
i dont want to open new thread cause it't just a simple question :)
in your opinion during the process of enqueued can_frame, is there some data operation that might cause UNALLIGNED memory access (cortex M4)?
Very rarely I get hard fault right after receiving new CAN interrupt with this info:
[MAIN] SCB->BFAR = 0xe000ed38
[MAIN] SCB->MMFAR = 0xe000ed34
[MAIN] SCB->HFSR = 0x40000000
[MAIN] SCB->CFSR = 0x01000400
[MAIN] r0 = 0x2001ffff
[MAIN] r1 = 0x20000cdc
[MAIN] r2 = 0x00000000
[MAIN] r3 = 0xdeaddead
[MAIN] r12 = 0x12121212
[MAIN] lr = 0xfffffffd
[MAIN] pc = 0x0802028a
[MAIN] psr = 0x6100000eand
0x08020284: 680a .h LDR r2,[r1,#0]
0x08020286: 6002 .` STR r2,[r0,#0]
0x08020288: 6810 .h LDR r0,[r2,#0]
0x0802028a: e8900ff0 .... LDM r0,{r4-r11}which is cause by the LDM instruction according to internet.
I made sure that even canbus_frame_t use ALIGNMENT attribute, but still happens from time to time.
Hi @mitkodev !
As long as this is happening only during the interrupt callback, the problem could be in iqueue enqueue function.
Can you reduce the I15765_QUEUE_ELMS
from 64 to 8 or 16 and check if this fault is happening more often?
from iso15765-canbus.
Related Issues (10)
- Multi-node communication HOT 1
- Error in operator precedence in n_pdu_unpack() HOT 3
- The function send_N_PCI_T_FC calls send_frame with wrong parameters HOT 1
- N_UNE_PDU return value in process_in_cf() HOT 2
- From which document can I find the rules for N_AI mapping to 11bit CAN ID? HOT 1
- Bugs? HOT 3
- Implementation in STM32HAL HOT 1
- I think this is written incorrectly HOT 2
- Flow Control Management? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from iso15765-canbus.