/**
 * @file   AXCMutexFreeRTOS.hpp
 * @brief  AXCMutexFreeRTOSクラスヘッダ
 *
 * @par    Programming Language
 *         C++
 */
#ifndef AXCMUTEXFREERTOS_HPP_
#define AXCMUTEXFREERTOS_HPP_

#include "AXCMutex.hpp"
#include "FreeRTOS.h"
#include "semphr.h"

/**
 * @class AXCMutexFreeRTOS
 * @brief AXFMutex に対し、Mutexを使用してクリティカルセクションを保護する機能を提供する
 *
 * @n     [注意]AXM層は本クラスは直接使用せず、AXFMutex を使用し、OS依存しないようにする。
 * @n     Mutex を使用してクリティカルセクションを保護する機能を提供する。
 * @n     使用方法:
 * @n     1. Mutexインスタンスを生成する。
 * @n       int stat;
 * @n       AXCMutexFreeRTOS* mutex = new AXCMutexFreeRTOS();
 * @n     2. Mutexインスタンスの初期化を行う。
 * @n        本メソッドは、複数回呼び出してはならない。
 * @n        初期化に失敗した場合、呼び出し元の異常処理を行う。
 * @n       stat = mutex.init();
 * @n       if (AXCMutexFreeRTOS::MUTEX_SUCCESS != stat) {
 * @n         ...
 * @n     3.1 Mutexを獲得する。(ブロックあり)
 * @n        獲得に失敗した場合、呼び出し元の異常処理を行う。
 * @n       stat = mutex.lock();
 * @n       if (AXCMutexFreeRTOS::MUTEX_SUCCESS != stat) {
 * @n         ...
 * @n     3.2 Mutexを獲得する。(ブロックなし)
 * @n        獲得に成功した場合、保護対象のリソースにアクセスする。
 * @n        AXCMutexFreeRTOS_ERROR_BUSY が返ってきた場合、タイミングをおいて、再度、trylock を行う。
 * @n        獲得に失敗した場合、呼び出し元の異常処理を行う。
 * @n       stat = mutex.trylock();
 * @n       switch (stat) {
 * @n         case AXFMutexTKernel::MUTEX_SUCCESS:
 * @n           ...
 * @n           break;
 * @n         case AXCMutexFreeRTOS::MUTEX_ERROR_BUSY:
 * @n           ...
 * @n           mutex.trylock();
 * @n         defalut:
 * @n           ...
 * @n     4. Mutexを解放する。
 * @n        解放に失敗した場合、呼び出し元の異常処理を行う。
 * @n        stat = mutex.unlock();
 * @n        if (AXCMutexFreeRTOS::MUTEX_SUCCESS != stat) {
 * @n          ...
 * @n     5. Mutexインスタンスを破棄する。
 * @n       delelte mutex;
 * @n
 *
 */

/**
 * @class AXCMutexFreeRTOS
 * @brief Class of AXCMutexFreeRTOS
 */
class AXCMutexFreeRTOS : public AXCMutex  {
  bool m_isInited;            ///< 初期化フラグ

 public:
  /**
   * @brief AXCMutexFreeRTOSコンストラクタ
   */
  AXCMutexFreeRTOS();

  /**
   * @brief AXCMutexFreeRTOSデストラクタ
   */
  virtual ~AXCMutexFreeRTOS();

  /**
   * @brief Mutex初期化
   * @n
   * @return mutex初期化状況
   * - MUTEX_SUCCESS 正常終了
   * - MUTEX_ERROR 異常終了
   */
  mutexStatus init();

  /**
   * @brief Mutexロックの獲得（ブロックあり）
   * @n
   * @return Mutex獲得状況
   * - MUTEX_SUCCESS 正常終了
   * - MUTEX_ERROR_NOINIT Mutex未初期化
   * - MUTEX_ERROR 異常終了
   */
  mutexStatus lock();

  /**
   * @brief Mutexロックの獲得（ブロックなし）
   * @n
   * @return Mutex獲得状況
   * - MUTEX_SUCCESS 正常終了
   * - MUTEX_ERROR_NOINIT Mutex未初期化
   * - MUTEX_ERROR_BUSY 既にロック中のため、獲得失敗
   * - MUTEX_ERROR 異常終了
   */
  mutexStatus trylock();

  /**
   * @brief Mutexロックの解放
   * @n
   * @return Mutex解放状況
   * - MUTEX_SUCCESS 正常終了
   * - MUTEX_ERROR_NOINIT Mutex未初期化
   * - MUTEX_ERROR 異常終了
   */
  mutexStatus unlock();

  private:
		xSemaphoreHandle	m_mutex;		///< mutex ID（SemaphoreHandle）

};

#endif /* AXCMUTEXFREERTOS_HPP_ */
