📄 hw_serial.c
字号:
/*
* 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: hw_serial.c,v 1.9 2003/07/08 14:46:02 takayuki Exp $
*/
#include "hw_serial.h"
#include "hal_msg.h"
#include <t_services.h>
#include "resource.h"
#include "debugout.h"
#define BUFSZ_UPPERBOUND 24*1024 /* 僐儞僜乕儖僶僢僼傽偺姫栠偟婎弨僒僀僘 (偙傟傪挻偊傞偲姫偒栠偟) (偳偆傗傜30000傪挻偊傜傟側偄傜偟偄)*/
#define BUFSZ_LOWERBOUND 8*1024 /* 姫偒栠偟偨偲偒偵偳偺偔傜偄姫偒栠偡偐 (UPPERBOUND傛傝傕彫偝偄悢)*/
#define ID_PORT(x) ((x) + 1)
#define INDEX_PORT(x) ((x) - 1)
#define GET_SIOPCB(x) (&siopcb_table[INDEX_PORT(x)])
#define BITTEST(x,y) ( ( (x) & (y) ) != 0)
#define BITSET(x,y) InterlockedExchange( &(x), (x) | (y) )
#define BITCLEAR(x,y) InterlockedExchange( &(x), (x) & ~(y) )
extern HINSTANCE ProcessInstance;
extern HANDLE PrimaryThreadHandle;
/* 僔儕傾儖惂屼僽儘僢僋 */
SIOPCB siopcb_table[TNUM_PORT];
/* 抳柦揑側僄儔乕敪惗帪梡傾僒乕僩 */
extern void FatalAssertion(int exp, LPCSTR format, ... );
/*
* 僔儕傾儖I/O嫟捠晹僀儞僞僼僃乕僗
*/
/*===========================================================================*/
/*
* 僐儞僜乕儖宆僔儕傾儖
*/
#define MAX_CONSOLE_BUFSZ 2048
#define SERMSG_CREATE WM_APP
#define SERMSG_UPDATE (WM_APP+1)
struct tagSerialConsoleParameters
{
CRITICAL_SECTION cs;
unsigned int position;
char buffer[MAX_CONSOLE_BUFSZ];
};
static LRESULT CALLBACK KeyEventTrapper(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
SIOPCB * scope;
/* WM_CHAR傪僼僢僋偡傞 */
if(Msg == WM_CHAR)
{
scope = (SIOPCB *)GetWindowLong(GetParent(hWnd),GWL_USERDATA);
PostMessage(scope->Handle,WM_CHAR,wParam,lParam);
return TRUE;
}
/* 傕偲傕偲偺WndProc傪屇傃側偍偡 */
return CallWindowProc((void *)GetWindowLong(hWnd,GWL_USERDATA),hWnd,Msg,wParam,lParam);
}
static void SelectConsoleFont(HWND console, UINT pixel)
{
HANDLE oldfont;
HANDLE newfont;
LOGFONT logfont;
HDC hDC;
/* DC庢摼 */
hDC = GetDC(console);
/* 崱偺僼僅儞僩忣曬傪庢摼偡傞 */
oldfont = (HANDLE) SendMessage(console, WM_GETFONT, 0, 0);
GetObject(oldfont, sizeof(LOGFONT), &logfont);
/* 億僀儞僩傪曄峏 */
logfont.lfHeight = -MulDiv(pixel, GetDeviceCaps(hDC, LOGPIXELSY), 72);
/* 峏怴偟偨僼僅儞僩忣曬傪尦偵丄怴偟偄僼僅儞僩傪惗惉偟偰慖戰 */
newfont = CreateFontIndirect(&logfont);
SendMessage(console, WM_SETFONT, (WPARAM)newfont, MAKELPARAM(TRUE,0));
/* 慜偺僼僅儞僩傪攋婞 */
DeleteObject(oldfont);
/* DC夝曻 */
ReleaseDC(console, hDC);
}
static LRESULT ConsoleCommandHandler(HWND hDlg, UINT wID, UINT wNotifyCode, LPARAM lParam)
{
BOOL result;
HANDLE console;
result = TRUE;
console = GetDlgItem(hDlg, IDC_CONSOLE);
switch(wID)
{
/*
* 僼僅儞僩偺戝偒偝傪曄峏偡傞
*/
case ID_FONT_BIG:
SelectConsoleFont(console, 16);
break;
case ID_FONT_NORMAL:
SelectConsoleFont(console, 9);
break;
case ID_FONT_SMALL:
SelectConsoleFont(console, 4);
break;
default:
result = FALSE;
}
return result;
}
static INT_PTR CALLBACK ConsoleProc(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam)
{
switch(Msg)
{
case SERMSG_CREATE:
{
SIOPCB * work;
void * DefWndProc;
HWND hConsole;
hConsole = GetDlgItem(hDlg, IDC_CONSOLE);
/* 僥僉僗僩儃僢僋僗偺WndProc偵僼僢僋傪偐偗傞 */
DefWndProc = (void *)GetWindowLong(hConsole,GWL_WNDPROC);
SetWindowLong(hConsole, GWL_USERDATA, (LONG) DefWndProc);
work = (SIOPCB *)lParam;
SetWindowLong(hDlg,GWL_USERDATA,lParam);
SetWindowLong(hConsole, GWL_WNDPROC, (long)KeyEventTrapper);
SetTimer(hDlg, 100, 300, NULL);
ShowWindow(hDlg,SW_SHOWNA);
break;
}
case WM_DESTROY:
{
SIOPCB * scope;
KillTimer(hDlg, 100);
scope = (SIOPCB *)GetWindowLong(hDlg,GWL_USERDATA);
if(scope != 0)
scope->Handle = INVALID_HANDLE_VALUE;
break;
}
case WM_CLOSE: /* 儐乕僓偵傛傞僂傿儞僪僂僋儘乕僘傪梷巭 */
break;
case WM_CHAR:
{
SIOPCB * scope;
scope = (SIOPCB *)GetWindowLong(hDlg,GWL_USERDATA);
if(scope != 0)
{
scope->ReceiveBuffer = (char)wParam;
BITSET(scope->Flag, SIO_STA_INTRCV);
HALInterruptRequest(INHNO_SERIAL);
}
break;
}
case WM_SETFONT:
return TRUE;
case WM_INITDIALOG:
case WM_SIZE:
{
RECT client;
GetClientRect(hDlg,&client);
MoveWindow(GetDlgItem(hDlg,IDC_CONSOLE),0,0,client.right,client.bottom,TRUE);
break;
}
case WM_COMMAND:
return ConsoleCommandHandler(hDlg, LOWORD(wParam), HIWORD(wParam), lParam);
//堦掕帪娫偨偭偨傜夵峴偑偙側偔偰傕弌椡偡傞
case WM_TIMER:
if(wParam == 100)
{
SIOPCB * scope;
struct tagSerialConsoleParameters * param;
scope = (SIOPCB *)GetWindowLong(hDlg, GWL_USERDATA);
param = (struct tagSerialConsoleParameters *)scope->versatile;
if(param->position == 0)
break;
lParam = TRUE;
}
//lParam : 憲怣偑廔傢偭偨屻偵妱崬傒傪偐偗傞偐偳偆偐 (FALSE:偐偗側偄 TRUE:偐偗傞)
case SERMSG_UPDATE:
{
LRESULT result;
int textlength;
HANDLE console;
SIOPCB * scope;
struct tagSerialConsoleParameters * param;
scope = (SIOPCB *)GetWindowLong(hDlg, GWL_USERDATA);
param = (struct tagSerialConsoleParameters *)scope->versatile;
console = GetDlgItem(hDlg, IDC_CONSOLE);
textlength = GetWindowTextLength(console);
if(textlength > BUFSZ_UPPERBOUND)
{
/* 屆偄忣曬傪徚偡 */
SendMessage(console,EM_SETSEL,0,textlength - BUFSZ_LOWERBOUND);
SendMessage(console,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)"");
textlength = GetWindowTextLength(console);
}
/* 枛旜偵暥帤傪抲偔 */
result = SendMessage(console,EM_SETSEL,textlength,textlength);
EnterCriticalSection(¶m->cs);
param->buffer[param->position] = '\x0';
result = SendMessage(console,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)param->buffer);
param->position = 0;
LeaveCriticalSection(¶m->cs);
if(lParam == TRUE)
{
BITSET(scope->Flag, SIO_STA_INTSND);
HALInterruptRequest(INHNO_SERIAL);
}
break;
}
default:
return FALSE;
}
return TRUE;
}
static void SerialConsole_FinalRelease(void * param)
{
SIOPCB * cb = (SIOPCB *)param;
struct tagSerialConsoleParameters * versatile;
if(cb->Handle != 0l && cb->Handle != INVALID_HANDLE_VALUE)
DestroyWindow(cb->Handle);
cb->Handle = INVALID_HANDLE_VALUE;
versatile = cb->versatile;
DeleteCriticalSection(&versatile->cs);
GlobalFree((HGLOBAL)versatile);
}
static void CreateSerialConsole(SIOPCB * cb)
{
struct tagSerialConsoleParameters * param;
param = GlobalAlloc(GMEM_FIXED, sizeof(struct tagSerialConsoleParameters));
FatalAssertion(param != NULL, "CreateSerialCOnsole: GlobalAlloc returned NULL.");
param->position = 0;
InitializeCriticalSection(¶m->cs);
cb->versatile = param;
cb->Handle = CreateDialog(ProcessInstance, MAKEINTRESOURCE(CONSOLEDIALOG), 0, ConsoleProc);
FatalAssertion(cb->Handle != 0, "CreateSerialConsole could not create its dialog.");
SendMessage(cb->Handle,SERMSG_CREATE,0,(LPARAM)cb);
UpdateWindow(cb->Handle);
HALAddDestructionProcedure(SerialConsole_FinalRelease,cb);
}
static BOOL SerialConsole_PutChar(SIOPCB * cb, INT chr, BOOL rasint)
{
char buffer[2];
int textlength;
HANDLE console;
assert(cb != NULL);
assert(BITTEST(cb->Flag, SIO_TYP_CONSOLE));
assert(cb->Handle != INVALID_HANDLE_VALUE);
console = GetDlgItem(cb->Handle, IDC_CONSOLE);
buffer[0] = (char) chr;
buffer[1] = '\x0';
textlength = GetWindowTextLength(console);
if(textlength > BUFSZ_UPPERBOUND)
{
/* 屆偄忣曬傪徚偡 */
SendMessage(console,EM_SETSEL,0,textlength - BUFSZ_LOWERBOUND);
SendMessage(console,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)"");
textlength = GetWindowTextLength(console);
}
/* 枛旜偵暥帤傪抲偔 */
SendMessage(console,EM_SETSEL,textlength,textlength);
SendMessage(console,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)buffer);
if(rasint == TRUE)
{
BITSET(cb->Flag, SIO_STA_INTSND);
HALInterruptRequest(INHNO_SERIAL);
}
return TRUE;
}
static BOOL SerialConsole_PushChar(SIOPCB * cb, INT chr)
{
BOOL success;
BOOL update;
struct tagSerialConsoleParameters * param;
param = (struct tagSerialConsoleParameters *)cb->versatile;
do {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -