CAN Queue mechanism permitting creation and management of CAN messages through a queueing

Files at this revision

API Documentation at this revision

Comitter:
WiredHome
Date:
Sun Jul 15 15:15:20 2012 +0000
Commit message:
[mbed] converted /A_CANAdapter/CANUtilities/CANQueue

Changed in this revision

CANQueue.cpp Show annotated file Show diff for this revision Revisions of this file
CANQueue.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CANQueue.cpp	Sun Jul 15 15:15:20 2012 +0000
@@ -0,0 +1,99 @@
+/// @file CANQueue.h 
+/// The CAN Queue mechanism permits the creation and management of 
+/// messages through a CAN queue.
+///
+/// @todo disable on the relevant interrupts, rather than all when protecting
+///       the critical section.
+///
+/// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved.
+///     Individuals may use this application for evaluation or non-commercial
+///     purposes. Within this restriction, changes may be made to this application
+///     as long as this copyright notice is retained. The user shall make
+///     clear that their work is a derived work, and not the original.
+///     Users of this application and sources accept this application "as is" and
+///     shall hold harmless Smartware Computing, for any undesired results while
+///     using this application - whether real or imagined.
+///
+/// @author David Smart, Smartware Computing
+///
+
+// These are needed by this file
+#include "CANQueue.h"
+//#include "CANUtilities.h"
+
+
+CANQueue::CANQueue(int Size)
+{
+    queue = new CANmsg[Size];
+    queueSize = Size;
+    queueCount = 0;
+    queueMaxCount = 0;
+    enqueuePosition = 0;
+    dequeuePosition = 0;
+}
+
+
+CANQueue::~CANQueue()
+{
+    delete[] queue;
+}
+
+
+bool CANQueue::Enqueue(CANmsg msg)
+{
+#if 1
+    return Enqueue(&msg);
+#else
+    queue[enqueuePosition++] = msg;
+    enqueuePosition = enqueuePosition % queueSize;
+    queueCount++;
+    if (queueCount > queueMaxCount) // track the max
+        queueMaxCount = queueCount;
+    if (queueCount > queueSize)     // just overwrote the oldest
+    {
+        dequeuePosition++;
+        dequeuePosition = dequeuePosition % queueSize;
+        queueCount = queueSize;
+        return false;
+    }
+    return true;
+#endif
+}
+
+
+bool CANQueue::Enqueue(CANmsg *msg)
+{
+    bool retval = true;
+    
+    __disable_irq();
+    queue[enqueuePosition++] = *msg;
+    enqueuePosition = enqueuePosition % queueSize;
+    queueCount++;
+    if (queueCount > queueMaxCount) // track the max
+        queueMaxCount = queueCount;
+    if (queueCount > queueSize)    // just overwrote the oldest
+    {
+        dequeuePosition++;
+        dequeuePosition = dequeuePosition % queueSize;
+        queueCount = queueSize;
+        retval = false;
+    }
+    __enable_irq();
+    return retval;
+}
+
+
+
+bool CANQueue::Dequeue(CANmsg *msg)
+{
+    if (queueCount)
+    {
+        __disable_irq();
+        *msg = queue[dequeuePosition++];
+        dequeuePosition = dequeuePosition % queueSize;
+        queueCount--;
+        __enable_irq();
+        return true;
+    }
+    return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CANQueue.h	Sun Jul 15 15:15:20 2012 +0000
@@ -0,0 +1,117 @@
+/// @file CANQueue.h 
+/// The CAN Queue mechanism permits the creation and management of 
+/// messages through a CAN queue.
+///
+/// @version 1.02
+///
+/// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved.
+///     Individuals may use this application for evaluation or non-commercial
+///     purposes. Within this restriction, changes may be made to this application
+///     as long as this copyright notice is retained. The user shall make
+///     clear that their work is a derived work, and not the original.
+///     Users of this application and sources accept this application "as is" and
+///     shall hold harmless Smartware Computing, for any undesired results while
+///     using this application - whether real or imagined.
+///
+/// @author David Smart, Smartware Computing
+///
+/// v1.02 - 20111030
+/// \li Added QueueSize api to retrieve the defined size
+/// v1.01 - 29 May 2011
+/// \li Added QueueMax to find the highest water mark
+/// \li Added delete in the destructor
+/// \li Added [global] interrupt disable around the critical sections
+/// v1.00 - no date
+/// \li original version
+
+#ifndef CANQUEUE_H
+#define CANQUEUE_H
+#include "CANMessage.h"
+
+/// This is a simple queue mechanism for CANmsg messages
+///
+/// CANQueue is a circular queue that is designed for CAN messages.
+/// It can be used, for example, between a CAN receive interrupt
+/// and a background process to offload those received messages.
+/// In this way, the receive interrupt is light weight.
+///
+class CANQueue
+{
+public:
+    /// CANQueue constructor, which sets the queue size
+    ///
+    /// This sets the queue size and initializes the data elements
+    ///
+    /// @param Size is the size in entries for this queue
+    ///
+    CANQueue(int Size = 3);
+    
+    /// CANQueue destructor
+    ///
+    /// This destroys the queue
+    ///
+    ~CANQueue();
+
+    /// Enqueue a new message into the queue
+    ///
+    /// If we enqueue until we overwrite the dequeue location, then
+    /// we have lost the oldest message and must force the dequeue 
+    /// forward by one position.
+    ///
+    /// @param msg is the message to be enqueued
+    /// @return true if no overwrite of the oldest message
+    /// @return false if the oldest message was overwritten
+    ///
+    bool Enqueue(CANmsg msg);
+    
+    /// Enqueue a new message into the queue
+    ///
+    /// If we enqueue until we overwrite the dequeue location, then
+    /// we have lost the oldest message and must force the dequeue 
+    /// forward by one position.
+    ///
+    /// @param msg is the message to be enqueued
+    /// @return true if no overwrite of the oldest message
+    /// @return false if the oldest message was overwritten
+    ///
+    bool Enqueue(CANmsg *msg);
+    
+    /// Dequeue a message from the queue
+    ///
+    /// If there is a message we'll copy it out to the callers message
+    /// to which they provided the handle.
+    ///    
+    /// @param msg is a pointer to the callers memory to copy the message into
+    /// @returns true if a message was dequeued
+    /// @returns false if the queue was empty
+    ///
+    bool Dequeue(CANmsg *msg);
+    
+    /// Gets the count of the number of items in the queue
+    ///
+    /// @returns number of queue entries
+    ///
+    int QueueCount() { return queueCount; }
+
+    /// Get the maximum number of items that were ever in the queue
+    ///
+    /// @returns maximum as the high water mark
+    ///
+    int QueueMax() { return queueMaxCount; }
+    
+    /// Get the defined queue size
+    ///
+    /// @returns size of the queue as defined
+    ///
+    int QueueSize() { return queueSize; }
+    
+private:
+    CANmsg * queue;         ///<!- the queue
+    int queueSize;          ///<!- the size of the queue in entries
+    int queueCount;         ///<!- the current number of items in the queue
+    int queueMaxCount;      ///<!- the maximum ever held in the queue
+    int enqueuePosition;    ///<!- where the next item will be enqueued
+    int dequeuePosition;    ///<!- where the next item will be dequeued
+};
+
+#endif // CANQUEUE_H
\ No newline at end of file