⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.c

📁 嵌入式系统开发 TOPPERS and JSP Kernel Release 1.3 TOPPERS = Toyohashi Open Platform for Embedded Real-Tim
💻 C
字号:
/* *  TOPPERS/JSP Kernel *      Toyohashi Open Platform for Embedded Real-Time Systems/ *      Just Standard Profile Kernel *  *  Copyright (C) 2000,2001 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.c,v 1.8 2002/04/08 05:30:13 hiro Exp $ *//* *	シリアルインタフェ〖スドライバ */#include <jsp_services.h>#include "kernel_id.h"/* *  シリアルインタフェ〖スドライバの弹瓢 */static BOOL	in_inirtn = FALSE;	/* 介袋步ル〖チン悸乖面を绩す */voidserial_initialize(VP_INT portid){	in_inirtn = TRUE;	syscall(serial_open((ID) portid));	in_inirtn = FALSE;	syslog_1(LOG_NOTICE, "Serial driver service starts on port %d.",							portid);}/* *  シリアルポ〖ト瓷妄ブロックの年盗 */#define	SERIAL_BUFSZ	256	/* シリアルインタフェ〖ス脱バッファのサイズ */#define	inc(x)		(((x)+1 < SERIAL_BUFSZ) ? (x)+1 : 0)#define	INC(x)		((x) = inc(x))typedef struct serial_port_control_block {	BOOL	init_flag;	/* 介袋步貉か々 */	HWPORT	hwport;		/* ハ〖ドウェア巴赂攫鼠 */	ID	in_semid;	/* 减慨バッファ瓷妄脱セマフォの ID */	ID	out_semid;	/* 流慨バッファ瓷妄脱セマフォの ID */	int	in_read_ptr;	/* 减慨バッファ粕み叫しポインタ */	int	in_write_ptr;	/* 减慨バッファ今き哈みポインタ */	int	out_read_ptr;	/* 流慨バッファ粕み叫しポインタ */	int	out_write_ptr;	/* 流慨バッファ今き哈みポインタ */	UINT	ioctl;		/* ioctl による肋年柒推 */	BOOL	send_enabled;	/* 流慨をイネ〖ブルしてあるか々 */	BOOL	ixon_stopped;	/* STOP を减け艰った觉轮か々 */	BOOL	ixoff_stopped;	/* 陵缄に STOP を流った觉轮か々 */	char	ixoff_send;	/* 陵缄に START/STOP を流るか々 */	char	in_buffer[SERIAL_BUFSZ];	/* 减慨バッファエリア */	char	out_buffer[SERIAL_BUFSZ];	/* 减慨バッファエリア */} SPCB;#define	IN_BUFFER_EMPTY(spcb) \		((spcb)->in_read_ptr == (spcb)->in_write_ptr)#define	IN_BUFFER_FULL(spcb) \		((spcb)->in_read_ptr == inc((spcb)->in_write_ptr))#define	OUT_BUFFER_FULL(spcb) \		((spcb)->out_read_ptr == inc((spcb)->out_write_ptr))/* *  モジュ〖ル柒で蝗う簇眶 */static BOOL	serial_getc(SPCB *spcb, char *c);static BOOL	serial_putc(SPCB *spcb, char c);/* *  シリアルポ〖ト瓷妄ブロックの年盗と介袋步 */static SPCB spcb_table[NUM_PORT] = {	{ 0, HWPORT1, SEM_SERIAL1_IN, SEM_SERIAL1_OUT },#if NUM_PORT > 1	{ 0, HWPORT2, SEM_SERIAL2_IN, SEM_SERIAL2_OUT },#endif};#define get_spcb(portid)	(&(spcb_table[(portid)-1]))#define get_spcb_def(portid)	get_spcb((portid) ? (portid) : CONSOLE_PORTID)/* *  ポ〖トのオ〖プン * *  剩眶のタスクが票箕に钙ぶ觉斗には滦炳していないˉ */ERserial_open(ID portid){	SPCB	*spcb;	ER	ercd;	if (!(1 <= portid && portid <= NUM_PORT)) {		return(E_ID);	}	spcb = get_spcb(portid);	if (spcb->init_flag) {		/* 介袋步貉かのチェック */		return(E_OK);	}	/*	 *  恃眶の介袋步	 */	spcb->in_read_ptr = spcb->in_write_ptr = 0;	spcb->out_read_ptr = spcb->out_write_ptr = 0;	spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_CANONICAL				| IOCTL_IXON | IOCTL_IXOFF);	spcb->send_enabled = FALSE;	spcb->ixon_stopped = spcb->ixoff_stopped = FALSE;	spcb->ixoff_send = 0;	/*	 *  ハ〖ドウェア巴赂の介袋步	 */	if (!in_inirtn) {		syscall(loc_cpu());	}	if (hw_port_initialize(&(spcb->hwport))) {		ercd = E_SYS;	}	else {		spcb->init_flag = TRUE;		ercd = E_OK;	}	if (!in_inirtn) {		syscall(unl_cpu());	}	return(ercd);}/* *  ポ〖トのクロ〖ズ * *  flush が TRUE の眷圭は·シリアルポ〖トへの流慨バッファが鄂になるま *  で略つˉ *  剩眶のタスクが票箕に钙ぶ觉斗には滦炳していないˉ */#define	MAX_FLUSH_LOOP	1000000ERserial_close(ID portid, BOOL flush){	SPCB	*spcb;	int	i;	if (!(1 <= portid && portid <= NUM_PORT)) {		return(E_ID);		/* ポ〖ト戎规のチェック */	}	spcb = get_spcb(portid);	if (!(spcb->init_flag)) {	/* 介袋步貉かのチェック */		return(E_OBJ);	}	/*	 *  バッファのフラッシュ借妄	 */	if (flush) {		for (i = 0; i < MAX_FLUSH_LOOP; i++) {			if (spcb->out_write_ptr == spcb->out_read_ptr) {				break;			}		}	}	/*	 *  ハ〖ドウェア巴赂のシャットダウン借妄	 */	syscall(loc_cpu());	hw_port_terminate(&(spcb->hwport));	syscall(unl_cpu());	spcb->init_flag = FALSE;	return(E_OK);}/* *  フロ〖コントロ〖ル簇犯の年盗 */#define	STOP	'\023'		/* コントロ〖ル-S */#define	START	'\021'		/* コントロ〖ル-Q */#define	IXOFF_STOP	64	/* STOPを流る荒りバッファエリア */#define	IXOFF_START	128	/* STARTを流る荒りバッファエリア */#define	in_buf_area(spcb)						\		((spcb->in_read_ptr >= spcb->in_write_ptr) ?		\		 (spcb->in_read_ptr - spcb->in_write_ptr) :		\		 (spcb->in_read_ptr + SERIAL_BUFSZ - spcb->in_write_ptr))/* *  ユ〖ティリティル〖チン */Inline BOOLenable_send(SPCB *spcb, char c){	if (!(spcb->send_enabled)) {		hw_port_sendstart(&(spcb->hwport));		spcb->send_enabled = TRUE;		if (hw_port_putready(&(spcb->hwport))) {			hw_port_putchar(&(spcb->hwport), c);			return(TRUE);		}	}	return(FALSE);}/* *  シリアルポ〖トからの减慨 */static BOOLserial_getc(SPCB *spcb, char *c){	BOOL	buffer_empty;	syscall(loc_cpu());	*c = spcb->in_buffer[spcb->in_read_ptr];	INC(spcb->in_read_ptr);	if (*c == '\r' && (spcb->ioctl & IOCTL_RAW) == 0) {		*c = '\n';	}	if (spcb->ixoff_stopped && (in_buf_area(spcb) > IXOFF_START)) {		if (!enable_send(spcb, START)) {			spcb->ixoff_send = START;		}		spcb->ixoff_stopped = FALSE;	}	buffer_empty = IN_BUFFER_EMPTY(spcb);	syscall(unl_cpu());	return(buffer_empty);}ER_UINTserial_read(ID portid, char *buf, UINT len){	SPCB		*spcb;	BOOL		buffer_empty;	char		c;	unsigned int	i;	if (sns_dpn()) {		/* コンテキストのチェック */		return(E_CTX);	}	if (!(0 <= portid && portid <= NUM_PORT)) {		return(E_ID);		/* ポ〖ト戎规のチェック */	}	spcb = get_spcb_def(portid);	if (!(spcb->init_flag)) {	/* 介袋步貉かのチェック */		return(E_OBJ);	}	if (len == 0) {		return(len);	}	syscall(wai_sem(spcb->in_semid));	buffer_empty = FALSE;	for (i = 0; i < len; i++) {		buffer_empty = serial_getc(spcb, &c);		if ((spcb->ioctl & IOCTL_ECHO) != 0) {			syscall(wai_sem(spcb->out_semid));			if (!serial_putc(spcb, c)) {				syscall(sig_sem(spcb->out_semid));			}		}		*buf++ = c;		if ((spcb->ioctl & IOCTL_RAW) != 0				|| ((spcb->ioctl & IOCTL_CANONICAL) != 0						&& c == '\n')) {			len = i + 1;			break;		}		if (buffer_empty && i < len - 1) {			syscall(wai_sem(spcb->in_semid));		}	}	if (!buffer_empty) {		syscall(sig_sem(spcb->in_semid));	}	return(len);}/* *  シリアルポ〖トへの流慨 */static BOOLserial_putc(SPCB *spcb, char c){	BOOL	buffer_full;	if (c == '\n' && (spcb->ioctl & IOCTL_CRLF) != 0) {		if (serial_putc(spcb, '\r')) {			syscall(wai_sem(spcb->out_semid));		}	}	syscall(loc_cpu());	if (!(spcb->ixon_stopped) && enable_send(spcb, c)) {		buffer_full = FALSE;	}	else {		spcb->out_buffer[spcb->out_write_ptr] = c;		INC(spcb->out_write_ptr);		buffer_full = OUT_BUFFER_FULL(spcb);	}	syscall(unl_cpu());	return(buffer_full);}ER_UINTserial_write(ID portid, char *buf, UINT len){	SPCB		*spcb;	BOOL		buffer_full;	unsigned int	i;	if (sns_dpn()) {		/* コンテキストのチェック */		return(E_CTX);	}	if (!(0 <= portid && portid <= NUM_PORT)) {		return(E_ID);		/* ポ〖ト戎规のチェック */	}	spcb = get_spcb_def(portid);	if (!(spcb->init_flag)) {	/* 介袋步貉かのチェック */		return(E_OBJ);	}	syscall(wai_sem(spcb->out_semid));	buffer_full = FALSE;	for (i = 0; i < len; i++) {		buffer_full = serial_putc(spcb, *buf++);		if (buffer_full && i < len - 1) {			syscall(wai_sem(spcb->out_semid));		}	}	if (!buffer_full) {		syscall(sig_sem(spcb->out_semid));	}	return(len);}/* *  シリアルポ〖トの扩告 */ERserial_ioctl(ID portid, UINT ioctl){	SPCB	*spcb;	if (sns_ctx()) {		/* コンテキストのチェック */		return(E_CTX);	}	if (!(0 <= portid && portid <= NUM_PORT)) {		return(E_ID);		/* ポ〖ト戎规のチェック */	}	spcb = get_spcb_def(portid);	if (!(spcb->init_flag)) {	/* 介袋步貉かのチェック */		return(E_OBJ);	}	spcb->ioctl = ioctl;	return(E_OK);}/* *  シリアルポ〖ト充哈みサ〖ビスル〖チン */voidserial_handler_in(ID portid){	SPCB	*spcb;	char	c;	spcb = get_spcb(portid);	if (hw_port_getready(&(spcb->hwport))) {		c = hw_port_getchar(&(spcb->hwport));		if ((spcb->ioctl & IOCTL_IXON) != 0 && c == STOP) {			spcb->ixon_stopped = TRUE;		}		else if (((spcb->ioctl & IOCTL_IXON) != 0					|| spcb->ixon_stopped)				&& (c == START					|| (spcb->ioctl & IOCTL_IXANY) != 0)) {			spcb->ixon_stopped = FALSE;			if (!(spcb->send_enabled)) {				hw_port_sendstart(&(spcb->hwport));				spcb->send_enabled = TRUE;			}		}		else if (IN_BUFFER_FULL(spcb)) {			/* バッファフルの眷圭·减慨した矢机を嘉てるˉ*/		}		else {			spcb->in_buffer[spcb->in_write_ptr] = c;			if (spcb->in_read_ptr == spcb->in_write_ptr) {				syscall(isig_sem(spcb->in_semid));			}			INC(spcb->in_write_ptr);			if ((spcb->ioctl & IOCTL_IXOFF) != 0					&& !(spcb->ixoff_stopped)					&& (in_buf_area(spcb) < IXOFF_STOP)) {				if (!enable_send(spcb, STOP)) {					spcb->ixoff_send = STOP;				}				spcb->ixoff_stopped = TRUE;			}		}	}}voidserial_handler_out(ID portid){	SPCB	*spcb;	spcb = get_spcb(portid);	if (hw_port_putready(&(spcb->hwport))) {		if (!spcb->send_enabled) {			hw_port_sendstop(&(spcb->hwport));		}		else if (spcb->ixoff_send) {			hw_port_putchar(&(spcb->hwport), spcb->ixoff_send);			spcb->ixoff_send = 0;		}		else if (spcb->ixon_stopped				|| spcb->out_read_ptr == spcb->out_write_ptr) {			/* 流慨匿贿 */			hw_port_sendstop(&(spcb->hwport));			spcb->send_enabled = FALSE;		}		else {			hw_port_putchar(&(spcb->hwport),					spcb->out_buffer[spcb->out_read_ptr]);			if (OUT_BUFFER_FULL(spcb)) {				syscall(isig_sem(spcb->out_semid));			}			INC(spcb->out_read_ptr);		}	}}/* *  充哈みハンドラ */#ifdef SEPARATE_SIO_INTvoidserial_in_handler(void){	hw_serial_handler_in();}voidserial_out_handler(void){	hw_serial_handler_out();}#else /* SEPARATE_SIO_INT */voidserial_handler(void){	hw_serial_handler();}#endif /* SEPARATE_SIO_INT */

⌨️ 快捷键说明

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