Skip to content
Draft
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ function(add_app_subdirectory APP_SUBDIRECTORY)
endfunction()

## Include Rover Apps
add_subdirectory(${ROVER_APPS_DIR}/common)
add_app_subdirectory(${ROVER_APPS_DIR}/arm_2021)
add_app_subdirectory(${ROVER_APPS_DIR}/gamepad_2021)
add_app_subdirectory(${ROVER_APPS_DIR}/gimbal_2021)
Expand Down
1 change: 0 additions & 1 deletion libs/can/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ target_link_libraries(CANInterface
PUBLIC
mbed-os
mbed-events
PRIVATE
uwrt-mars-rover-hw-bridge
CANBus
CANMsg
Expand Down
9 changes: 4 additions & 5 deletions libs/can/include/CANInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class CANInterface {
bool getRXSignalValue(HWBRIDGE::CANID msgID, HWBRIDGE::CANSIGNAL signalName, HWBRIDGE::CANSignalValue_t &signalValue);

// Switch CAN bus
bool switchCANBus(HWBRIDGE::CANBUSID canBusID);
bool switchCANBus(HWBRIDGE::CANBUSID canBusID); // TODO: Unnecessary

// Set CAN bus hw filter
bool setFilter(HWBRIDGE::CANFILTER filter, CANFormat format = CANStandard,
Expand All @@ -51,6 +51,9 @@ class CANInterface {
uint16_t getNumCANRXFaults(void);
uint16_t getNumCANTXFaults(void);

void rxClientPeriodic(void);
void txProcessorPeriodic(void);

private:
static constexpr osPriority RX_POSTMAN_THREAD_PRIORITY = osPriorityRealtime;
static constexpr osPriority RX_CLIENT_THREAD_PRIORITY = osPriorityAboveNormal;
Expand All @@ -60,16 +63,12 @@ class CANInterface {

void rxISR(void);
void rxPostman(void);
void rxClient(void);
void txProcessor(void);

CANBus m_CANBus1;
CANBus m_CANBus2;
CANBus *m_activeCANBus;

Thread m_rxPostmanThread;
Thread m_rxClientThread;
Thread m_txProcessorThread;

Mutex m_rxMutex;
Mutex m_txMutex;
Expand Down
93 changes: 38 additions & 55 deletions libs/can/src/CANInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ CANInterface::CANInterface(const Config &config)
m_CANBus2(config.can2_RX, config.can2_TX, config.frequency_hz),
m_activeCANBus(&m_CANBus1),
m_rxPostmanThread(RX_POSTMAN_THREAD_PRIORITY),
m_rxClientThread(RX_CLIENT_THREAD_PRIORITY),
m_txProcessorThread(TX_PROCESSOR_THREAD_PRIORITY),
m_rxMsgMap(config.rxMsgMap),
m_txMsgMap(config.txMsgMap),
m_rxOneShotMsgHandler(config.rxOneShotMsgHandler),
Expand All @@ -22,8 +20,6 @@ CANInterface::CANInterface(const Config &config)

// Processing threads
m_rxPostmanThread.start(callback(&m_rxEventQueue, &EventQueue::dispatch_forever));
m_rxClientThread.start(callback(this, &CANInterface::rxClient));
m_txProcessorThread.start(callback(this, &CANInterface::txProcessor));

// RX ISR
m_CANBus1.attach(callback(this, &CANInterface::rxISR), CAN::RxIrq);
Expand Down Expand Up @@ -52,18 +48,12 @@ void CANInterface::rxPostman(void) {
can_irq_set(m_activeCANBus->getHandle(), IRQ_RX, true);
}

void CANInterface::rxClient(void) {
while (true) {
CANMsg *mail = nullptr;

// Wait for a message to arrive
do {
mail = m_rxMailbox.try_get(); // using try_get() because try_get_for() was crashing
ThisThread::sleep_for(1ms);
} while (mail == nullptr);

MBED_ASSERT(mail != nullptr);
void CANInterface::rxClientPeriodic(void) {
CANMsg *mail = nullptr;
// Check if a message has arrived:
mail = m_rxMailbox.try_get();

if (mail != nullptr) {
// Extract message
CANMsg msg = *mail;
MBED_ASSERT(m_rxMailbox.free(mail) == osOK);
Expand Down Expand Up @@ -111,52 +101,45 @@ void CANInterface::rxClient(void) {
}
}

void CANInterface::txProcessor(void) {
while (true) {
auto startTime = Kernel::Clock::now();
void CANInterface::txProcessorPeriodic(void) {

CANMsg *mail = nullptr;
CANMsg *mail = nullptr;

// Send all one-shot messages that were queued
while ((mail = m_txMailboxOneShot.try_get()) != nullptr) {
if (!m_activeCANBus->write(*mail)) {
MBED_WARNING(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_WRITE_FAILED), "CAN TX write failed");
m_numCANTXFaults++;
}
MBED_ASSERT(m_txMailboxOneShot.free(mail) == osOK);
ThisThread::sleep_for(TX_INTERDELAY);
// Send all one-shot messages that were queued
while ((mail = m_txMailboxOneShot.try_get()) != nullptr) {
if (!m_activeCANBus->write(*mail)) {
MBED_WARNING(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_WRITE_FAILED), "CAN TX write failed");
m_numCANTXFaults++;
}
MBED_ASSERT(m_txMailboxOneShot.free(mail) == osOK);
}

// Send all streamed messages
if (m_txMsgMap != nullptr) {
for (auto it = m_txMsgMap->begin(); it != m_txMsgMap->end(); it++) {
HWBRIDGE::CANID msgID = it->first;
HWBRIDGE::CANMsgData_t msgData = {0};
size_t len = 0;

m_txMutex.lock();
bool msgPacked = HWBRIDGE::packCANMsg(msgData.raw, msgID, m_txMsgMap, len);
m_txMutex.unlock();

if (msgPacked) {
// Send message
CANMsg msg;
msg.setID(msgID);
msg.setPayload(msgData, len);
m_activeCANBus->write(msg);

m_numStreamedMsgsSent++;

ThisThread::sleep_for(TX_INTERDELAY);
} else {
MBED_WARNING(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_INVALID_DATA_DETECTED),
"CAN TX message packing failed");
m_numCANTXFaults++;
}
// Send all streamed messages
if (m_txMsgMap != nullptr) {
for (auto it = m_txMsgMap->begin(); it != m_txMsgMap->end(); it++) {
HWBRIDGE::CANID msgID = it->first;
HWBRIDGE::CANMsgData_t msgData = {0};
size_t len = 0;

m_txMutex.lock();
bool msgPacked = HWBRIDGE::packCANMsg(msgData.raw, msgID, m_txMsgMap, len);
m_txMutex.unlock();

if (msgPacked) {
// Send message
CANMsg msg;
msg.setID(msgID);
msg.setPayload(msgData, len);
m_activeCANBus->write(msg);

m_numStreamedMsgsSent++;

} else {
MBED_WARNING(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_INVALID_DATA_DETECTED),
"CAN TX message packing failed");
m_numCANTXFaults++;
}
}

ThisThread::sleep_until(startTime + TX_PERIOD);
}
}

Expand Down
9 changes: 3 additions & 6 deletions libs/utility/include/WatchdogWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ namespace Utility {

class WatchdogWrapper {
public:
static void startWatchdog(std::chrono::milliseconds countdown_ms = 5000ms, std::chrono::milliseconds pet_ms = 1000ms);
static void logResetReason();

private:
static void petWatchdog(std::chrono::milliseconds *pet_ms);
static Thread pet_thread;
static void startWatchdog(std::chrono::milliseconds countdown_ms);
static void logResetReason(void);
static void petWatchdog(void);
};
} // namespace Utility
17 changes: 5 additions & 12 deletions libs/utility/src/WatchdogWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@

namespace Utility {

Thread WatchdogWrapper::pet_thread;

void WatchdogWrapper::startWatchdog(std::chrono::milliseconds countdown_ms /*= 5000ms*/,
std::chrono::milliseconds pet_ms /*= 1000ms*/) {
void WatchdogWrapper::startWatchdog(std::chrono::milliseconds countdown_ms) {
uint32_t countdown_uint32 = countdown_ms.count();
Watchdog &watchdog = Watchdog::get_instance();
watchdog.start(countdown_uint32);
pet_thread.start(callback(WatchdogWrapper::petWatchdog, &pet_ms));
}

void WatchdogWrapper::logResetReason() {
void WatchdogWrapper::logResetReason(void) {
const reset_reason_t reason = ResetReason::get();
if (reason == RESET_REASON_WATCHDOG) {
time_t seconds = time(NULL);
Expand All @@ -26,10 +22,7 @@ void WatchdogWrapper::logResetReason() {
}
}

void WatchdogWrapper::petWatchdog(std::chrono::milliseconds *pet_ms) {
while (1) {
Watchdog::get_instance().kick();
ThisThread::sleep_for(*pet_ms);
}
void WatchdogWrapper::petWatchdog(void) {
Watchdog::get_instance().kick();
}
} // namespace Utility
} // namespace Utility
7 changes: 5 additions & 2 deletions rover-apps/arm_2021/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
add_executable(arm_2021)
target_sources(arm_2021 PRIVATE src/main.cpp)
target_include_directories(arm_2021 PUBLIC include)
target_sources(arm_2021 PRIVATE ../common/src/main.cpp)
target_include_directories(arm_2021 PUBLIC include ../common/include)
target_link_libraries(arm_2021
PRIVATE
#Control
Expand All @@ -21,6 +21,9 @@ target_link_libraries(arm_2021
CANMsg
#Sensor
CurrentSensor
#common-modules
WatchdogModule
CANDriverModule
#Other
uwrt-mars-rover-hw-bridge
Logger
Expand Down
17 changes: 17 additions & 0 deletions rover-apps/arm_2021/include/AppConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <vector>

#include "Module.h"
#include "WatchdogModule.h"
#include "CANDriverModule.h"
#include "CANConfig.h"
#include "hw_bridge.h"
#include "CANInterface.h"

WatchdogModule arm_watchdog;

std::vector<Module*> gModules = {
// put modules here
&arm_watchdog,
};
19 changes: 19 additions & 0 deletions rover-apps/common/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
add_library(WatchdogModule STATIC)
target_sources(WatchdogModule PRIVATE src/WatchdogModule.cpp)
target_include_directories(WatchdogModule PUBLIC include)
target_link_libraries(WatchdogModule
PRIVATE
WatchdogWrapper
mbed-os
)

add_library(CANDriverModule STATIC)
target_sources(CANDriverModule PRIVATE src/CANDriverModule.cpp)
target_include_directories(CANDriverModule PUBLIC include)
target_link_libraries(CANDriverModule
PRIVATE
CANInterface
CANMsg
mbed-os
)

44 changes: 44 additions & 0 deletions rover-apps/common/include/CANDriverModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once

#include "CANInterface.h"
#include "Module.h"
#include "mbed.h"
#include "CANBus.h"
#include "CANMsg.h"
#include "hw_bridge.h"
#include "mbed.h"

class CANDriverModule final : public Module {
public:
CANDriverModule(const CANInterface::Config &config);
void periodic_1s(void) override;

void periodic_10s(void) override;
void periodic_100ms(void) override;
void periodic_10ms(void) override;
void periodic_1ms(void) override;
void rxPostman(void);
bool sendOneShotMessage(CANMsg &msg, Kernel::Clock::duration_u32 timeout);

// Update a TX CAN signal
bool setTXSignalValue(HWBRIDGE::CANID msgID, HWBRIDGE::CANSIGNAL signalName, HWBRIDGE::CANSignalValue_t signalValue);

// Read a RX CAN signal
bool getRXSignalValue(HWBRIDGE::CANID msgID, HWBRIDGE::CANSIGNAL signalName, HWBRIDGE::CANSignalValue_t &signalValue);

// Set CAN bus hw filter
bool setFilter(HWBRIDGE::CANFILTER filter, CANFormat format = CANStandard,
uint16_t mask = HWBRIDGE::ROVER_CANID_FILTER_MASK, int handle = 0);

// For diagnostic purposes
uint32_t getNumStreamedMsgsReceived(void);
uint32_t getNumOneShotMsgsReceived(void);
uint32_t getNumStreamedMsgsSent(void);
uint32_t getNumOneShotMsgsSent(void);

uint16_t getNumCANRXFaults(void);
uint16_t getNumCANTXFaults(void);

private:
CANInterface interface;
};
10 changes: 10 additions & 0 deletions rover-apps/common/include/Module.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

class Module {
public:
virtual void periodic_10s(void) = 0;
virtual void periodic_1s(void) = 0;
virtual void periodic_100ms(void) = 0;
virtual void periodic_10ms(void) = 0;
virtual void periodic_1ms(void) = 0;
};
24 changes: 24 additions & 0 deletions rover-apps/common/include/WatchdogModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include "Module.h"
#include "mbed.h"

class WatchdogModule final : public Module {
public:
/* Initiates the watchdog with a countdown
* @param countdown - max timeout of the watchdog
* */
WatchdogModule();

/* Periodic function to kick the watchdog and restart its timer every 1s
* */
void periodic_1s(void) override;

void periodic_10s(void) override {}
void periodic_100ms(void) override {}
void periodic_10ms(void) override {}
void periodic_1ms(void) override {}

private:
static const std::chrono::milliseconds WATCHDOG_DEFAULT_COUNTDOWN;
};
Loading