mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-17 12:23:34 +08:00
STM32: Driver multiplexing, fixed ChibiOS Event
This commit is contained in:
@@ -176,6 +176,8 @@ class CanDriver : public uavcan::ICanDriver, uavcan::Noncopyable
|
||||
CanIface if1_;
|
||||
#endif
|
||||
|
||||
uavcan::CanSelectMasks makeSelectMasks() const;
|
||||
|
||||
virtual uavcan::int16_t select(uavcan::CanSelectMasks& inout_masks, uavcan::MonotonicTime blocking_deadline);
|
||||
|
||||
public:
|
||||
|
||||
@@ -525,11 +525,46 @@ uavcan::uint8_t CanIface::yieldLastHardwareErrorCode()
|
||||
/*
|
||||
* CanDriver
|
||||
*/
|
||||
uavcan::int16_t CanDriver::select(uavcan::CanSelectMasks& inout_masks, uavcan::MonotonicTime blocking_deadline)
|
||||
uavcan::CanSelectMasks CanDriver::makeSelectMasks() const
|
||||
{
|
||||
(void)inout_masks;
|
||||
(void)blocking_deadline;
|
||||
return -1;
|
||||
uavcan::CanSelectMasks msk;
|
||||
// Iface 0
|
||||
msk.read = if0_.isRxBufferEmpty() ? 0 : 1;
|
||||
msk.write = if0_.isTxBufferFull() ? 0 : 1;
|
||||
// Iface 1
|
||||
#if UAVCAN_STM32_NUM_IFACES > 1
|
||||
if (!if1_.isRxBufferEmpty())
|
||||
{
|
||||
msk.read |= 1 << 1;
|
||||
}
|
||||
if (!if1_.isTxBufferFull())
|
||||
{
|
||||
msk.write |= 1 << 1;
|
||||
}
|
||||
#endif
|
||||
return msk;
|
||||
}
|
||||
|
||||
uavcan::int16_t CanDriver::select(uavcan::CanSelectMasks& inout_masks, const uavcan::MonotonicTime blocking_deadline)
|
||||
{
|
||||
const uavcan::CanSelectMasks in_masks = inout_masks;
|
||||
const uavcan::MonotonicTime time = clock::getMonotonic();
|
||||
|
||||
if0_.discardTimedOutTxMailboxes(time); // Check TX timeouts - this may release some TX slots
|
||||
#if UAVCAN_STM32_NUM_IFACES > 1
|
||||
if1_.discardTimedOutTxMailboxes(time);
|
||||
#endif
|
||||
|
||||
inout_masks = makeSelectMasks(); // Check if we already have some of the requested events
|
||||
if ((inout_masks.read & in_masks.read) != 0 ||
|
||||
(inout_masks.write & in_masks.write) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
(void)update_event_.wait(blocking_deadline - time); // Block until timeout expires or any iface updates
|
||||
inout_masks = makeSelectMasks(); // Return what we got even if none of the requested events became signaled
|
||||
return 1; // Return value doesn't matter as long as it is non-negative
|
||||
}
|
||||
|
||||
int CanDriver::init(uavcan::uint32_t bitrate)
|
||||
|
||||
@@ -14,13 +14,13 @@ namespace uavcan_stm32
|
||||
bool Event::wait(uavcan::MonotonicDuration duration)
|
||||
{
|
||||
msg_t ret = msg_t();
|
||||
if (duration.isZero())
|
||||
if (!duration.isPositive())
|
||||
{
|
||||
sem_.waitTimeout(TIME_IMMEDIATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
sem_.waitTimeout(US2ST(duration.toUSec()));
|
||||
sem_.waitTimeout(MS2ST(duration.toMSec()));
|
||||
}
|
||||
return ret == RDY_OK;
|
||||
}
|
||||
|
||||
@@ -71,13 +71,10 @@ int main()
|
||||
|
||||
puts("Hello world");
|
||||
|
||||
unsigned iter_counter = 0;
|
||||
while (true)
|
||||
{
|
||||
sleep(1);
|
||||
app::ledSet(true);
|
||||
sleep(1);
|
||||
app::led_turn_off_event.signal();
|
||||
|
||||
iter_counter++;
|
||||
printf("Mono clock: %lu %lu\n",
|
||||
static_cast<unsigned long>(uavcan_stm32::SystemClock::instance().getMonotonic().toUSec()),
|
||||
static_cast<unsigned long>(uavcan_stm32::SystemClock::instance().getMonotonic().toMSec()));
|
||||
@@ -90,38 +87,65 @@ int main()
|
||||
uavcan_stm32::SystemClock::instance().adjustUtc(uavcan::UtcDuration::fromMSec(10000));
|
||||
}
|
||||
|
||||
uavcan::CanFrame frame;
|
||||
const uavcan::MonotonicTime deadline =
|
||||
uavcan_stm32::clock::getMonotonic() + uavcan::MonotonicDuration::fromMSec(10);
|
||||
app::led_turn_off_event.signal();
|
||||
|
||||
frame.id = 123 | uavcan::CanFrame::FlagEFF;
|
||||
frame.data[0] = 42;
|
||||
frame.dlc = 2;
|
||||
sleep(1);
|
||||
|
||||
const int send_res =
|
||||
static_cast<uavcan::ICanIface*>(app::can.driver.getIface(0))->send(frame, deadline,
|
||||
uavcan::CanIOFlagLoopback);
|
||||
printf("send_res=%i errcnt=%lu hwerr=%i\n", send_res,
|
||||
const uavcan::MonotonicTime before_select = uavcan_stm32::clock::getMonotonic();
|
||||
|
||||
uavcan::CanSelectMasks masks; // Zero masks - always blocks
|
||||
(void)static_cast<uavcan::ICanDriver&>(app::can.driver).select(masks,
|
||||
uavcan_stm32::clock::getMonotonic() + uavcan::MonotonicDuration::fromMSec(10000));
|
||||
|
||||
const uavcan::MonotonicDuration select_duration = uavcan_stm32::clock::getMonotonic() - before_select;
|
||||
printf("Select duration: %lu msec errs=%lu/%lu\n",
|
||||
static_cast<unsigned long>(select_duration.toMSec()),
|
||||
static_cast<unsigned long>(app::can.driver.getIface(0)->getErrorCount()),
|
||||
static_cast<int>(app::can.driver.getIface(0)->yieldLastHardwareErrorCode()));
|
||||
static_cast<unsigned long>(app::can.driver.getIface(1)->getErrorCount()));
|
||||
|
||||
while (true)
|
||||
app::ledSet(true);
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
uavcan::CanRxFrame rx_frame;
|
||||
uavcan::CanIOFlags flags = 0;
|
||||
|
||||
const int recv_res =
|
||||
static_cast<uavcan::ICanIface*>(app::can.driver.getIface(0))->receive(rx_frame, rx_frame.ts_mono,
|
||||
rx_frame.ts_utc, flags);
|
||||
|
||||
printf("recv_res=%i flg=%u canid=%lu dlc=%u data=[%02x %02x %02x %02x %02x %02x %02x %02x]\n",
|
||||
recv_res, unsigned(flags), rx_frame.id & uavcan::CanFrame::MaskExtID, int(rx_frame.dlc),
|
||||
int(rx_frame.data[0]), int(rx_frame.data[1]), int(rx_frame.data[2]), int(rx_frame.data[3]),
|
||||
int(rx_frame.data[4]), int(rx_frame.data[5]), int(rx_frame.data[6]), int(rx_frame.data[7]));
|
||||
|
||||
if (recv_res <= 0)
|
||||
if ((iter_counter % 3 == 0) && (masks.write & (1 << i)))
|
||||
{
|
||||
break;
|
||||
uavcan::CanFrame frame;
|
||||
const uavcan::MonotonicTime deadline =
|
||||
uavcan_stm32::clock::getMonotonic() + uavcan::MonotonicDuration::fromMSec(10);
|
||||
|
||||
frame.id = 123 | uavcan::CanFrame::FlagEFF;
|
||||
frame.data[0] = 42;
|
||||
frame.dlc = 2;
|
||||
|
||||
const int send_res =
|
||||
static_cast<uavcan::ICanIface*>(app::can.driver.getIface(0))->send(frame, deadline,
|
||||
uavcan::CanIOFlagLoopback);
|
||||
printf("send_res=%i errcnt=%lu hwerr=%i\n", send_res,
|
||||
static_cast<unsigned long>(app::can.driver.getIface(0)->getErrorCount()),
|
||||
static_cast<int>(app::can.driver.getIface(0)->yieldLastHardwareErrorCode()));
|
||||
}
|
||||
|
||||
if (masks.read & (1 << i))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
uavcan::CanRxFrame rx_frame;
|
||||
uavcan::CanIOFlags flags = 0;
|
||||
|
||||
const int recv_res =
|
||||
static_cast<uavcan::ICanIface*>(app::can.driver.getIface(0))->receive(rx_frame, rx_frame.ts_mono,
|
||||
rx_frame.ts_utc, flags);
|
||||
|
||||
printf("recv_res=%i flg=%u canid=%lu dlc=%u data=[%02x %02x %02x %02x %02x %02x %02x %02x]\n",
|
||||
recv_res, unsigned(flags), rx_frame.id & uavcan::CanFrame::MaskExtID, int(rx_frame.dlc),
|
||||
int(rx_frame.data[0]), int(rx_frame.data[1]), int(rx_frame.data[2]), int(rx_frame.data[3]),
|
||||
int(rx_frame.data[4]), int(rx_frame.data[5]), int(rx_frame.data[6]), int(rx_frame.data[7]));
|
||||
|
||||
if (recv_res <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user