Engee documentation

CAN software control

This page contains all the available CAN software control functions in Engee.

To work with the CAN software control functions in Engee. install the hardware support package as specified in article. After installation, run:

using Main.EngeeDeviceManager.Devices.CAN

Next, you need to create a CAN object.:

CAN.Can()
CAN.bus_status(device, channel::String)->Int64

Состояние шины:

  • 0 — ошибок нет;

  • ненулевое значение — ошибка.

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

  • channel::String: идентификатор канала (например, "can0", "virtual_0").

CAN.close(device)

Закрытие CAN-объекта и освобождение ресурсов.

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

CAN.create_bus(device, interface::String, channel::String, kbits::Float64, auto_reset::Bool, is_fd::Bool=false, data_kbits::Float64=0.0, timing=nothing)

Создает и активирует шину CAN с заданными настройками.

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

  • interface::String: тип интерфейса ("socketcan", "pcan", "marathon", "virtual").

  • channel::String: идентификатор канала (например, "can0", "virtual_0").

  • kbits::Float64: скорость передачи в кбит/с.

  • auto_reset::Bool: автоматический перезапуск при ошибках;

  • is_fd::Bool: использовать ли CAN FD (опционально, по умолчанию false);

  • data_kbits::Float64: скорость для CAN FD (опционально, по умолчанию 0.0);

  • timing::Union{Nothing, CanFdTiming, CanTiming}: дополнительные параметры тайминга (опционально, по умолчанию Nothing).

CAN.destroy_bus(device, channel::String)

Останавливает и удаляет шину CAN.

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

  • channel::String: идентификатор канала (например, "can0", "virtual_0").

CAN.get_tx_rx_errors(device, channel::String)->Vector{Int64}

Возвращает вектор количества ошибок при приеме и передаче [tx_errors, rx_errors].

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

  • channel::String: идентификатор канала (например, "can0", "virtual_0").

CAN.recv(device, channel::String, timeout::Float64, async_rpc::Bool=false)->Union{Nothing, CanMessage}

Прием одного сообщения с таймаутом в секундах. Возвращает Nothing, если сообщений нет.

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

  • channel::String: идентификатор канала (например, "can0", "virtual_0").

  • timeout::Float64: таймаут в секундах.

  • async_rpc::Bool: опционально, по умолчанию false. Если true, прием выполняется асинхронно.

CAN.reset(device, channel::String)

Перезапуск интерфейса (восстановление после Bus-off).

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

  • channel::String: идентификатор канала (например, "can0", "virtual_0").

CAN.send(device, channel::String, message::CanMessage, async_rpc::Bool=false)

Отправка CAN-сообщения.

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

  • channel::String: идентификатор канала (например, "can0", "virtual_0").

  • message::CanMessage: отправляемое CAN-сообщение.

  • async_rpc::Bool: опционально, по умолчанию false. Если true, отправка выполняется асинхронно, вызов неблокирующий.

CAN.set_bus_settings(device, interface::String, channel::String, kbits::Float64, auto_reset::Bool, is_fd::Bool=false, data_kbits::Float64=0.0, timing=nothing)

Конфигурирует CAN-интерфейс до создания шины.

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

  • interface::String: тип интерфейса ("socketcan", "pcan", "marathon", "virtual").

  • channel::String: идентификатор канала (например, "can0", "virtual_0").

  • kbits::Float64: скорость передачи в кбит/с.

  • auto_reset::Bool: автоматический перезапуск при ошибках;

  • is_fd::Bool: использовать ли CAN FD (опционально, по умолчанию false);

  • data_kbits::Float64: скорость для CAN FD (опционально, по умолчанию 0.0);

  • timing::Union{Nothing, CanFdTiming, CanTiming}: дополнительные параметры тайминга (опционально, по умолчанию Nothing).

CAN.set_filters(device, channel::String, filter_id::Int64, mask::Int64)

Аппаратный фильтр приема по arbitration ID. Фильтр (0, 0) принимает все сообщения.

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

  • channel::String: идентификатор канала (например, "can0", "virtual_0").

  • filter_id::Int64: идентификатор фильтра.

  • mask::Int64: маска, определяющая, какие биты arbitration ID должны совпадать.

CAN.start_stream(device, channel::String, sample_time::Float64=0.01)->Tuple{String, String}

Запуск потокового приема с заданным шагом. Возвращает имена очередей для AMQPStream.

Аргументы

  • device::Main.EngeeDeviceManager.Devices.CAN.CanType: объект устройства CAN.

  • channel::String: идентификатор канала (например, "can0", "virtual_0").

  • sample_time::Float64: шаг для запуска приема (опционально, по умолчанию 0.01)

Structure of the CAN message

Base.@kwdef struct CanMessage
    timestamp::Float64          # метка времени
    arbitration_id::Int64       # ID сообщения (11 или 29 бит)
    is_extended_id::UInt8       # 1 — 29-битный ID
    is_remote_frame::UInt8      # 1 — RTR
    is_error_frame::UInt8       # 1 — кадр ошибки
    is_fd::UInt8                # 1 — CAN FD
    bitrate_switch::UInt8       # 1 — переключение скорости
    error_state_indicator::UInt8
    dlc::Int64                  # длина данных (0–8 Classic, 0–64 FD)
    data::Union{Vector{UInt8}, Int64}
end

Examples

Interface virtual

can = CAN.Can()

CAN.set_bus_settings(can, "virtual", "virtual_0", 500.0, true)
CAN.set_bus_settings(can, "virtual", "virtual_1", 500.0, true)
CAN.create_bus(can, "virtual", "virtual_0", 500.0, true)
CAN.create_bus(can, "virtual", "virtual_1", 500.0, true)
CAN.set_filters(can, "virtual_0", 0, 0)

data_field = rand(UInt8, 8)
message = CanMessage(
    timestamp = rand(Float64),
    arbitration_id = rand(UInt32),
    is_extended_id = 0,
    is_remote_frame = 0,
    is_error_frame = 0,
    is_fd = 0,
    bitrate_switch = 0,
    error_state_indicator = 0,
    dlc = length(data_field),
    data = data_field,
)

CAN.send(can, "virtual_0", message, true)
msg = CAN.recv(can, "virtual_1", 0.0)
println("Отправлено: $data_field")
println("Получено:   $(msg.data)")

CAN.destroy_bus(can, "virtual_0")
CAN.close(can)

CAN FD

CAN.set_bus_settings(can, "socketcan", "can0", 500.0, true, true, 2000.0)
CAN.create_bus(can, "socketcan", "can0", 500.0, true, true, 2000.0)

fd_message = CanMessage(
    timestamp = time(), arbitration_id = 0x123,
    is_extended_id = 0, is_remote_frame = 0, is_error_frame = 0,
    is_fd = 1, bitrate_switch = 1, error_state_indicator = 0,
    dlc = 64, data = rand(UInt8, 64),
)
CAN.send(can, "can0", fd_message)