1
0
mirror of https://github.com/peterantypas/maiana.git synced 2025-05-31 23:00:16 -07:00

Compiles, not tested yet

This commit is contained in:
Peter Antypas 2020-10-08 16:22:12 -07:00
commit d983ac6fd6
14 changed files with 78 additions and 115 deletions

View File

@ -24,6 +24,8 @@
#include <map> #include <map>
#include "CircularQueue.hpp" #include "CircularQueue.hpp"
#include "Events.hpp" #include "Events.hpp"
#include "FreeRTOS.h"
#include "queue.h"
using namespace std; using namespace std;
@ -45,18 +47,18 @@ public:
void removeObserver(EventConsumer *c); void removeObserver(EventConsumer *c);
/* /*
* We push events here to be processed by the main thread * We push events here to be processed by the dispatching task
*/ */
void push(Event* event); void push(const Event &event);
/* /*
* This method must be called repeatedly by main() (never an ISR!!!!!!) * This method must be called repeatedly by an RTOS task or main() (never an ISR)
*/ */
void dispatch(); void dispatch();
private: private:
EventQueue(); EventQueue();
CircularQueue<Event*> *mISRQueue; // Exclusively used by ISRs QueueHandle_t mQueueHandle;
CircularQueue<Event*> *mThreadQueue; // Exclusively used by the (only) thread StaticQueue_t mQueue;
map<EventConsumer *, uint32_t> mConsumers; map<EventConsumer *, uint32_t> mConsumers;
}; };

View File

@ -77,6 +77,12 @@ public:
: type(UNKNOWN_EVENT), flags(0) { : type(UNKNOWN_EVENT), flags(0) {
} }
Event(EventType t)
: type(t), flags(0)
{
}
RXPacket rxPacket; RXPacket rxPacket;
union { union {
@ -102,6 +108,7 @@ public:
virtual void processEvent(const Event &event)=0; virtual void processEvent(const Event &event)=0;
}; };
#if 0
class EventPool class EventPool
{ {
public: public:
@ -117,6 +124,6 @@ private:
ObjectPool<Event> *mISRPool; ObjectPool<Event> *mISRPool;
ObjectPool<Event> *mThreadPool; ObjectPool<Event> *mThreadPool;
}; };
#endif
#endif /* EVENTS_HPP_ */ #endif /* EVENTS_HPP_ */

View File

@ -66,8 +66,8 @@ void Configuration::reportStationData()
if ( !readStationData(d) ) if ( !readStationData(d) )
memset(&d, 0, sizeof d); memset(&d, 0, sizeof d);
Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE); Event e(PROPR_NMEA_SENTENCE);
sprintf(e->nmeaBuffer.sentence, sprintf(e.nmeaBuffer.sentence,
"$PAISTN,%lu,%s,%s,%d,%d,%d,%d,%d*", "$PAISTN,%lu,%s,%s,%d,%d,%d,%d,%d*",
d.mmsi, d.mmsi,
d.name, d.name,
@ -77,7 +77,7 @@ void Configuration::reportStationData()
d.beam, d.beam,
d.portOffset, d.portOffset,
d.bowOffset); d.bowOffset);
Utils::completeNMEA(e->nmeaBuffer.sentence); Utils::completeNMEA(e.nmeaBuffer.sentence);
EventQueue::instance().push(e); EventQueue::instance().push(e);
} }

View File

@ -111,12 +111,9 @@ void termInputCB(char c)
else if ( c == '\n' ) else if ( c == '\n' )
{ {
__rxbuff[__rxpos++] = 0; __rxbuff[__rxpos++] = 0;
Event *e = EventPool::instance().newEvent(COMMAND_EVENT); Event e(COMMAND_EVENT);
if ( e ) strncpy(e.command.buffer, __rxbuff, sizeof e.command.buffer);
{ EventQueue::instance().push(e);
memcpy(e->command.buffer, __rxbuff, sizeof __rxbuff);
EventQueue::instance().push(e);
}
} }
} }

View File

@ -19,13 +19,18 @@
#include "EventQueue.hpp" #include "EventQueue.hpp"
#include <cassert>
#include <stm32l4xx.h> #include <stm32l4xx.h>
#include "printf_serial.h" #include "printf_serial.h"
#include "printf_serial.h" #include "printf_serial.h"
#include "Utils.hpp" #include "Utils.hpp"
#include "FreeRTOS.h"
#include "queue.h"
#include "task.h"
#define EVENT_QUEUE_SIZE 40
static Event __queue[EVENT_QUEUE_SIZE];
EventQueue &EventQueue::instance() EventQueue &EventQueue::instance()
{ {
@ -35,34 +40,23 @@ EventQueue &EventQueue::instance()
EventQueue::EventQueue() EventQueue::EventQueue()
{ {
mISRQueue = new CircularQueue<Event*>(40); mQueueHandle = xQueueCreateStatic(EVENT_QUEUE_SIZE, sizeof(Event), (uint8_t*)&__queue[0], &mQueue);
mThreadQueue = new CircularQueue<Event*>(40);
} }
void EventQueue::init() void EventQueue::init()
{ {
} }
void EventQueue::push(Event *event) void EventQueue::push(const Event &e)
{ {
/* BaseType_t xHighPriorityTaskWoken = pdFALSE;
* For mISRQueue, interrupt context is the "producer", and the thread is the "consumer".
* For mThreadQueue, the thread is both the producer and the consumer, so all access is serialized.
*/
ASSERT(event);
if ( Utils::inISR() ) if ( Utils::inISR() )
{ {
if ( !mISRQueue->push(event) ) xQueueSendFromISR(mQueueHandle, &e, &xHighPriorityTaskWoken);
{
EventPool::instance().deleteEvent(event);
}
} }
else else
{ {
if ( !mThreadQueue->push(event) ) xQueueSend(mQueueHandle, &e, 0);
{
EventPool::instance().deleteEvent(event);
}
} }
} }
@ -82,27 +76,18 @@ void EventQueue::removeObserver(EventConsumer *c)
void EventQueue::dispatch() void EventQueue::dispatch()
{ {
//ASSERT(!Utils::inISR()); Event e;
Event *e = nullptr; while ( xQueueReceive(mQueueHandle, &e, 0) == pdTRUE )
// This is safe to do as interrupt context never pops this queue!
while ( mISRQueue->pop(e) )
{
mThreadQueue->push(e);
}
if ( mThreadQueue->pop(e) )
{ {
for ( map<EventConsumer*, uint32_t>::iterator c = mConsumers.begin(); c != mConsumers.end(); ++c ) for ( map<EventConsumer*, uint32_t>::iterator c = mConsumers.begin(); c != mConsumers.end(); ++c )
{ {
if ( c->second & e->type ) if ( c->second & e.type )
{ {
c->first->processEvent(*e); c->first->processEvent(e);
} }
} }
EventPool::instance().deleteEvent(e);
} }
} }

View File

@ -19,10 +19,9 @@
#include "Events.hpp" #include "Events.hpp"
#include <algorithm>
#include "printf_serial.h" #include "printf_serial.h"
#if 0
EventPool &EventPool::instance() EventPool &EventPool::instance()
{ {
static EventPool __instance; static EventPool __instance;
@ -82,3 +81,4 @@ uint32_t EventPool::utilization()
{ {
return std::max(mISRPool->utilization(), mThreadPool->utilization()); return std::max(mISRPool->utilization(), mThreadPool->utilization());
} }
#endif

View File

@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/> along with this program. If not, see <https://www.gnu.org/licenses/>
*/ */
#include "GPS.hpp" #include "GPS.hpp"
@ -112,12 +112,9 @@ void GPS::onRX(char c)
else if (c == '\n') else if (c == '\n')
{ {
mBuff[mBuffPos] = 0; mBuff[mBuffPos] = 0;
Event *event = EventPool::instance().newEvent(GPS_NMEA_SENTENCE); Event event(GPS_NMEA_SENTENCE);
if ( event ) strncpy(event.nmeaBuffer.sentence, mBuff, sizeof event.nmeaBuffer.sentence);
{ EventQueue::instance ().push(event);
memcpy(event->nmeaBuffer.sentence, mBuff, sizeof event->nmeaBuffer.sentence);
EventQueue::instance ().push (event);
}
mBuffPos = 0; mBuffPos = 0;
mBuff[mBuffPos] = 0; mBuff[mBuffPos] = 0;
} }
@ -171,12 +168,9 @@ void GPS::onPPS()
} }
} }
Event *event = EventPool::instance().newEvent(CLOCK_EVENT); Event event(CLOCK_EVENT);
if ( event ) event.clock.utc = mUTC;
{ EventQueue::instance ().push(event);
event->clock.utc = mUTC;
EventQueue::instance ().push(event);
}
} }
void GPS::processEvent(const Event &event) void GPS::processEvent(const Event &event)
@ -258,16 +252,13 @@ void GPS::parseSentence(const char *buff)
mLng = Utils::longitudeFromNMEA (sentence.fields()[5], sentence.fields()[6]); mLng = Utils::longitudeFromNMEA (sentence.fields()[5], sentence.fields()[6]);
mSpeed = atof(sentence.fields()[7].c_str()); mSpeed = atof(sentence.fields()[7].c_str());
mCOG = atof(sentence.fields()[8].c_str()); mCOG = atof(sentence.fields()[8].c_str());
Event *event = EventPool::instance ().newEvent(GPS_FIX_EVENT); Event event(GPS_FIX_EVENT);
if (event) event.gpsFix.utc = mUTC;
{ event.gpsFix.lat = mLat;
event->gpsFix.utc = mUTC; event.gpsFix.lng = mLng;
event->gpsFix.lat = mLat; event.gpsFix.speed = mSpeed;
event->gpsFix.lng = mLng; event.gpsFix.cog = mCOG;
event->gpsFix.speed = mSpeed; EventQueue::instance().push (event);
event->gpsFix.cog = mCOG;
EventQueue::instance().push (event);
}
} }
} }
} }

View File

@ -76,15 +76,12 @@ void RXPacketProcessor::processEvent(const Event &e)
case 18: case 18:
case 24: case 24:
{ {
Event *ie = EventPool::instance().newEvent(INTERROGATION_EVENT); Event ie(INTERROGATION_EVENT);
if (ie) ie.interrogation.channel = e.rxPacket.channel();
{ ie.interrogation.messageType = target.messageType;
ie->interrogation.channel = e.rxPacket.channel();
ie->interrogation.messageType = target.messageType;
//printf2("Scheduling message %d in response to interrogation\r\n", ie->interrogation.messageType); //printf2("Scheduling message %d in response to interrogation\r\n", ie->interrogation.messageType);
EventQueue::instance().push(ie); EventQueue::instance().push(ie);
}
break; break;
} }
default: default:

View File

@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/> along with this program. If not, see <https://www.gnu.org/licenses/>
*/ */
#include "Receiver.hpp" #include "Receiver.hpp"
@ -121,7 +121,7 @@ void Receiver::timeSlotStarted(uint32_t slot)
// This should never be called while transmitting. Transmissions start after the slot boundary and end before the end of it. // This should never be called while transmitting. Transmissions start after the slot boundary and end before the end of it.
//assert(gRadioState == RADIO_RECEIVING); //assert(gRadioState == RADIO_RECEIVING);
//if ( gRadioState != RADIO_RECEIVING ) //if ( gRadioState != RADIO_RECEIVING )
//DBG(" **** WTF??? Transmitting past slot boundary? **** \r\n"); //DBG(" **** WTF??? Transmitting past slot boundary? **** \r\n");
mSlotBitNumber = 0; mSlotBitNumber = 0;
if ( mBitState == BIT_STATE_IN_PACKET ) if ( mBitState == BIT_STATE_IN_PACKET )
@ -242,14 +242,8 @@ bool Receiver::addBit(uint8_t bit)
void Receiver::pushPacket() void Receiver::pushPacket()
{ {
#ifndef TX_TEST_MODE #ifndef TX_TEST_MODE
Event *p = EventPool::instance().newEvent(AIS_PACKET_EVENT); Event p(AIS_PACKET_EVENT);
if ( p == nullptr ) p.rxPacket = mRXPacket;
{
//DBG("AISPacket allocation failed\r\n");
return;
}
p->rxPacket = mRXPacket;
mRXPacket.reset(); mRXPacket.reset();
EventQueue::instance().push(p); EventQueue::instance().push(p);
#else #else
@ -260,13 +254,10 @@ void Receiver::pushPacket()
uint8_t Receiver::reportRSSI() uint8_t Receiver::reportRSSI()
{ {
uint8_t rssi = readRSSI(); uint8_t rssi = readRSSI();
Event *e = EventPool::instance().newEvent(RSSI_SAMPLE_EVENT); Event e(RSSI_SAMPLE_EVENT);
if ( e ) e.rssiSample.channel = mChannel;
{ e.rssiSample.rssi = rssi;
e->rssiSample.channel = mChannel; EventQueue::instance().push(e);
e->rssiSample.rssi = rssi;
EventQueue::instance().push(e);
}
return rssi; return rssi;
} }

View File

@ -40,10 +40,8 @@ void SystickTimer::onTick()
if ( mTickCounter == 1000 ) if ( mTickCounter == 1000 )
{ {
mTickCounter = 0; mTickCounter = 0;
Event *e = EventPool::instance().newEvent(ONE_SEC_TIMER_EVENT); Event e(ONE_SEC_TIMER_EVENT);
if ( e ) EventQueue::instance().push(e);
EventQueue::instance().push(e);
//DBG("One second tick\r\n");
++mSecondCounter; ++mSecondCounter;
} }
@ -51,9 +49,8 @@ void SystickTimer::onTick()
{ {
mSecondCounter = 0; mSecondCounter = 0;
//DBG("One minute mark\r\n"); //DBG("One minute mark\r\n");
Event *e = EventPool::instance().newEvent(ONE_MIN_TIMER_EVENT); Event e(ONE_MIN_TIMER_EVENT);
if ( e ) EventQueue::instance().push(e);
EventQueue::instance().push(e);
} }
} }

View File

@ -32,14 +32,14 @@ void TXPacket::configure(VHFChannel channel)
{ {
mTestPacket = false; mTestPacket = false;
mChannel = channel; mChannel = channel;
strcpy(mMessageType, "--"); memset(mMessageType, 0, sizeof mMessageType);
} }
void TXPacket::configureForTesting(VHFChannel channel, uint16_t numBits) void TXPacket::configureForTesting(VHFChannel channel, uint16_t numBits)
{ {
mTestPacket = true; mTestPacket = true;
mChannel = channel; mChannel = channel;
strcpy(mMessageType, "--"); strcpy(mMessageType, "00");
mSize = numBits; mSize = numBits;
} }

View File

@ -349,12 +349,10 @@ void Transceiver::configureGPIOsForRX()
void Transceiver::reportTXEvent() void Transceiver::reportTXEvent()
{ {
Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE); Event e(PROPR_NMEA_SENTENCE);
if ( !e )
return;
sprintf(e->nmeaBuffer.sentence, "$PAITX,%c,%s*", AIS_CHANNELS[mTXPacket->channel()].designation, mTXPacket->messageType()); snprintf(e.nmeaBuffer.sentence, sizeof e.nmeaBuffer.sentence, "$PAITX,%c,%s*", AIS_CHANNELS[mTXPacket->channel()].designation, mTXPacket->messageType());
Utils::completeNMEA(e->nmeaBuffer.sentence); Utils::completeNMEA(e.nmeaBuffer.sentence);
EventQueue::instance().push(e); EventQueue::instance().push(e);
} }

View File

@ -71,7 +71,7 @@ void determineCauseOfReset()
void mainTask(void *params) void mainTask(void *params)
{ {
EventQueue::instance().init(); EventQueue::instance().init();
EventPool::instance().init(); //EventPool::instance().init();
Configuration::instance().init(); Configuration::instance().init();
CommandProcessor::instance().init(); CommandProcessor::instance().init();
DataTerminal::instance().init(); DataTerminal::instance().init();
@ -134,7 +134,7 @@ int main(void)
bsp_hw_init(); bsp_hw_init();
TaskHandle_t xHandle; TaskHandle_t xHandle;
xTaskCreate(mainTask, "main", 256u, NULL, 5, &xHandle); xTaskCreate(mainTask, "main", 1024u, NULL, 5, &xHandle);
xPortStartScheduler(); xPortStartScheduler();
#if 0 #if 0

View File

@ -50,13 +50,11 @@ void printf_serial(const char *format, ...)
{ {
if ( Utils::inISR() ) if ( Utils::inISR() )
{ {
Event *e = EventPool::instance().newEvent(DEBUG_EVENT); Event e(DEBUG_EVENT);
if ( e == nullptr )
return;
va_list list; va_list list;
va_start(list, format); va_start(list, format);
vsnprintf(e->debugMessage.buffer, sizeof e->debugMessage, format, list); vsnprintf(e.debugMessage.buffer, sizeof e.debugMessage, format, list);
va_end(list); va_end(list);
EventQueue::instance().push(e); EventQueue::instance().push(e);