serial_console.c

来自「嵌入式系统开发 TOPPERS and JSP Kernel Release 」· C语言 代码 · 共 375 行

C
375
字号
/* *  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: serial_console.c,v 1.7 2002/04/10 11:20:09 takayuki Exp $ *//* * エディットボックスを蝗ったシリアルインタ〖フェ〖スモジュ〖ル */#include "debugout.h"#include <jsp_services.h>#include "kernel_id.h"#include "hal_msg.h"#include "resource.h"#define SERMSG_CREATE WM_APP#define TRANSLATE_PORTID(x) \	x = (x != 0) ? (x) : CONSOLE_PORTID #define CHECK_PORTID(x) \	( (x) > 0 && (x) <= NUM_PORT )#define NUM_PORT 1	/* 掐蜗脱バッファサイズ (2^nであること) */#define SERIAL_INPUTBUFFERSIZE 0x80	/* 山绩リミッタ〖サイズ */#define SERIAL_LIMITTERUPPERBOUND 0x1000#define SERIAL_LIMITTERSIZE 0x500	/* プロトタイピング */void	serial_initialize(VP_INT portid);ER		serial_open(ID portid);int		serial_close(ID portid, int flush);ER_UINT serial_read(ID portid, char *buf, unsigned int len);ER_UINT serial_write(ID portid, char *buf, unsigned int len);ER serial_ioctl(ID portid, UINT ioctl);void	serial_handler(void);static LRESULT CALLBACK KeyEventTrapper(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);typedef struct serial_port_control_block {	void * DefWndProc;	HWND	Handle;	ID		InputSemaphore;	char	Buffer[SERIAL_INPUTBUFFERSIZE];	int		Top;	int		Tail;} SPCB;SPCB spcb[NUM_PORT] ={	{	0l, 0l, SEM_SERIAL1_IN,"",0,0	}	};extern HINSTANCE ProcessInstance;#define NEXT(x) (((x)+1) & (SERIAL_INPUTBUFFERSIZE-1))#ifdef _MSC_VER__forceinline __declspec(naked) void * __fastcall MemoryCopy(void * dest, void * src, unsigned int size){	__asm	mov	eax, ecx	__asm	mov edi, ecx	__asm	mov esi, edx	__asm	pop ebx	__asm	pop ecx	__asm	rep movsb	__asm	jmp ebx}#else#include <string.h>#define MemoryCopy memcpy#endifInline voidCloseAllHandles(SPCB * cb){	if(cb->Handle != 0l)	{		DestroyWindow(cb->Handle);		cb->Handle = 0l;	}}static LRESULT CALLBACK ConsoleProc(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam){	switch(Msg)	{	case SERMSG_CREATE:		{			SPCB * work;			work = (SPCB *)lParam;			work->DefWndProc = (void *)GetWindowLong(GetDlgItem(hDlg,IDC_CONSOLE),GWL_WNDPROC);			SetWindowLong(hDlg,GWL_USERDATA,lParam);			SetWindowLong(GetDlgItem(hDlg,IDC_CONSOLE),GWL_WNDPROC,(long)KeyEventTrapper);			SetWindowLong(GetDlgItem(hDlg,IDC_CONSOLE),GWL_USERDATA,lParam);			ShowWindow(hDlg,SW_SHOWNA);			break;		}	case WM_DESTROY:		{			SPCB * scope;			scope = (SPCB *)GetWindowLong(hDlg,GWL_USERDATA);			scope->Handle = 0l;			break;		}	case WM_CLOSE:		break;	case WM_CHAR:		{			SPCB * scope;			scope = (SPCB *)GetWindowLong(hDlg,GWL_USERDATA);			if(NEXT(scope->Tail) == scope->Top)				break;	/* Buffer Overflow */			scope->Buffer[scope->Tail] = (char)wParam;			scope->Tail = NEXT(scope->Tail);			syscall(sig_sem(scope->InputSemaphore));			break;		}	case WM_INITDIALOG:	case WM_SIZE:		{			RECT client;			GetClientRect(hDlg,&client);			MoveWindow(GetDlgItem(hDlg,IDC_CONSOLE),0,0,client.right,client.bottom,TRUE);			break;		}	default:		return FALSE;	}	return TRUE;}static LRESULT CALLBACK KeyEventTrapper(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){	SPCB * scope;		if(Msg == WM_CHAR)	{		scope = (SPCB *)GetWindowLong(hWnd,GWL_USERDATA);		PostMessage(scope->Handle,WM_CHAR,wParam,lParam);		return TRUE;	}	scope = (SPCB *)GetWindowLong(hWnd, GWL_USERDATA);	return CallWindowProc(scope->DefWndProc,hWnd,Msg,wParam,lParam);}static void SerialConsole_FinalRelease(void * param){	SPCB * cb = (SPCB *)param;	if(cb->Handle != 0l)		DestroyWindow(cb->Handle);}	/*この簇眶はPrimaryThreadによって悸乖される	 *#こうしないと介袋步脱スレッド姜位箕にウィンドウが誓じられてしまう	 */static void CreateSerialConsole(SPCB * cb){	cb->Handle = CreateDialog(ProcessInstance, MAKEINTRESOURCE(CONSOLEDIALOG), PrimaryDialogHandle, ConsoleProc);	SendMessage(cb->Handle,SERMSG_CREATE,0,(LPARAM)cb);	UpdateWindow(cb->Handle);	HALAddDestructionProcedure(SerialConsole_FinalRelease,cb);}/* *  シリアルインタフェ〖スドライバの弹瓢 */voidserial_initialize(VP_INT portid){	syscall(serial_open((ID)portid));	syslog_1(LOG_NOTICE, "Serial driver service starts on port %d.", portid);}ERserial_open(ID portid){	SPCB * cb;	TRANSLATE_PORTID(portid);	if(!CHECK_PORTID(portid))		return E_PAR;	cb = &spcb[portid-1];	HALExecuteProcedure(CreateSerialConsole,cb);	return E_OK;}intserial_close(ID portid, int flush){	SPCB * cb;	return 0;	TRANSLATE_PORTID(portid);	if(!CHECK_PORTID(portid))		return E_PAR;	cb = &spcb[portid-1];	if(cb->Handle == INVALID_HANDLE_VALUE)		return E_OBJ;	CloseAllHandles(cb);	return E_OK;}ER_UINTserial_read(ID portid, char * buf, unsigned int len){	SPCB * cb;	DWORD cnt;	if(len == 0)		return 0;	TRANSLATE_PORTID(portid);	if(!CHECK_PORTID(portid) || buf == 0l)		return E_PAR;	cb = &spcb[portid-1];	if(cb->Handle == 0l)		return E_OBJ;	while(len>0)	{		cnt = 0;		if(cb->Top != cb->Tail)		{			if(cb->Top > cb->Tail)			{				cnt = SERIAL_INPUTBUFFERSIZE - cb->Top;				MemoryCopy(buf,cb->Buffer + cb->Top, cnt);				buf += cnt;				if(cb->Tail != 0)				{					MemoryCopy(buf,cb->Buffer, cb->Tail);					buf += cb->Tail;					cnt += cb->Tail;				}			}else			{				cnt = cb->Tail - cb->Top;				MemoryCopy(buf,cb->Buffer + cb->Top, cnt);				buf += cnt;			}			cb->Top = cb->Tail;		}else		{			syscall(wai_sem(cb->InputSemaphore));		}		len -= cnt;	}	return E_OK;}ER_UINTserial_write(ID portid,char * buf, unsigned int len){	SPCB * cb;	DWORD cnt;	int i,j;	char buffer[1024];	HANDLE console;	if(len == 0)		return 0;	TRANSLATE_PORTID(portid);	if(!CHECK_PORTID(portid) || buf == 0l)		return E_PAR;	cb = &spcb[portid-1];	if(cb->Handle == 0l)		return E_OBJ;	console = GetDlgItem(cb->Handle,IDC_CONSOLE);	i = GetWindowTextLength(console);	if(i > SERIAL_LIMITTERUPPERBOUND)	{		SendMessage(console,EM_SETSEL,0,i - SERIAL_LIMITTERSIZE);		SendMessage(console,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)"");	}	cnt = 0;	while(cnt<len)	{		i = len-cnt;		if(i>512)			i = 511;		for(j=0;j<i;j++,buf++)		{			if( (buffer[j] = *buf) == '\n')			{				buffer[j] = '\r';				buffer[++j] = '\n';			}		}		buffer[j] = '\x0';		j = GetWindowTextLength(console);		SendMessage(console,EM_SETSEL,j,j);		SendMessage(console,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)buffer);				cnt += i;	}	return 1;		return (UINT)cnt;}ERserial_ioctl(ID portid, UINT ioctl){	return E_OK;}voidserial_handler(void){}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?