Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ if (BUILD_EXECUTABLE STREQUAL "unitTest")
add_subdirectory(libs/bsw/asyncFreeRtos/test)
add_subdirectory(libs/bsw/asyncImpl/examples)
add_subdirectory(libs/bsw/asyncImpl/test)
add_subdirectory(libs/bsw/blob/test)
add_subdirectory(libs/bsw/bsp/test)
add_subdirectory(libs/bsw/cpp2can/test)
add_subdirectory(libs/bsw/cpp2ethernet/test)
Expand All @@ -171,6 +172,7 @@ if (BUILD_EXECUTABLE STREQUAL "unitTest")
add_subdirectory(libs/bsw/lwipSocket/test)
add_subdirectory(libs/bsw/middleware/test)
add_subdirectory(libs/bsw/platform/test)
add_subdirectory(libs/bsw/routing/test)
add_subdirectory(libs/bsw/runtime/test)
add_subdirectory(libs/bsw/storage/test)
add_subdirectory(libs/bsw/timer/test)
Expand Down
4 changes: 3 additions & 1 deletion docker/development/files/requirements.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --output-file=docker/development/files/requirements.lock docker/development/files/requirements.txt test/pyTest/requirements.txt tools/UdsTool/requirements.txt
# pip-compile --output-file=docker/development/files/requirements.lock docker/development/files/requirements.txt test/pyTest/requirements.txt tools/UdsTool/requirements.txt tools/blob/requirements.txt
#
anyio==4.12.0
# via httpx
Expand Down Expand Up @@ -31,6 +31,8 @@ cmakelang==0.6.13
# via -r docker/development/files/requirements.txt
crashtest==0.4.1
# via cleo
crc==7.1.0
# via -r tools/blob/requirements.txt
cryptography==46.0.3
# via secretstorage
distlib==0.4.0
Expand Down
8 changes: 8 additions & 0 deletions executables/referenceApp/application/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ if (PLATFORM_SUPPORT_ETHERNET)
target_sources(app.referenceApp
PRIVATE src/systems/DoIpServerSystem.cpp)
endif ()

if (PLATFORM_SUPPORT_CAN)
target_sources(app.referenceApp PRIVATE src/systems/RoutingSystem.cpp)
endif ()
endif ()

if (PLATFORM_SUPPORT_CAN)
Expand Down Expand Up @@ -103,6 +107,10 @@ if (PLATFORM_SUPPORT_ETHERNET)
if (PLATFORM_SUPPORT_TRANSPORT)
target_link_libraries(app.referenceApp PRIVATE doip)
endif ()

if (PLATFORM_SUPPORT_CAN)
target_link_libraries(app.referenceApp PRIVATE blob routing)
endif ()
endif ()

if (PLATFORM_SUPPORT_STORAGE)
Expand Down
187 changes: 187 additions & 0 deletions executables/referenceApp/application/include/systems/RoutingSystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/********************************************************************************
* Copyright (c) 2022 Accenture
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

#pragma once

#include "routing/ErrorHandler.h"

#include "systems/ICanSystem.h"

#include <async/util/Call.h>
#include <can/filter/IntervalFilter.h> // pre-integration testing, to be removed later
#include <can/transceiver/AbstractCANTransceiver.h>
#include <io/IReader.h>
#include <io/IWriter.h>
#include <io/MemoryQueue.h>
#include <lifecycle/SimpleLifecycleComponent.h>
#include <lwipSocket/udp/LwipDatagramSocket.h>
#include <routing/Integration.h>
#include <routing/PduTransportIntegration.h>
#include <routing/constants.h>

#include <etl/limits.h>
#include <etl/singleton_base.h>
#include <etl/vector.h>
#include <platform/estdint.h>

namespace systems
{
class RoutingSystem
: public ::etl::singleton_base<RoutingSystem>
, public ::lifecycle::SimpleLifecycleComponent
, private ::async::IRunnable
{
public:
static constexpr auto MAX_NUM_PDU_TRANSPORT_CHANNELS = ::routing::NUM_PDU_TRANSPORT_CHANNELS;
static constexpr auto NUM_FLEXRAY_CHANNELS = ::routing::NUM_FLEXRAY_CHANNELS;
static constexpr auto NUM_CAN_CHANNELS = ::routing::NUM_CAN_CHANNELS;

// Ethernet MTU (1500) - IPv4 header size (20) - UDP header size (8) - space for future protocol
// headers (56)
static constexpr size_t MAX_FRAME_SIZE = 1416U;
static constexpr size_t MAX_PDU_TRANSPORT_CHANNEL_ELEMENT_SIZE = 72U;
static constexpr size_t MAX_CAN_CHANNEL_ELEMENT_SIZE = 72U;
static constexpr size_t MAX_FLEXRAY_CHANNEL_ELEMENT_SIZE = 72U;

RoutingSystem(::async::ContextType context, ::can::ICanSystem& canSystem);

void init() override;
void run() override;
void shutdown() override;

::async::ContextType getTransitionContext(Transition::Type /* transition */) override
{
return _context;
}

private:
static constexpr size_t MAX_CAN_QUEUE_ELEMENT_SIZE = 72U;
static constexpr size_t CAN_QUEUE_SIZE = 2048U;
using CanQueue = ::io::MemoryQueue<CAN_QUEUE_SIZE, MAX_CAN_QUEUE_ELEMENT_SIZE>;
using CanReader = ::io::MemoryQueueReader<CanQueue>;
using CanWriter = ::io::MemoryQueueWriter<CanQueue>;

class CanRxListener final : public ::can::ICANFrameListener
{
public:
CanRxListener(CanWriter& inputWriter) : _canFilter(), _inputWriter(inputWriter)
{
// It will accept any IDs, but Router will filter them.
// Possible optimization: filtering in listener to avoid spamming the input queue.
_canFilter.open();
}

void frameReceived(::can::CANFrame const& frame) override
{
::etl::span<uint8_t> pdu = _inputWriter.allocate(8U + frame.getPayloadLength());
if (pdu.empty())
{
return;
}

pdu.take<::etl::be_uint32_t>() = frame.getId();
pdu.take<::etl::be_uint32_t>() = frame.getPayloadLength();
::etl::copy(
::etl::span<uint8_t const>(frame.getPayload(), frame.getPayloadLength()), pdu);

_inputWriter.commit();
}

::can::IFilter& getFilter() override { return _canFilter; }

private:
::can::IntervalFilter _canFilter;

CanWriter& _inputWriter;
};

class CanOutputWriter final : public ::io::IWriter
{
public:
CanOutputWriter(::can::ICanTransceiver& canTransceiver) : _canTransceiver(canTransceiver) {}

size_t maxSize() const override { return MAX_CAN_QUEUE_ELEMENT_SIZE; }

::etl::span<uint8_t> allocate(size_t size)
{
_currentFrame = ::etl::make_span(_data).first(size);
return _currentFrame;
}

void commit()
{
if (_currentFrame.empty())
{
return;
}

uint32_t id = _currentFrame.take<::etl::be_uint32_t>();
uint32_t length = _currentFrame.take<::etl::be_uint32_t>();
auto payload = _currentFrame;
::can::CANFrame frame(id, payload.data(), length);

// No retry handling
(void)_canTransceiver.write(frame);

_currentFrame = {};
}

void flush() {}

private:
::can::ICanTransceiver& _canTransceiver;

::etl::array<uint8_t, MAX_CAN_QUEUE_ELEMENT_SIZE> _data;
::etl::span<uint8_t> _currentFrame;
};

using Integration = ::routing::Integration<
MAX_NUM_PDU_TRANSPORT_CHANNELS,
NUM_CAN_CHANNELS,
NUM_FLEXRAY_CHANNELS,
MAX_PDU_TRANSPORT_CHANNEL_ELEMENT_SIZE,
MAX_CAN_CHANNEL_ELEMENT_SIZE,
MAX_FLEXRAY_CHANNEL_ELEMENT_SIZE>;
using PduTransportIntegration
= ::routing::PduTransportIntegration<MAX_NUM_PDU_TRANSPORT_CHANNELS, MAX_FRAME_SIZE>;

void execute() override;

void
handleError(::routing::ErrorHandler::StatusCode statusCode, uint8_t channelId, uint32_t data);

bool _initialized;

PduTransportIntegration _pduTransportIntegration;

Integration _integration;

::async::TimeoutType _timeout;

::async::ContextType _context;

::can::ICanSystem& _canSystem;

::etl::vector<::udp::LwipDatagramSocket, MAX_NUM_PDU_TRANSPORT_CHANNELS> _lwipInputSockets;
::etl::vector<::udp::LwipDatagramSocket, MAX_NUM_PDU_TRANSPORT_CHANNELS> _lwipOutputSockets;
::etl::vector<::udp::AbstractDatagramSocket*, MAX_NUM_PDU_TRANSPORT_CHANNELS> _inputSockets;
::etl::vector<::udp::AbstractDatagramSocket*, MAX_NUM_PDU_TRANSPORT_CHANNELS> _outputSockets;

::etl::vector<CanQueue, NUM_CAN_CHANNELS> _canInputQueues;
::etl::vector<CanReader, NUM_CAN_CHANNELS> _canInputReaders;
::etl::vector<CanWriter, NUM_CAN_CHANNELS> _canInputWriters;
::etl::vector<CanRxListener, NUM_CAN_CHANNELS> _canRxListeners;

::etl::vector<CanOutputWriter, NUM_CAN_CHANNELS> _canOutputWriters;

::routing::ErrorHandler::Function _errorHandlingFunction;
};

} // namespace systems
17 changes: 15 additions & 2 deletions executables/referenceApp/application/src/app/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@
#include "systems/DoIpServerSystem.h"
#endif // PLATFORM_SUPPORT_TRANSPORT
#endif // PLATFORM_SUPPORT_ETHERNET
//

#if defined(PLATFORM_SUPPORT_ETHERNET) && defined(PLATFORM_SUPPORT_CAN)
#include "systems/RoutingSystem.h"
#endif // defined(PLATFORM_SUPPORT_ETHERNET) && defined(PLATFORM_SUPPORT_CAN)

#if defined(PLATFORM_SUPPORT_CAN) && defined(PLATFORM_SUPPORT_TRANSPORT)
#include "systems/DoCanSystem.h"
#endif // defined(PLATFORM_SUPPORT_CAN) && defined(PLATFORM_SUPPORT_TRANSPORT)
Expand Down Expand Up @@ -133,6 +137,10 @@ ::etl::typed_storage<::systems::SafetySystem> safetySystem;
::etl::typed_storage<::systems::EthernetSystem> ethernetSystem;
#endif // PLATFORM_SUPPORT_ETHERNET

#if defined(PLATFORM_SUPPORT_ETHERNET) && defined(PLATFORM_SUPPORT_CAN)
::etl::typed_storage<::systems::RoutingSystem> routingSystem;
#endif // defined(PLATFORM_SUPPORT_ETHERNET) && defined(PLATFORM_SUPPORT_CAN)

#ifdef PLATFORM_SUPPORT_TRANSPORT
::etl::typed_storage<::transport::TransportSystem> transportSystem;
#ifdef PLATFORM_SUPPORT_CAN
Expand Down Expand Up @@ -295,7 +303,12 @@ void startApp()
6U);
#endif

/* runlevel 7 */
#if defined(PLATFORM_SUPPORT_ETHERNET) && defined(PLATFORM_SUPPORT_CAN)
lifecycleManager.addComponent(
"routing", routingSystem.create(TASK_ETHERNET, ::systems::getCanSystem()), 6U);
#endif

/* runlevel 7 */
#if defined(PLATFORM_SUPPORT_TRANSPORT) && defined(PLATFORM_SUPPORT_UDS)
lifecycleManager.addComponent(
"uds", udsSystem.create(lifecycleManager, *transportSystem, TASK_UDS, LOGICAL_ADDRESS), 7U);
Expand Down
5 changes: 5 additions & 0 deletions executables/referenceApp/application/src/logger/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ DEFINE_LOGGER_COMPONENT(ETHERNET);
DEFINE_LOGGER_COMPONENT(DOIP);
DEFINE_LOGGER_COMPONENT(UDS);
DEFINE_LOGGER_COMPONENT(LWIP);
DEFINE_LOGGER_COMPONENT(ROUTING);

#include <async/AsyncBinding.h>
#include <console/AsyncCommandWrapper.h>
Expand Down Expand Up @@ -86,6 +87,10 @@ LOGGER_COMPONENT_MAPPING_INFO(_DEBUG, LWIP, ::util::format::Color::LIGHT_YELLOW)
LOGGER_COMPONENT_MAPPING_INFO(_DEBUG, DOIP, ::util::format::Color::LIGHT_GREEN)
#endif // PLATFORM_SUPPORT_TRANSPORT
#endif // PLATFORM_SUPPORT_ETHERNET
#if defined(PLATFORM_SUPPORT_ETHERNET) && defined(PLATFORM_SUPPORT_CAN)
LOGGER_COMPONENT_MAPPING_INFO(_DEBUG, ROUTING, ::util::format::Color::LIGHT_CYAN)
#endif // defined(PLATFORM_SUPPORT_ETHERNET) && defined(PLATFORM_SUPPORT_CAN)

/* end: adding logger components */
END_LOGGER_COMPONENT_MAPPING_INFO_TABLE();

Expand Down
Loading
Loading