📄 hw_serial.c
字号:
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 != INVALID_HANDLE_VALUE && cb->Handle != 0);
stdin = GetStdHandle(STD_INPUT_HANDLE);
FatalAssertion(stdin != 0, "WinConsole_ReceiverThread failed to acquire the handle of standard input.");
while((work = WaitForSingleObject(cb->Handle, INFINITE)) != WAIT_FAILED)
{
assert(work == WAIT_OBJECT_0); /* 僆僽僕僃僋僩偼僔僌僫儖忬懺偵側偭偨 */
ReadConsoleInput(stdin, &input_record, 1, &work);
if(input_record.EventType == KEY_EVENT && input_record.Event.KeyEvent.bKeyDown == TRUE)
{
cb->ReceiveBuffer = (char)input_record.Event.KeyEvent.uChar.AsciiChar;
BITSET(cb->Flag, SIO_STA_INTRCV);
HALInterruptRequest(INHNO_SERIAL);
}
}
return 0;
}
static void WinConsole_CreatePort(SIOPCB * cb)
{
BOOL result;
result = AllocConsole();
FatalAssertion(result != 0, "WinConsole_CreatePort failed to allocate its own console.");
cb->Handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTitle("TOPPERS/JSP SerialConsole");
/* 庴怣僶僢僼傽娔帇梡僗儗僢僪傪嶌惉 */
CreateThread(NULL,0,WinConsole_ReceiverThread,(LPVOID)cb,0,NULL);
}
static BOOL WinConsole_PutChar(SIOPCB * cb, INT chr, BOOL rasint)
{
BOOL result;
DWORD written;
char word;
assert(cb != NULL);
assert(BITTEST(cb->Flag, SIO_TYP_TTY));
assert(cb->Handle != INVALID_HANDLE_VALUE && cb->Handle != 0);
/* 昗弨弌椡偵堦暥帤憲怣 */
word = (char)chr;
result = WriteFile(cb->Handle, &word, 1, &written, NULL);
/* 妱崬傒敪惗僼儔僌偑棫偭偰偄偨傜丄憲怣姰椆妱崬傒梫媮傪婲偙偡 */
if(result != 0 && rasint == TRUE)
{
BITSET(cb->Flag, SIO_STA_INTSND);
HALInterruptRequest(INHNO_SERIAL);
}
return result != 0 ? TRUE : FALSE;
}
static void WinConsole_ClosePort(SIOPCB * cb)
{
assert(cb != NULL);
assert(BITTEST(cb->Flag, SIO_TYP_TTY));
if(cb->Handle != INVALID_HANDLE_VALUE && cb->Handle != 0)
{
FreeConsole();
cb->Handle = INVALID_HANDLE_VALUE;
}
}
/*===========================================================================*/
/*
* Windows偺僐儞僜乕儖傪巊梡偟偨僔儕傾儖擖弌椡
*/
static DWORD WINAPI ScreenBuffer_ReceiverThread(LPVOID param)
{
SIOPCB * cb = (SIOPCB *)param;
DWORD work;
INPUT_RECORD input_record;
assert(cb != NULL);
assert(cb->Handle != INVALID_HANDLE_VALUE && cb->Handle != 0);
while((work = WaitForSingleObject(cb->Handle, INFINITE)) != WAIT_FAILED)
{
assert(work == WAIT_OBJECT_0); /* 僆僽僕僃僋僩偼僔僌僫儖忬懺偵側偭偨 */
ReadConsoleInput(cb->Handle, &input_record, 1, &work);
if(input_record.EventType == KEY_EVENT && input_record.Event.KeyEvent.bKeyDown == TRUE)
{
cb->ReceiveBuffer = (char)input_record.Event.KeyEvent.uChar.AsciiChar;
BITSET(cb->Flag, SIO_STA_INTRCV);
HALInterruptRequest(INHNO_SERIAL);
}
}
return 0;
}
static void ScreenBuffer_CreatePort(SIOPCB * cb)
{
cb->Handle = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
FatalAssertion(cb->Handle != INVALID_HANDLE_VALUE, "ScreenBuffer_CreatePort failed to allocate its own console.");
SetConsoleActiveScreenBuffer(cb->Handle);
SetConsoleTitle("TOPPERS/JSP SerialConsole");
/* 庴怣僶僢僼傽娔帇梡僗儗僢僪傪嶌惉 */
CreateThread(NULL,0,ScreenBuffer_ReceiverThread,(LPVOID)cb,0,NULL);
}
static BOOL ScreenBuffer_PutChar(SIOPCB * cb, INT chr, BOOL rasint)
{
BOOL result;
DWORD written;
char word;
assert(cb != NULL);
assert(BITTEST(cb->Flag, SIO_TYP_SCRBUF));
assert(cb->Handle != INVALID_HANDLE_VALUE && cb->Handle != 0);
/* 昗弨弌椡偵堦暥帤憲怣 */
word = (char)chr;
result = WriteFile(cb->Handle, &word, 1, &written, NULL);
/* 妱崬傒敪惗僼儔僌偑棫偭偰偄偨傜丄憲怣姰椆妱崬傒梫媮傪婲偙偡 */
if(result != 0 && rasint == TRUE)
{
BITSET(cb->Flag, SIO_STA_INTSND);
HALInterruptRequest(INHNO_SERIAL);
}
return result != 0 ? TRUE : FALSE;
}
static void ScreenBuffer_ClosePort(SIOPCB * cb)
{
assert(cb != NULL);
assert(BITTEST(cb->Flag, SIO_TYP_SCRBUF));
if(cb->Handle != INVALID_HANDLE_VALUE && cb->Handle != 0)
{
CloseHandle(cb->Handle);
cb->Handle = INVALID_HANDLE_VALUE;
}
}
/*
* SIO僪儔僀僶偺弶婜壔儖乕僠儞
*/
void sio_initialize(void)
{
int i;
for(i=0; i<TNUM_PORT; ++i)
{
siopcb_table[i].Flag = SIO_TYP_CONSOLE;
siopcb_table[i].Handle = INVALID_HANDLE_VALUE;
siopcb_table[i].ReceiveBuffer = -1;
siopcb_table[i].versatile = NULL;
}
}
/*
* 僔儕傾儖I/O億乕僩偺僆乕僾儞
*/
SIOPCB * sio_opn_por(ID siopid, VP_INT exinf)
{
BOOL success;
SIOPCB * siopcb = GET_SIOPCB(siopid);
assert(siopcb != NULL);
siopcb->exinf = exinf;
success = TRUE;
switch(SIO_TYP(siopcb->Flag))
{
case SIO_TYP_CONSOLE:
HALExecuteProcedure(CreateSerialConsole,siopcb);
break;
case SIO_TYP_TTY:
WinConsole_CreatePort(siopcb);
break;
case SIO_TYP_SCRBUF:
HALExecuteProcedure(ScreenBuffer_CreatePort,siopcb);
break;
default:
success = FALSE;
}
if(success == TRUE)
BITSET(siopcb->Flag, SIO_STA_OPEN);
return siopcb;
}
/*
* 僔儕傾儖I/O億乕僩偺僋儘乕僘
*/
void sio_cls_por(SIOPCB *siopcb)
{
assert(siopcb != NULL);
switch(SIO_TYP(siopcb->Flag))
{
case SIO_TYP_CONSOLE:
HALExecuteProcedure(SerialConsole_FinalRelease,siopcb);
break;
case SIO_TYP_TTY:
WinConsole_ClosePort(siopcb);
break;
case SIO_TYP_SCRBUF:
HALExecuteProcedure(ScreenBuffer_ClosePort,siopcb);
break;
}
}
/*
* 僔儕傾儖I/O億乕僩傊偺暥帤憲怣
*/
BOOL sio_snd_chr(SIOPCB *siopcb, INT chr)
{
BOOL result;
assert(siopcb != NULL);
switch(SIO_TYP(siopcb->Flag))
{
case SIO_TYP_CONSOLE:
result = SerialConsole_PushChar(siopcb, chr);
break;
case SIO_TYP_TTY:
result = WinConsole_PutChar(siopcb, chr, TRUE);
break;
case SIO_TYP_SCRBUF:
result = ScreenBuffer_PutChar(siopcb, chr, TRUE);
break;
}
return result;
}
/*
* 僔儕傾儖I/O億乕僩偐傜偺暥帤庴怣
*/
INT sio_rcv_chr(SIOPCB * siopcb)
{
INT result;
result = siopcb->ReceiveBuffer;
siopcb->ReceiveBuffer = -1;
return result;
}
/*
* 僔儕傾儖I/O億乕僩偐傜偺僐乕儖僶僢僋嫋壜
*/
void sio_ena_cbr(SIOPCB * siopcb, UINT cbrtn)
{}
/*
* 僔儕傾儖I/O億乕僩偐傜偺僐乕儖僶僢僋嬛巭
*/
void sio_dis_cbr(SIOPCB * siopcb, UINT cbrtn)
{}
/*
* 僔儕傾儖I/O億乕僩妱崬傒僴儞僪儔
*/
void sio_handler(void)
{
int port;
for(port = 0; port < TNUM_PORT; ++ port)
{
if(BITTEST(siopcb_table[port].Flag, SIO_STA_OPEN))
{
/* 庴怣姰椆妱崬傒 */
if(BITTEST(siopcb_table[port].Flag, SIO_STA_INTRCV))
{
/* 庴怣偟偨暥帤傪庢傝弌偟 */
BITCLEAR(siopcb_table[port].Flag, SIO_STA_INTRCV);
sio_ierdy_rcv(GET_SIOPCB(ID_PORT(port))->exinf);
}
/* 憲怣姰椆妱崬傒 */
if(BITTEST(siopcb_table[port].Flag, SIO_STA_INTSND))
{
BITCLEAR(siopcb_table[port].Flag, SIO_STA_INTSND);
sio_ierdy_snd(GET_SIOPCB(ID_PORT(port))->exinf);
}
}
}
}
/*
* 僐儞僜乕儖億乕僩傊偺嫮惂堦暥帤弌椡 (妱崬傒側偟)
*/
void SerialRawPutc(INT chr)
{
SIOPCB * siopcb = &siopcb_table[CONSOLE_PORTID - 1];
assert(siopcb != NULL);
if(!BITTEST(siopcb->Flag, SIO_STA_OPEN))
return;
switch(SIO_TYP(siopcb->Flag))
{
case SIO_TYP_CONSOLE:
SerialConsole_PutChar(siopcb, chr, FALSE);
break;
case SIO_TYP_TTY:
WinConsole_PutChar(siopcb, chr, FALSE);
break;
case SIO_TYP_SCRBUF:
ScreenBuffer_PutChar(siopcb, chr, FALSE);
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -