DanielMartensson / Open-SAE-J1939

SAE J1939 protocol free to use for embedded systems or PC with CAN-bus
MIT License
455 stars 164 forks source link

problem in Open_SAE_J1939_Listen_For_Messages function #39

Closed payapars closed 9 months ago

payapars commented 9 months ago

The serious problem that the Open_SAE_J1939_Listen_For_Messages function has is the data sending functions. Sending functions must be placed in a while loop.

DanielMartensson commented 9 months ago

What do you mean? @payapars

payapars commented 9 months ago

Using can_delay in callback interrupt to send large data causes the microcontroller to hang. @DanielMartensson

DanielMartensson commented 9 months ago

@payapars why? Send me your code

payapars commented 9 months ago

ENUM_J1939_STATUS_CODES SAE_J1939_Send_Transport_Protocol_Data_Transfer(J1939 *j1939, uint8_t DA){
    uint32_t ID = (0x1CEB << 16) | (DA << 8) | j1939->information_this_ECU.this_ECU_address;
    uint8_t i, j, package[8];
    uint16_t bytes_sent = 0;
    ENUM_J1939_STATUS_CODES status = STATUS_SEND_OK;
    for(i = 1; i <= j1939->this_ecu_tp_cm.number_of_packages; i++) {
        package[0] = i;                                                                     /* Number of package */
        for(j = 0; j < 7; j++){
            if(bytes_sent < j1939->this_ecu_tp_cm.total_message_size){
                package[j+1] = j1939->this_ecu_tp_dt.data[bytes_sent++];                    /* Data that we have collected */
            }else{
                package[j+1] = 0xFF;                                                        /* Reserved */
            }
        }
        status = CAN_Send_Message(ID, package);
        CAN_Delay(100);                                                                     /* Important CAN delay according to standard */
        if(status != STATUS_SEND_OK){
            return status;
        }
    }
    return status;
}

I mean CAN_Delay(100) in this code.

DanielMartensson commented 9 months ago

Have you configured your delay callback? @payapars

payapars commented 9 months ago
void CAN_Delay(uint8_t milliseconds) {
    #if PROCESSOR_CHOICE == STM32
osDelay(milliseconds);

    #elif PROCESSOR_CHOICE == ARDUINO

    #elif PROCESSOR_CHOICE == PIC

    #elif PROCESSOR_CHOICE == AVR

    #elif PROCESSOR_CHOICE == QT_USB

    #elif PROCESSOR_CHOICE == INTERNAL_CALLBACK
    /* Get start time */
    clock_t start_time = clock();

    /* Compute desired duration */
    clock_t desired_duration = (clock_t)(CLOCKS_PER_SEC * milliseconds / 1000);

    /* Wait */
    while ((clock() - start_time) < desired_duration) {
        ;
    }
    #else
    /* Nothing */
    #endif
}

i am using stm32! @DanielMartensson

DanielMartensson commented 9 months ago

@payapars I see. When osDelay is called, your MCU breaks. That's is a memory issue, not a library issue. Have you tried to increase the memory for your thread ?

payapars commented 9 months ago

thanks