Mailbox and Mail

#ifndef __MAILBOX_H__
#define __MAILBOX_H__

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
  // uint32_t Capacity;
  uint8_t * Memory;
  uint32_t MailSize;
  uint32_t MailCount;
  uint32_t ReadIndex;
  uint32_t ReadCount;
} MAILBOX;

// Creates a new mailbox and Init it.
MAILBOX * MBX_Create( uint32_t MailSize, uint32_t MailCount );

// Deletes a specified mailbox.
void MBX_Delete( MAILBOX * Mailbox );

// Clears all messages in a specified mailbox.
void MBX_Clear( MAILBOX * Mailbox );

// Init a new mailbox.
void MBX_Init( MAILBOX * Mailbox, uint32_t MailSize, uint32_t MailCount,
  void * Memory );

// Stores a new message of a predefined size in a mailbox.
uint32_t MBX_Write( MAILBOX * Mailbox, void * Mail );

/*
 * Stores a new message of a predefined size into a mailbox in front of all
 * other messages, if the mailbox is able to accept one more message.
 * The new message will be retrieved first.
 */
uint32_t MBX_WriteFront( MAILBOX * Mailbox, void * Mail );

/* Retrieves a new message of a predefined size from a mailbox.
 * Mail : Pointer to the memory area that the message should be stored at.
 * Make sure that it points to a valid memory area and that there is sufficient
 * space for an entiremessage. The message size (in bytes) was defined
 * when the mailbox was created.
 */
uint32_t MBX_Read( MAILBOX * Mailbox, void * Mail );

// Returns the number of mail currently available in a specified mailbox.
uint32_t MBX_GetCount( MAILBOX * Mailbox );

#endif /* __MAILBOX_H__ */
#include "mailbox.h"
#include "macro_misc.h"
#include "cmsis_os.h"

// Creates a new mailbox and Init it.
MAILBOX * MBX_Create( uint32_t MailSize, uint32_t MailCount )
{
  uint32_t Size = ALIGN_UP( sizeof(MAILBOX), 4 ) + MailSize * MailCount;
  MAILBOX * Mailbox = (MAILBOX *) osMalloc( Size, osWaitForever );
  if ( Mailbox == 0 )
    return Mailbox;

  uint8_t * Memory = //
    (uint8_t *) ( ( (uint32_t) ( Mailbox ) ) + ALIGN_UP( sizeof(MAILBOX), 4 ) );

  MBX_Init( Mailbox, MailSize, MailCount, Memory );

  return Mailbox;
}

// Deletes a specified mailbox.
void MBX_Delete( MAILBOX * Mailbox )
{
  osFree( Mailbox );
}

// Clears all messages in a specified mailbox.
void MBX_Clear( MAILBOX * Mailbox )
{
  Mailbox->ReadCount = 0;
}

// Returns the number of mail currently available in a specified mailbox.
uint32_t MBX_GetCount( MAILBOX * Mailbox )
{
  return Mailbox->ReadCount;
}

// Init a new mailbox.
void MBX_Init( MAILBOX * Mailbox, uint32_t MailSize, uint32_t MailCount,
  void * Memory )
{
  // Mailbox->Capacity = MailCount * MailSize;
  Mailbox->MailSize = MailSize;
  Mailbox->MailCount = MailCount;
  Mailbox->Memory = Memory;
  Mailbox->ReadIndex = 0;
  Mailbox->ReadCount = 0;
}

/* Stores a new message of a predefined size in a mailbox.
 *
 * 0: Message could not be stored (mailbox is full).
 * 1: Success; message stored.
 */
uint32_t MBX_Write( MAILBOX * Mailbox, void * Mail )
{
  if ( Mailbox->ReadCount == Mailbox->MailCount )
    return 0;

  uint32_t Value = osDisableInterrupt( );

  uint32_t IndexToWrite = ( Mailbox->ReadIndex + Mailbox->ReadCount );
  if ( IndexToWrite == Mailbox->MailCount )
    IndexToWrite = 0;

  uint32_t MemoryIndexToWrite = IndexToWrite * Mailbox->MailSize;
  memcpy( &Mailbox->Memory[ MemoryIndexToWrite ], Mail, Mailbox->MailSize );
  Mailbox->ReadCount++;

  osRestoreInterrupt( Value );

  return 1;
}

/*
 * Stores a new message of a predefined size into a mailbox in front of all
 * other messages, if the mailbox is able to accept one more message.
 * The new message will be retrieved first.
 *
 * 0: Message could not be stored (mailbox is full).
 * 1: Success; message stored.
 */
uint32_t MBX_WriteFront( MAILBOX * Mailbox, void * Mail )
{
  if ( Mailbox->ReadCount == Mailbox->MailCount )
    return 0;

  if ( Mailbox->ReadCount == 0 )
    return MBX_Write( Mailbox, Mail );

  uint32_t Value = osDisableInterrupt( );

  uint32_t IndexToWrite;

  if ( Mailbox->ReadIndex )
    IndexToWrite = Mailbox->ReadIndex - 1;
  else
    IndexToWrite = Mailbox->MailCount - 1;

  uint32_t MemoryIndexToWrite = IndexToWrite * Mailbox->MailSize;
  memcpy( &Mailbox->Memory[ MemoryIndexToWrite ], Mail, Mailbox->MailSize );

  Mailbox->ReadIndex = IndexToWrite;
  Mailbox->ReadCount++;

  osRestoreInterrupt( Value );

  return 1;
}

/* Retrieves a new message of a predefined size from a mailbox.
 * Mail : Pointer to the memory area that the message should be stored at.
 * Make sure that it points to a valid memory area and that there is sufficient
 * space for an entiremessage. The message size (in bytes) was defined
 * when the mailbox was created.
 *
 * 0: Message could not be retrieved (mailbox is empty)
 * 1: Success; message retrieved.
 */
uint32_t MBX_Read( MAILBOX * Mailbox, void * Mail )
{
  if ( Mailbox->ReadCount == 0 )
    return 0;

  uint32_t Value = osDisableInterrupt( );

  uint32_t MemoryIndexToRead = Mailbox->ReadIndex * Mailbox->MailSize;
  memcpy( Mail, &Mailbox->Memory[ MemoryIndexToRead ], Mailbox->MailSize );

  Mailbox->ReadIndex++;
  if ( Mailbox->ReadIndex == Mailbox->MailCount )
    Mailbox->ReadIndex = 0;
  Mailbox->ReadCount--;

  osRestoreInterrupt( Value );

  return 1;
}
原文地址:https://www.cnblogs.com/shangdawei/p/3917674.html