device_com.cpp
来自「嵌入式系统开发 TOPPERS and JSP Kernel Release 」· C++ 代码 · 共 316 行
CPP
316 行
/* * TOPPERS/JSP Kernel * Toyohashi Open Platform for Embedded Real-Time Systems/ * Just Standard Profile Kernel * * Copyright (C) 2000-2002 by Embedded and Real-Time Systems Laboratory * Toyohashi Univ. of Technology, JAPAN * * 惧淡螟侯涪荚は·Free Software Foundation によって给山されている * GNU General Public License の Version 2 に淡揭されている掘凤か·笆 * 布の(1)×(4)の掘凤を塔たす眷圭に嘎り·塑ソフトウェア∈塑ソフトウェ * アを猖恃したものを崔むˉ笆布票じ∷を蝗脱ˇ剩澜ˇ猖恃ˇ浩芹邵∈笆布· * 网脱と钙ぶ∷することを痰浸で钓满するˉ * (1) 塑ソフトウェアをソ〖スコ〖ドの妨で网脱する眷圭には·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年が·そのままの妨でソ〖 * スコ〖ド面に崔まれていることˉ * (2) 塑ソフトウェアを浩网脱材墙なバイナリコ〖ド∈リロケ〖タブルオブ * ジェクトファイルやライブラリなど∷の妨で网脱する眷圭には·网脱 * に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟侯涪山绩· * この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (3) 塑ソフトウェアを浩网脱稍材墙なバイナリコ〖ドの妨または怠达に寥 * み哈んだ妨で网脱する眷圭には·肌のいずれかの掘凤を塔たすことˉ * (a) 网脱に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (b) 网脱の妨轮を·侍に年める数恕によって·惧淡螟侯涪荚に鼠桂する * ことˉ * (4) 塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じるいかなる禄 * 巢からも·惧淡螟侯涪荚を倘勒することˉ * * 塑ソフトウェアは·痰瘦沮で捏丁されているものであるˉ惧淡螟侯涪荚は· * 塑ソフトウェアに簇して·その努脱材墙拉も崔めて·いかなる瘦沮も乖わ * ないˉまた·塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じたい * かなる禄巢に簇しても·その勒扦を砷わないˉ * * @(#) $Id: device_com.cpp,v 1.6 2002/04/10 11:20:09 takayuki Exp $ */#include "sys_defs.h"#ifdef DEVICE_ENABLE#include <windows.h>#define __HAL_MSG_MSGONLY#include "hal_msg.h"#include <objbase.h>#include <unknwn.h>#include <ocidl.h>#define DEV_READ (WM_APP + 0x10)#define DEV_WRITE (WM_APP + 0x11)#define DEV_QUIT WM_QUIT/* * デバイスサポ〖ト (COMば〖じょん) * 年盗ブロック *///typedef struct _IID//{// unsigned long x;// unsigned short s1;// unsigned short s2;// unsigned char c[8];//} IID; //紧」のIDの离咐const IID IID__IKernelEvents = {0x1353969D,0xE84F,0x463F,{0xB2,0x11,0x33,0x7E,0x9B,0xCF,0xB9,0x9E}};const IID IID_IKernel = {0xD3E42099,0x3FDD,0x4A78,{0xBD,0xBD,0x4E,0x57,0xD3,0x62,0xF5,0xED}};const CLSID CLSID_Kernel = {0x51789667,0x9F20,0x40AF,{0xAF,0x7F,0x98,0x56,0x32,0x5D,0xFB,0x0B}};class IKernel : public IUnknown{public: STDMETHOD(Read)(unsigned long address,unsigned long sz,char __RPC_FAR data[]) PURE; STDMETHOD(IsValid)(BOOL __RPC_FAR * valid) PURE; STDMETHOD(Write)(unsigned long address,unsigned long sz,char __RPC_FAR data[]) PURE;};class IKernelEvents : public IUnknown{public: STDMETHOD(QueryInterface)(REFIID iid, void ** unk); STDMETHOD_(ULONG,AddRef)(); STDMETHOD_(ULONG,Release)(); STDMETHOD(OnInterruptRequest)(unsigned long inhno); IKernelEvents(void); long RefCount;}; //プロトタイプ离咐 (device_com.hはC咐胳慌屯なので)extern "C" void _cdecl InitializeDeviceSupportModule(void);extern "C" void _cdecl FinalizeDeviceSupportModule(void);extern "C" int _cdecl DeviceRead(unsigned long address, unsigned long size, void * storage);extern "C" int _cdecl DeviceWrite(unsigned long address, unsigned long size, void * storage);extern "C" int ena_int(unsigned int);extern "C" int dis_int(unsigned int);/* * デバイスサポ〖ト (COM version) * 悸刘ブロック */static HANDLE WorkerThread;static DWORD WorkerThreadID;static HANDLE Blocker;struct tagParameter{ unsigned long address; unsigned long size; void * storage;};bool Advise(IUnknown * container, REFIID iid, IUnknown * sink, DWORD * cookie, IConnectionPoint ** pcp = NULL){ IConnectionPointContainer * cpc; IConnectionPoint * cp; if(pcp == NULL) pcp = &cp; container->QueryInterface(IID_IConnectionPointContainer, (void **)&cpc); if(cpc == 0) return false; cpc->FindConnectionPoint(iid, pcp); cpc->Release(); if(*pcp == 0) return false; if(FAILED((*pcp)->Advise(sink, cookie))) return false; if(pcp == &cp) cp->Release(); return true;}DWORD WINAPI WorkerThreadProcess(LPVOID _param){ IKernel * manager; IKernelEvents * sink; IConnectionPoint * cp; DWORD cookie; BOOL Success; MSG msg; tagParameter * param; /* * Initialize */ ::CoInitialize(NULL); manager = 0; if(FAILED(::CoCreateInstance(CLSID_Kernel, NULL, CLSCTX_ALL, IID_IKernel, (void **)&manager))) goto _WorkerThreadProc_Cleanup; cp = 0; sink = new IKernelEvents; if(!Advise(manager, IID__IKernelEvents, sink, &cookie,&cp)) { delete sink; goto _WorkerThreadProc_Cleanup; } manager->IsValid(&Success); if(Success != 0) { ::SetEvent(Blocker); while( ::GetMessage(&msg, NULL, 0,0) != 0 ) { switch(msg.message) { case DEV_READ: param = (tagParameter *)msg.lParam; manager->Read(param->address, param->size, (char *)param->storage); break; case DEV_WRITE: param = (tagParameter *)msg.lParam; manager->Write(param->address, param->size, (char *)param->storage); break; default: ::DispatchMessage(msg); } ::SetEvent(Blocker); } } /* * Finalize */ if(cp != 0) { cp->Unadvise(cookie); cp->Release(); cp = 0; sink = 0; }_WorkerThreadProc_Cleanup: if(manager != 0) manager->Release(); manager = 0l; WorkerThreadID = 0; WorkerThread = 0; ::SetEvent(Blocker); ::CloseHandle(Blocker); Blocker = INVALID_HANDLE_VALUE; ::CoUninitialize(); return 0;}extern "C"void _cdecl InitializeDeviceSupportModule(void){ Blocker = ::CreateEvent(NULL,FALSE,FALSE,NULL); WorkerThread = ::CreateThread(NULL,0,WorkerThreadProcess,NULL,NULL,&WorkerThreadID); ::WaitForSingleObject(Blocker,INFINITE);}extern "C"void _cdecl FinalizeDeviceSupportModule(void){ ::PostThreadMessage(WorkerThreadID,DEV_QUIT,0,0); ::WaitForSingleObject(WorkerThread,INFINITE);}extern "C"int _cdecl DeviceRead(unsigned long address, unsigned long size, void * storage){ tagParameter param; if(WorkerThreadID == 0) return -1; dis_int(0); param.address = address; param.size = size; param.storage = storage; ::PostThreadMessage(WorkerThreadID, DEV_READ, 0, (LPARAM)¶m); ::WaitForSingleObject(Blocker,INFINITE); ena_int(0); return size;}extern "C"int _cdecl DeviceWrite(unsigned long address, unsigned long size, void * storage){ tagParameter param; if(WorkerThreadID == 0) return -1; dis_int(0); param.address = address; param.size = size; param.storage = storage; ::PostThreadMessage(WorkerThreadID, DEV_WRITE, 0, (LPARAM)¶m); ::WaitForSingleObject(Blocker,INFINITE); ena_int(0); return size;}/* * IKernelEvents悸刘 */IKernelEvents::IKernelEvents(void) : RefCount(0){}HRESULT IKernelEvents::QueryInterface(REFIID iid, void ** unk){ if( iid == IID__IKernelEvents || iid == IID_IUnknown ) { *unk = this; ::InterlockedIncrement(&RefCount); return S_OK; } return E_NOINTERFACE;}ULONG IKernelEvents::AddRef(){ return ::InterlockedIncrement(&RefCount); }ULONG IKernelEvents::Release(){ if( ::InterlockedDecrement(&RefCount) == 0) delete this; return RefCount;}extern "C" HANDLE PrimaryDialogHandle;HRESULT IKernelEvents::OnInterruptRequest(unsigned long inhno){ ::PostMessage((HWND)PrimaryDialogHandle,HALMSG_MESSAGE,HALMSG_INTERRUPT,(LPARAM)inhno); return S_OK;}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?