📄 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.13 2003/12/15 07:19:22 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 BOOL 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 = NULL; 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); if(scope != 0) { param = (struct tagSerialConsoleParameters *)scope->versatile; if(param->position == 0) break; lParam = TRUE; } else break; //まだ介袋步が姜わってないので部もしない } //lParam : 流慨が姜わった稿に充哈みをかけるかどうか (FALSE:かけない TRUE:かける) case SERMSG_UPDATE: { LRESULT result; int textlength; HANDLE console; SIOPCB * scope; struct tagSerialConsoleParameters * param; scope = (SIOPCB *)GetWindowLong(hDlg, GWL_USERDATA); if(scope != 0) { 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); } } else PostMessage(hDlg, Msg, wParam, lParam); //まだ介袋步が姜わってないので琐萨につけなおす 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 != NULL) DestroyWindow(cb->Handle); cb->Handle = NULL; 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 reported 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."); PostMessage(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 != NULL); 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 { success = FALSE; update = FALSE; EnterCriticalSection(¶m->cs); if(param->position < MAX_CONSOLE_BUFSZ) { param->buffer[param->position] = (char)chr; param->position ++; if(chr == '\n') update = TRUE; }else update = TRUE; LeaveCriticalSection(¶m->cs); if(update == TRUE) SendMessage(cb->Handle, SERMSG_UPDATE, 0, 1); } while(success == TRUE); return TRUE;}/*===========================================================================*//* * Windowsのコンソ〖ルを蝗脱したシリアル掐叫蜗 */static DWORD WINAPI WinConsole_ReceiverThread(LPVOID param){ SIOPCB * cb = (SIOPCB *)param; DWORD work; HANDLE stdin; INPUT_RECORD input_record; assert(cb != NULL); assert(cb->Handle != NULL && cb->Handle != 0); stdin = GetStdHandle(STD_INPUT_HANDLE); FatalAssertion(stdin != 0, "WinConsole_ReceiverThread failed to acquire the handle of standard input.");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -