📄 com_support.cpp
字号:
/*
* TOPPERS/JSP Kernel
* Toyohashi Open Platform for Embedded Real-Time Systems/
* Just Standard Profile Kernel
*
* Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
* Toyohashi Univ. of Technology, JAPAN
*
* 忋婰挊嶌尃幰偼丆埲壓偺 (1)乣(4) 偺忦審偐丆Free Software Foundation
* 偵傛偭偰岞昞偝傟偰偄傞 GNU General Public License 偺 Version 2 偵婰
* 弎偝傟偰偄傞忦審傪枮偨偡応崌偵尷傝丆杮僜僼僩僂僃傾乮杮僜僼僩僂僃傾
* 傪夵曄偟偨傕偺傪娷傓丏埲壓摨偠乯傪巊梡丒暋惢丒夵曄丒嵞攝晍乮埲壓丆
* 棙梡偲屇傇乯偡傞偙偲傪柍彏偱嫋戻偡傞丏
* (1) 杮僜僼僩僂僃傾傪僜乕僗僐乕僪偺宍偱棙梡偡傞応崌偵偼丆忋婰偺挊嶌
* 尃昞帵丆偙偺棙梡忦審偍傛傃壓婰偺柍曐徹婯掕偑丆偦偺傑傑偺宍偱僜乕
* 僗僐乕僪拞偵娷傑傟偰偄傞偙偲丏
* (2) 杮僜僼僩僂僃傾傪丆儔僀僽儔儕宍幃側偳丆懠偺僜僼僩僂僃傾奐敪偵巊
* 梡偱偒傞宍偱嵞攝晍偡傞応崌偵偼丆嵞攝晍偵敽偆僪僉儏儊儞僩乮棙梡
* 幰儅僯儏傾儖側偳乯偵丆忋婰偺挊嶌尃昞帵丆偙偺棙梡忦審偍傛傃壓婰
* 偺柍曐徹婯掕傪宖嵹偡傞偙偲丏
* (3) 杮僜僼僩僂僃傾傪丆婡婍偵慻傒崬傓側偳丆懠偺僜僼僩僂僃傾奐敪偵巊
* 梡偱偒側偄宍偱嵞攝晍偡傞応崌偵偼丆師偺偄偢傟偐偺忦審傪枮偨偡偙
* 偲丏
* (a) 嵞攝晍偵敽偆僪僉儏儊儞僩乮棙梡幰儅僯儏傾儖側偳乯偵丆忋婰偺挊
* 嶌尃昞帵丆偙偺棙梡忦審偍傛傃壓婰偺柍曐徹婯掕傪宖嵹偡傞偙偲丏
* (b) 嵞攝晍偺宍懺傪丆暿偵掕傔傞曽朄偵傛偭偰丆TOPPERS僾儘僕僃僋僩偵
* 曬崘偡傞偙偲丏
* (4) 杮僜僼僩僂僃傾偺棙梡偵傛傝捈愙揑傑偨偼娫愙揑偵惗偠傞偄偐側傞懝
* 奞偐傜傕丆忋婰挊嶌尃幰偍傛傃TOPPERS僾儘僕僃僋僩傪柶愑偡傞偙偲丏
*
* 杮僜僼僩僂僃傾偼丆柍曐徹偱採嫙偝傟偰偄傞傕偺偱偁傞丏忋婰挊嶌尃幰偍
* 傛傃TOPPERS僾儘僕僃僋僩偼丆杮僜僼僩僂僃傾偵娭偟偰丆偦偺揔梡壜擻惈傕
* 娷傔偰丆偄偐側傞曐徹傕峴傢側偄丏傑偨丆杮僜僼僩僂僃傾偺棙梡偵傛傝捈
* 愙揑傑偨偼娫愙揑偵惗偠偨偄偐側傞懝奞偵娭偟偰傕丆偦偺愑擟傪晧傢側偄丏
*
* @(#) $Id: com_support.cpp,v 1.6 2003/07/30 09:30:42 takayuki Exp $
*/
#include "cpu_rename.h"
#include "vitron.h"
#include "com_support.h"
#include "eventlog.h"
#include "syslog.h"
#include "resource.h"
#include <commctrl.h>
/*
* 慜偵暦偐傟偨帠偺愢柧
* Q: C僗僞僀儖僐儊儞僩偲C++僗僞僀儖僐儊儞僩偑崿偞偭偰偄傑偡偑?
* A: 婥妝偵僐儊儞僩傾僂僩偝傟傞偲崲傞張棟偑C僗僞僀儖僐儊儞僩偱丄帡偨傛偆側張棟傪偡傞応強偺愢柧偵C++僗僞僀儖僐儊儞僩傪巊偭偰偄傑偡丅
*
* Q: 曄悢偺柤偯偗婯懃偑傔偪傖偔偪傖偱偡偑?
* A: 婎杮揑偵僗僐乕僾斖埻偱巊偄暘偗偰偄傑偡丅
* 儘乕僇儖偑彫暥帤+"_", 僌儘乕僶儖偑戝暥帤彫暥帤, 儊儞僶偑Java偭傐偄僗僞僀儖
*/
#ifndef __COM_NOT_REQUIRED__
//===================================================
/*
* 嫟捠晹
*/
extern "C" SYSTIM _kernel_systim_offset;
extern "C" SYSTIM _kernel_current_time;
extern "C" HINSTANCE ProcessInstance;
extern "C" HANDLE PrimaryDialogHandle;
extern "C" BOOL ShutdownPostponementRequest;
extern "C" void FatalAssertion(int exp, LPCSTR format, ... );
extern "C" void enter_system_critical_section(BOOL * cookie);
extern "C" void leave_system_critiacl_section(BOOL * cookie);
//===================================================
/* 儐乕僓掕媊偺儘僌 */
#define USERDEFINED 0x60
#define LOG_MODULENAME (0 | USERDEFINED) /* 儌僕儏乕儖偺柤慜 */
#define LOG_TIMESTAMP (1 | USERDEFINED) /* 婰榐傪奐巒偟偨帪崗 (SYSTEMTIME峔憿懱傪偦偺傑傑僟儞僾) */
#define __HAL_MSG_MSGONLY
#include "hal_msg.h"
#include <string>
namespace
{
/*
* COM僀儞僞乕僼僃乕僗娭楢偺掕媊
*/
//彅乆偺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}};
// IKernel僀儞僞乕僼僃乕僗掕媊
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;
STDMETHOD(OnLogEvent)(long sz, unsigned char __RPC_FAR data[]) PURE;
};
// IKernelEvents僀儞僞僼僃乕僗掕媊
class IKernelEvents : public IUnknown
{
public:
STDMETHOD(QueryInterface)(REFIID iid, void ** unk);
STDMETHOD_(ULONG,AddRef)();
STDMETHOD_(ULONG,Release)();
STDMETHOD(OnInterruptRequest)(long inhno);
IKernelEvents(void);
long RefCount;
};
/*
* 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;
}
HRESULT IKernelEvents::OnInterruptRequest(long inhno)
{
if(inhno < 0)
{
/* inhno < 0 偼摿庩側堄枴傪帩偮 */
/* inhno = -1 : keep-alive */
}else
::PostMessage((HWND)PrimaryDialogHandle,HALMSG_MESSAGE,HALMSG_INTERRUPT,(LPARAM)inhno);
return S_OK;
}
}
namespace {
/*
* COM捠怣梡嶌嬈僗儗僢僪偵娭偡傞掕媊
*/
HANDLE request_semaphore = INVALID_HANDLE_VALUE; //梫媮懸偪僙儅僼僅
HANDLE worker_thread_handle = INVALID_HANDLE_VALUE; //嶌嬈僗儗僢僪偺僴儞僪儖
//==============================================================================
//COM嶌嬈僗儗僢僪偑惓忢偵嶌摦偟偰偄傞偐斲偐
inline bool IsValid(void)
{ return (request_semaphore != INVALID_HANDLE_VALUE) && (worker_thread_handle != INVALID_HANDLE_VALUE); }
//===================================================
/*
* Q: 偳偆偟偰僔僗僥儉儘僢僋偑昁梫側偺?
* A: 儘僌僀儀儞僩傪僉儏乕僀儞僌偡傞偨傔偵奺僞僗僋/妱崬傒僗儗僢僪偑儊儌儕傪庢傞
* -> VisualC++偺儅儖僠僗儗僢僪梡儊儌儕妋曐儔僀僽儔儕偼撪晹偱僋儕僥傿僇儖僙僋僔儑儞僆僽僕僃僋僩傪巊偭偰攔懠惂屼偟偰偄傞
* -> TOPPERS/JSP Windows偺僨傿僗僷僢僠儍(娗棟僗儗僢僪)偼梫媮偑棃傞偲崱摦偄偰偄傞僗儗僢僪傪巭傔偵偐偐傞
* -> 儊儌儕妋曐梡偺僋儕僥傿僇儖僙僋僔儑儞傪帩偭偨傑傑SuspendThread偝傟偰偟傑偄丄儊儌儕妋曐梫媮傪弌偟偨懠偺僗儗僢僪慡偰偑儘僢僋
* -> 娗棟僗儗僢僪傕儘僌傪弌偡偨傔偵儊儌儕傪偲傝偵棃傞偺偱丄娗棟僗儗僢僪傕儘僢僋
* -> 娗棟僗儗僢僪偑儘僢僋偝傟傞偲丄嵟弶偵SuspendThread偝傟偨儎僣傪婲偙偡僗儗僢僪偑偄側偄
* -> 僨僢僪儘僢僋
* 曗懌 : COM捠怣嶌嬈僗儗僢僪傗僐儞僜乕儖娗棟僗儗僢僪偺傛偆偵娗棟僗儗僢僪偺SuspendThread偺懳徾偵側傜側偄僗儗僢僪偼儘僢僋偟側偔偰傕偄偄
*/
//===================================================
/* 嶌嬈僗儗僢僪偵梌偊傞僨乕僞傪曐帩偡傞僋儔僗 */
class Request
{
public:
enum tagRequestType
{
Confirmation = 0x00, /* 儚乕僇僗儗僢僪偺摦嶌妋擣 (僙儅僼僅傪偨偨偔偩偗) */
DeviceRead = 0x01, /* 僨僶僀僗僄儈儏儗乕僔儑儞 撉弌偟憖嶌 */
DeviceWrite = 0x02, /* 僨僶僀僗僄儈儏儗乕僔儑儞 彂崬傒憖嶌 */
EventLog = 0x03, /* 僀儀儞僩儘僌憲弌 */
QuitThread = 0xff /* 嶌嬈僗儗僢僪偺廔椆 */
};
protected:
bool blocking;
bool allocated;
enum tagRequestType type;
unsigned long address; /* 僨僶僀僗 : 僨僶僀僗偺偁傞傾僪儗僗 */
unsigned long size; /* 嫟捠 : storage偑帩偮僨乕僞偺僒僀僘 */
HGLOBAL storage; /* 嫟捠 : 僨乕僞傪奿擺偟偰偄傞椞堟偺傾僪儗僗(僴儞僪儖) */
int result; /* 嫟捠 : 僽儘僢僉儞僌幚峴帪偺曉媝抧 */
HANDLE signalobject; /* 嫟捠 : 僽儘僢僉儞僌幚峴帪偺僗儗僢僪僴儞僪儖 */
Request * next; /* 僉儏乕偵偡傞偨傔偺儕儞僋 */
static LONG RequestCount; //僉儏乕偵偮側偑偭偰偄傞儕僋僄僗僩偺悢
static Request * top; //儕僋僄僗僩僉儏乕偺愭摢 (傕偭偲傕屆偄儕僋僄僗僩)
static Request * tail; //儕僋僄僗僩僉儏乕偺枛旜 (傕偭偲傕怴偟偄儕僋僄僗僩)
static CRITICAL_SECTION cs; //攔懠僉儏乕憖嶌梡婋尟椞堟僆僽僕僃僋僩
void connect(void)
{
//梫媮傪僉儏乕偵偮側偖
::EnterCriticalSection(&cs);
next = NULL;
if(tail != NULL)
tail->next = this;
tail = this;
if(top == NULL)
top = tail;
::LeaveCriticalSection(&cs);
::InterlockedIncrement(&RequestCount);
}
protected:
//僐儞僗僩儔僋僞
Request(enum tagRequestType _type, bool _block, unsigned int _size = 0, void * _storage = NULL, unsigned long _address = 0) : blocking(_block), allocated(false), type(_type), address(_address), size(0), storage(NULL), result(-1), signalobject(INVALID_HANDLE_VALUE), next(NULL)
{
size = _size;
if(size != 0)
{
//椞堟偑巜掕偝傟偰側偄応崌丄摦揑偵妋曐偡傞
if(_storage != NULL)
storage = static_cast<HGLOBAL>(_storage);
else
allocate(size, false);
}
}
public:
//僨僗僩儔僋僞
virtual ~Request(void)
{
//椞堟偑摦揑妋曐偝傟偰偄偨応崌丄攋婞傪峴偆
if(storage != NULL && allocated)
{
BOOL lock;
enter_system_critical_section(&lock);
::GlobalFree(storage);
leave_system_critiacl_section(&lock);
}
}
static void initialize(void)
{
if(RequestCount == -1)
{
::InitializeCriticalSection(&cs);
RequestCount = 0;
top = NULL;
tail = NULL;
}
}
static void finalize(void)
{
if(RequestCount != -1)
{
while(top != NULL)
{
Request * target = top;
top = top->next;
delete target;
}
::DeleteCriticalSection(&cs);
RequestCount = -1;
}
}
// 僔僗僥儉傪儘僢僋偟側偄偱儊儌儕奐曻
inline void release(void)
{
if(storage != NULL && allocated)
{
::GlobalFree(storage);
storage = 0;
}
}
inline bool isBlockingRequest(void) const
{ return blocking; }
inline enum tagRequestType getType(void) const
{ return type; }
inline bool operator == (enum tagRequestType _type) const
{ return type == _type; }
inline bool operator != (enum tagRequestType _type) const
{ return !(operator ==(_type)); }
inline void * getStorage(void)
{ return reinterpret_cast<void *>(storage); }
inline unsigned long getAddress(void) const
{ return address; }
inline unsigned long getSize(void) const
{ return size; }
inline int getResult(void) const
{ return result; }
static inline unsigned int getRequestCount(void)
{ return RequestCount; }
//椞堟偺妋曐
// _size : 昁梫偲偡傞椞堟偺僒僀僘
// realloc : 撪梕傪曐帩偡傞偐斲偐
bool allocate(unsigned int _size, bool realloc = false)
{
unsigned long old_size;
HGLOBAL old_storage;
BOOL lock;
FatalAssertion(type != Confirmation, "Request::allocate was performed with Confirmation Request Object.");
old_size = size;
old_storage = storage;
enter_system_critical_section(&lock);
storage = ::GlobalAlloc(GMEM_FIXED, _size);
FatalAssertion(storage != NULL, "Request::allocate failed to allocate a memory block.");
//慜偺撪梕偺曐帩 偍傛傃椞堟攋婞
if(old_storage != NULL)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -