Rebase onto main

This commit is contained in:
@CarlWachter 2024-01-01 16:03:21 +01:00
parent d7d7d9aab1
commit 7635cfe4ad
4 changed files with 237 additions and 0 deletions

3
.gitignore vendored
View File

@ -13,3 +13,6 @@ Release/
docs/html
docs/latex
# Config
include/sta/config.hpp

View File

@ -48,6 +48,7 @@ In order to use TACOS, you need to provide a configuration file in the path `sta
#define STA_RTOS_SYSTEM_EVENTS_ENABLE
// #define STA_RTOS_SYSTEM_WATCHDOG_ENABLE
// #define STA_RTOS_WATCHDOG_ENABLE
// #define STA_RTOS_CAN_BUS_ENABLE
// Uses the default configuration for TACOS.
#include<sta/tacos/configs/default.hpp>

View File

@ -0,0 +1,118 @@
#ifndef INCLUDE_TACOS_CAN_BUS_HPP_
#define INCLUDE_TACOS_CAN_BUS_HPP_
#include <sta/config.hpp>
//TODO UNCOMMENT THIS
//#ifdef STA_RTOS_CAN_BUS_ENABLE
#include <sta/tacos/thread.hpp>
#include <sta/rtos/queue.hpp>
#include <sta/debug/assert.hpp>
#include <sta/rtos/system/can_bus.hpp>
/**
* @defgroup tacos_can_bus Can Bus Task
* @ingroup tacos
* @brief Can Bus task for TACOS.
*/
namespace sta
{
namespace tacos
{
/**
* @brief Can Bus implementation for Tacos.
*
* @ingroup tacos_can_bus
*/
class CanBus : public TacosThread
{
public:
/**
* @brief Getter function for the singleton instance.
*/
static CanBus* instance(CAN_HandleTypeDef * handle)
{
static CGuard g;
if (!_instance)
{
// Create the can bus singleton instance.
CanBus::_instance = new CanBus(handle);
}
return _instance;
}
/**
* @brief Place data message in CAN driver TX queue.
*
* @param msg Message to transmit
* @param timeout Timeout for placing message (0 = no wait, osWaitForever = blocking)
* @return True if message was queued successfully
*/
bool queueCanBusMsg(const CanDataMsg & msg, uint32_t timeout);
/**
* @brief Place system message in CAN driver TX queue.
*
* @param msg Message to transmit
* @param timeout Timeout for placing message (0 = no wait, osWaitForever = blocking)
* @return True if message was queued successfully
*/
bool queueCanBusMsg(const CanSysMsg & msg, uint32_t timeout);
/**
* @brief Retrieve data message from CAN driver TX queue.
*
* @param[out] msg Output address for retrieved message
* @param timeout Timeout for retrieving message (0 = no wait, osWaitForever = blocking)
* @return True if message was retrieved successfully
*/
bool getCanBusMsg(CanDataMsg * msg, uint32_t timeout);
/**
* @brief Retrieve system message from CAN driver TX queue.
*
* @param[out] msg Destination for retrieved message
* @param timeout Timeout for retrieving message (0 = no wait, osWaitForever = blocking)
* @return True if message was retrieved successfully
*/
bool getCanBusMsg(CanSysMsg * msg, uint32_t timeout);
private:
static CanBus * _instance;
class CGuard
{
public:
~CGuard()
{
if( NULL != CanBus::_instance )
{
delete CanBus::_instance;
CanBus::_instance = NULL;
}
}
};
RtosQueue<CanDataMsg> canBusDataQueue_;
RtosQueue<CanDataMsg> canBusSysQueue_;
CanDataMsg canBusDataQueueBuffer[queueLength];
CanSysMsg canBusSysQueueBuffer[queueLength];
uint32_t canBusStack[256];
sta::STM32CanController * canBusController_;
const size_t queueLength_;
AlpakaCanBus canBus_;
}
} /* namespace tacos */
} /* namespace sta */
#endif /* STA_RTOS_CAN_BUS_ENABLE */
#endif /* INCLUDE_TACOS_CAN_BUS_HPP_ */

115
src/can_bus.cpp Normal file
View File

@ -0,0 +1,115 @@
#include <sta/tacos/can_bus.hpp>
#include <sta/debug/debug.hpp>
#include <sta/debug/assert.hpp>
namespace sta
{
namespace tacos
{
CanBus::CanBus(CAN_HandleTypeDef * handle)
: TacosThread{"Can Bus", STA_TACOS_CAN_BUS_PRIORITY},
canBusController_{handle},
canBusDataQueueBuffer{nullptr},
canBusSysQueueBuffer{nullptr},
canSysDataQueue_{STA_RTOS_CAN_BUS_QUEUE_LENGTH},
canBusDataQueue_{STA_RTOS_CAN_BUS_QUEUE_LENGTH},
canBus_{&canBusController_, HAL_GetTick, dummy::handleSysMessage, dummy::handleDataMessage}
{
}
void CanBus::init()
{
canBusController_.start();
}
void CanBus::func()
{
uint32_t flags = osThreadFlagsWait(STA_RTOS_THREAD_FLAGS_VALID_BITS, osFlagsWaitAny, 50);
if (flags != static_cast<uint32_t>(osErrorTimeout))
{
STA_ASSERT_MSG((flags & osStatusReserved) == flags, "Unexpected error occurred in wait");
if (flags & STA_RTOS_CAN_FLAG_SYS_QUEUED)
{
// Take messages from queue until empty
CanSysMsg msg;
while (rtos::getCanBusMsg(&msg, 0))
{
canBus_.send(msg);
}
}
if (flags & STA_RTOS_CAN_FLAG_DATA_QUEUED)
{
// Take messages from queue until empty
CanDataMsg msg;
while (rtos::getCanBusMsg(&msg, 0))
{
canBus_.send(msg);
}
}
if (flags & STA_RTOS_CAN_FLAG_MSG_AVAIL)
{
STA_DEBUG_PRINTLN("[event] CAN INT");
canBus_.processRx();
}
if (flags & STA_RTOS_CAN_FLAG_SHOW_STATS)
{
canBus_.showStatistics();
}
}
// Process ISOTP transmissions
canBus.processTx();
}
bool queueCanBusMsg(const CanDataMsg & msg, uint32_t timeout)
{
STA_ASSERT((msg.header.sid & STA_CAN_SID_SYS_BITS) == 0);
STA_ASSERT(msg.header.payloadLength <= sizeof(msg.payload));
if (canBusDataQueue_.put(&msg, timeout))
{
// Signal thread
notify(STA_RTOS_CAN_FLAG_DATA_QUEUED);
return true;
}
else
{
return false;
}
}
bool queueCanBusMsg(const CanSysMsg & msg, uint32_t timeout)
{
STA_ASSERT((msg.header.sid & ~STA_CAN_SID_SYS_BITS) == 0);
if (canBusSysQueue_.put(&msg, timeout))
{
// Signal thread
notify(STA_RTOS_CAN_FLAG_SYS_QUEUED);
return true;
}
else
{
return false;
}
}
bool getCanBusMsg(CanDataMsg * msg, uint32_t timeout)
{
return (osOK == osMessageQueueGet(canBusDataQueueHandle, msg, 0, timeout));
}
bool getCanBusMsg(CanSysMsg * msg, uint32_t timeout)
{
return (osOK == osMessageQueueGet(canBusSysQueueHandle, msg, 0, timeout));
}
} /* namespace tacos */
} /* namespace sta */