STM32 example refactored

This commit is contained in:
Pavel Kirienko
2015-10-09 01:45:23 +03:00
parent 909d71081e
commit 70232725e6
5 changed files with 169 additions and 79 deletions
@@ -10,8 +10,9 @@ PROJECT = uavcan_test_stm32f107
MAIN ?= main.cpp
CPPSRC = src/$(MAIN) \
src/dummy.cpp
CPPSRC = src/$(MAIN) \
src/dummy.cpp \
src/board/board.cpp
#
# UAVCAN library
@@ -37,10 +38,15 @@ $(info $(shell $(LIBUAVCAN_DSDLC) $(UAVCAN_DSDL_DIR)))
UINCDIR += dsdlc_generated
#
# Platform
# Git commit hash
#
CSRC += src/sys/board.c
GIT_HASH := $(shell git rev-parse --short HEAD)
UDEFS += -DGIT_HASH=0x$(GIT_HASH)
#
# Platform
#
UINCDIR += src/sys
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#include "board.hpp"
#include <cstring>
#include <unistd.h>
#include <ch.h>
#include <ch.hpp>
#include <hal.h>
#include <zubax_chibios/sys/sys.h>
/**
* GPIO config for ChibiOS PAL driver
*/
const PALConfig pal_default_config =
{
{ VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH },
{ VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH },
{ VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH },
{ VAL_GPIODODR, VAL_GPIODCRL, VAL_GPIODCRH },
{ VAL_GPIOEODR, VAL_GPIOECRL, VAL_GPIOECRH }
};
namespace board
{
void init()
{
halInit();
chibios_rt::System::init();
sdStart(&STDOUT_SD, NULL);
}
__attribute__((noreturn))
void die(int error)
{
lowsyslog("Fatal error %i\n", error);
while (1)
{
setLed(false);
::sleep(1);
setLed(true);
::sleep(1);
}
}
void setLed(bool state)
{
palWritePad(GPIO_PORT_LED, GPIO_PIN_LED, state);
}
void restart()
{
NVIC_SystemReset();
}
void readUniqueID(std::uint8_t bytes[UniqueIDSize])
{
std::memcpy(bytes, reinterpret_cast<const void*>(0x1FFFF7E8), UniqueIDSize);
}
}
/*
* Early init from ChibiOS
*/
extern "C"
{
void __early_init(void)
{
stm32_clock_init();
}
void boardInit(void)
{
AFIO->MAPR |=
AFIO_MAPR_CAN_REMAP_REMAP3 |
AFIO_MAPR_CAN2_REMAP |
AFIO_MAPR_USART2_REMAP;
}
}
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#pragma once
#include <cstdint>
namespace board
{
void init();
__attribute__((noreturn))
void die(int error);
void setLed(bool state);
void restart();
constexpr unsigned UniqueIDSize = 12;
void readUniqueID(std::uint8_t bytes[UniqueIDSize]);
}
@@ -6,6 +6,7 @@
#include <zubax_chibios/sys/sys.h>
#include <uavcan_stm32/uavcan_stm32.hpp>
#include <uavcan/protocol/global_time_sync_slave.hpp>
#include "board/board.hpp"
namespace app
{
@@ -27,16 +28,9 @@ Node& getNode()
return *node_;
}
void ledSet(bool state)
{
palWritePad(GPIO_PORT_LED, GPIO_PIN_LED, state);
}
void init()
{
halInit();
chibios_rt::System::init();
sdStart(&STDOUT_SD, NULL);
board::init();
int res = 0;
do
@@ -54,37 +48,58 @@ void init()
while (res < 0);
}
#if __GNUC__
__attribute__((noreturn))
#endif
void die(int status)
{
lowsyslog("Initialization failure %i\n", status);
while (1)
{
ledSet(false);
sleep(1);
ledSet(true);
sleep(1);
}
}
class : public chibios_rt::BaseStaticThread<8192>
{
void configureNodeInfo()
{
Node& node = app::getNode();
node.setNodeID(64);
node.setName("org.uavcan.stm32_test_stm32f107");
/*
* Software version
* TODO: Fill other fields too
*/
uavcan::protocol::SoftwareVersion swver;
swver.vcs_commit = GIT_HASH;
swver.optional_field_flags = swver.OPTIONAL_FIELD_FLAG_VCS_COMMIT;
node.setSoftwareVersion(swver);
lowsyslog("Git commit hash: 0x%08x\n", GIT_HASH);
/*
* Hardware version
* TODO: Fill other fields too
*/
uavcan::protocol::HardwareVersion hwver;
std::uint8_t uid[board::UniqueIDSize] = {};
board::readUniqueID(uid);
std::copy(std::begin(uid), std::end(uid), std::begin(hwver.unique_id));
node.setHardwareVersion(hwver);
lowsyslog("UDID:");
for (auto b : hwver.unique_id)
{
lowsyslog(" %02x", unsigned(b));
}
lowsyslog("\n");
}
public:
msg_t main()
{
/*
* Setting up the node parameters
*/
configureNodeInfo();
Node& node = app::getNode();
node.setNodeID(64);
node.setName("org.uavcan.stm32_test_stm32f107");
// TODO: fill software version info (version number, VCS commit hash, ...)
// TODO: fill hardware version info (version number, unique ID)
/*
* Initializing the UAVCAN node - this may take a while
*/
@@ -93,25 +108,10 @@ public:
// Calling start() multiple times is OK - only the first successfull call will be effective
int res = node.start();
#if !UAVCAN_TINY
uavcan::NetworkCompatibilityCheckResult ncc_result;
if (res >= 0)
{
lowsyslog("Checking network compatibility...\n");
res = node.checkNetworkCompatibility(ncc_result);
}
#endif
if (res < 0)
{
lowsyslog("Node initialization failure: %i, will try agin soon\n", res);
}
#if !UAVCAN_TINY
else if (!ncc_result.isOk())
{
lowsyslog("Network conflict with %u, will try again soon\n", ncc_result.conflicting_node.get());
}
#endif
else
{
break;
@@ -127,7 +127,7 @@ public:
const int res = time_sync_slave.start();
if (res < 0)
{
die(res);
board::die(res);
}
}
@@ -146,8 +146,10 @@ public:
lowsyslog("Time sync master: %u\n", unsigned(time_sync_slave.getMasterNodeID().get()));
lowsyslog("Memory usage: used=%u free=%u\n",
node.getAllocator().getNumUsedBlocks(), node.getAllocator().getNumFreeBlocks());
lowsyslog("Memory usage: free=%u used=%u worst=%u\n",
node.getAllocator().getNumFreeBlocks(),
node.getAllocator().getNumUsedBlocks(),
node.getAllocator().getPeakNumUsedBlocks());
lowsyslog("CAN errors: %lu %lu\n",
static_cast<unsigned long>(can.driver.getIface(0)->getErrorCount()),
@@ -179,7 +181,7 @@ int main()
{
for (int i = 0; i < 200; i++)
{
app::ledSet(app::can.driver.hadActivity());
board::setLed(app::can.driver.hadActivity());
::usleep(25000);
}
@@ -1,27 +0,0 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#include <ch.h>
#include <hal.h>
const PALConfig pal_default_config = {
{ VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH },
{ VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH },
{ VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH },
{ VAL_GPIODODR, VAL_GPIODCRL, VAL_GPIODCRH },
{ VAL_GPIOEODR, VAL_GPIOECRL, VAL_GPIOECRH }
};
void __early_init(void)
{
stm32_clock_init();
}
void boardInit(void)
{
AFIO->MAPR |=
AFIO_MAPR_CAN_REMAP_REMAP3 |
AFIO_MAPR_CAN2_REMAP |
AFIO_MAPR_USART2_REMAP;
}