//////////////////////////////////////////////////////////////////////////////// /////////////////// // OBJ_LED.h #pragma once //////////////////////////////////////////////////////////////////////////////// /////////////////// // CLASS OBJ_LED class OBJ_LED { //////////////////////////////////////////////////////////////////////////////// /////////////////// // CTOR/DTOR public: OBJ_LED(); ~OBJ_LED(); //////////////////////////////////////////////////////////////////////////////// /////////////////// // METHODS public: void Flash(int iLed, bool bOn); void Set(int iLed, bool bOn); bool Get (int iLed); void ThreadLoop(void); //////////////////////////////////////////////////////////////////////////////// /////////////////// // HELPERS private: void Start(void); void Stop(void); //////////////////////////////////////////////////////////////////////////////// /////////////////// // CONSTANTS private: enum { NUM_LEDS = 4, SLEEP_DELAY = 100, THREAD_PRIORITY = THREAD_PRIORITY_IDLE, LED_1_ON = 0x01, LED_2_ON = 0x02, LED_3_ON = 0x03, LED_4_ON =0x04, LED_ALL_ON = 0x05, LED_1_OFF = 0x06, LED_2_OFF = 0x07, LED_3_OFF = 0x08, LED_4_OFF = 0x09, LED_ALL_OFF = 0x0A, }; //////////////////////////////////////////////////////////////////////////////// /////////////////// // DATA struct { CRITICAL_SECTION Critical; HANDLE hDevice; bool bRunning; bool bStop; unsigned char ucLedState; unsigned char ucLedFlash; CWinThread* pThread; }v; };
WINCE - ThreadSafe wrapper for LEDs
//////////////////////////////////////////////////////////////////////////////// /////////////////// // OBJ_LED.cpp #include "stdafx.h" #include "OBJ_LED.h" ///////////////////////////////////////////////////////////////////////////// // safe short jumped Hook for thread UINT Thread_OBJ_LED(LPVOID pParam) { OBJ_LED* pOBJ_LED = (OBJ_LED*)pParam; pOBJ_LED->ThreadLoop(); return 1; } //////////////////////////////////////////////////////////////////////////////// /////////////////// // CTOR OBJ_LED::OBJ_LED() { v.pThread = NULL; v.hDevice = NULL; v.ucLedState = 0x00; v.ucLedFlash = 0x00; InitializeCriticalSection(&v.Critical); Start(); } //////////////////////////////////////////////////////////////////////////////// /////////////////// // DTOR OBJ_LED::~OBJ_LED() { Stop(); DeleteCriticalSection(&v.Critical); } //////////////////////////////////////////////////////////////////////////////// /////////////////// // START THREAD void OBJ_LED::Start(void) { v.bStop = false; v.bRunning = false; //OPEN STREAM DWORD dwAccess = GENERIC_WRITE; DWORD dwShareMode = NULL; DWORD dwCreationDisposition = OPEN_ALWAYS; DWORD dwFlagsAndAttributes = FILE_FLAG_NO_BUFFERING; v.hDevice = CreateFile(L"LED1:", dwAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); v.pThread = AfxBeginThread(Thread_OBJ_LED, this, THREAD_PRIORITY); } //////////////////////////////////////////////////////////////////////////////// /////////////////// // STOP THREAD void OBJ_LED::Stop(void) { for(int l = 0; l < NUM_LEDS; l++) Set(l, false); if(v.bRunning) { v.bStop = true; while(v.bRunning) Sleep(THREAD_GRANULARITY); } DeleteFile(L"LED1:"); } //////////////////////////////////////////////////////////////////////////////// /////////////////// // SET void OBJ_LED::Set(int iLed, bool bOn) { //////////////////////////////////////////////////////////////////////////////// /////////////////// EnterCriticalSection(&v.Critical); //////////////////////////////////////////////////////////////////////////////// /////////////////// if(bOn) v.ucLedState |= (0x01 << iLed); else v.ucLedState &= ~(0x01 << iLed); //////////////////////////////////////////////////////////////////////////////// /////////////////// LeaveCriticalSection(&v.Critical); //////////////////////////////////////////////////////////////////////////////// /////////////////// } //////////////////////////////////////////////////////////////////////////////// /////////////////// // GET bool OBJ_LED::Get(int iLed) { bool bReturn; //////////////////////////////////////////////////////////////////////////////// /////////////////// EnterCriticalSection(&v.Critical); //////////////////////////////////////////////////////////////////////////////// /////////////////// if(v.ucLedState & (0x01 << iLed)) bReturn = true; else bReturn = false; //////////////////////////////////////////////////////////////////////////////// /////////////////// LeaveCriticalSection(&v.Critical); //////////////////////////////////////////////////////////////////////////////// /////////////////// return bReturn; } //////////////////////////////////////////////////////////////////////////////// /////////////////// // FLASH void OBJ_LED::Flash(int iLed, bool bOn) { //////////////////////////////////////////////////////////////////////////////// /////////////////// EnterCriticalSection(&v.Critical); //////////////////////////////////////////////////////////////////////////////// /////////////////// if(bOn) v.ucLedFlash |= (0x01 << iLed); else v.ucLedFlash &= ~(0x01 << iLed); //////////////////////////////////////////////////////////////////////////////// /////////////////// LeaveCriticalSection(&v.Critical); //////////////////////////////////////////////////////////////////////////////// /////////////////// } //////////////////////////////////////////////////////////////////////////////// /////////////////// // MAIN THREAD LOOP void OBJ_LED::ThreadLoop(void) { unsigned char ucOldState = 0xFF; v.bStop = false; v.bRunning = true; while(!v.bStop) { //////////////////////////////////////////////////////////////////////////////// /////////////////// EnterCriticalSection(&v.Critical); //////////////////////////////////////////////////////////////////////////////// /////////////////// //FLASH LEDS for(int l = 0; l < NUM_LEDS; l++) if(v.ucLedFlash & (0x01<<l)) Set(l, !Get(l)); //MAKE LEDS REFLECT INTERNAL STATE if(ucOldState != v.ucLedState) { ucOldState = v.ucLedState; for(int l = 0; l < NUM_LEDS; l++) if(v.ucLedState & (0x01<<l)) DeviceIoControl(v.hDevice, LED_1_ON + l, NULL, NULL, NULL, NULL, NULL, NULL); else DeviceIoControl(v.hDevice, LED_1_OFF + l, NULL, NULL, NULL, NULL, NULL, NULL); } //////////////////////////////////////////////////////////////////////////////// /////////////////// LeaveCriticalSection(&v.Critical); //////////////////////////////////////////////////////////////////////////////// /////////////////// //DELAY Sleep(SLEEP_DELAY); } v.bRunning = false; }