📄 serial_mini.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 * Copyright (C) 2003-2004 by Ryosuke Takeuchi * Platform Development Center RICOH COMPANY,LTD. JAPAN * * 惧淡螟侯涪荚は·Free Software Foundation によって给山されている * GNU General Public License の Version 2 に淡揭されている掘凤か·笆 * 布の(1)×(4)の掘凤を塔たす眷圭に嘎り·塑ソフトウェア∈塑ソフトウェ * アを猖恃したものを崔むˉ笆布票じ∷を蝗脱ˇ剩澜ˇ猖恃ˇ浩芹邵∈笆布· * 网脱と钙ぶ∷することを痰浸で钓满するˉ * (1) 塑ソフトウェアをソ〖スコ〖ドの妨で网脱する眷圭には·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年が·そのままの妨でソ〖 * スコ〖ド面に崔まれていることˉ * (2) 塑ソフトウェアを浩网脱材墙なバイナリコ〖ド∈リロケ〖タブルオブ * ジェクトファイルやライブラリなど∷の妨で网脱する眷圭には·网脱 * に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟侯涪山绩· * この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (3) 塑ソフトウェアを浩网脱稍材墙なバイナリコ〖ドの妨または怠达に寥 * み哈んだ妨で网脱する眷圭には·肌のいずれかの掘凤を塔たすことˉ * (a) 网脱に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (b) 网脱の妨轮を·侍に年める数恕によって·惧淡螟侯涪荚に鼠桂する * ことˉ * (4) 塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じるいかなる禄 * 巢からも·惧淡螟侯涪荚を倘勒することˉ * * 塑ソフトウェアは·痰瘦沮で捏丁されているものであるˉ惧淡螟侯涪荚は· * 塑ソフトウェアに簇して·その努脱材墙拉も崔めて·いかなる瘦沮も乖わ * ないˉまた·塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じたい * かなる禄巢に簇しても·その勒扦を砷わないˉ * * @(#) $Id: serial_mini.c,v 1.3 2005/11/24 12:41:23 honda Exp $ *//* * シリアルインタフェ〖スドライバ */#include <t_services.h>#include <serial.h>#include <hw_serial.h>#include "kernel_id.h"/* * シリアルポ〖ト瓷妄ブロックの年盗 */#define SERIAL_BUFSZ 9 /* シリアルインタフェ〖ス脱バッファのサイズ */typedef struct serial_queue_block { BOOL openflag; /* オ〖プン貉みフラグ */ UH base; /* hardware port base address */ ID rsemid; /* receive semaphore id */ ID ssemid; /* send semaphore id */ char head; /* queue head */ char tail; /* queue tail */ char size; /* バッファサイズ */ char buffer[SERIAL_BUFSZ]; /* バッファエリア */} SQUE;static SQUE in_queue[TNUM_SIOP] ={ FALSE, TADR_SFR_UART0_BASE, SERIAL_RCV_SEM1, SERIAL_SND_SEM1, 0, 0, SERIAL_BUFSZ, "", FALSE, TADR_SFR_UART1_BASE, SERIAL_RCV_SEM2, SERIAL_SND_SEM2, 0, 0, SERIAL_BUFSZ, ""};/* * シリアルポ〖ト瓷妄ブロックの年盗と介袋步 */#define get_sque(portid) (&(in_queue[portid-1]))/* * SFR UARTの介袋步 */Inline voidSFR_uart_initialize(ID portid){ SQUE *q; VB *ip = (VB*)(TADR_SFR_INT_BASE+TADR_SFR_S0RIC_OFFSET); q = get_sque(portid); /* 流减慨モ〖ドレジスタの介袋步 */ sil_wrb_mem((VP)(q->base+TADR_SFR_UMR_OFFSET), MR_DEF); /* 流慨扩告レジスタの介袋步 */ sil_wrb_mem((VP)(q->base+TADR_SFR_UC0_OFFSET), C0_DEF); /* 啪流庐刨レジスタの介袋步 */ sil_wrb_mem((VP)(q->base+TADR_SFR_UBRG_OFFSET), BRG1_DEF); /* 充哈みレベルの肋年 */ sil_wrb_mem((VP)(ip + ((INT)portid-1)*2), RB_LEVEL); sil_wrb_mem((VP)(q->base+TADR_SFR_UC1_OFFSET), C1R_DEF); sil_reb_mem((VP)(q->base+TADR_SFR_URB_OFFSET)); /* ダミ〖デ〖タ减慨 */ sil_reb_mem((VP)(q->base+TADR_SFR_URB_OFFSET)); /* ダミ〖デ〖タ减慨 */ q->openflag = TRUE;}/* * SQUEの减慨バッファからサイズを艰り叫す */Inline intqueue_size(SQUE *q){ int size = q->head - q->tail; if(size < 0) size += q->size; return size;}/* * シリアルインタフェ〖スドライバの弹瓢 */voidserial_initialize(VP_INT exinf){ SFR_uart_initialize(LOGTASK_PORTID);}/* * シリアルポ〖トのオ〖プン */ERserial_opn_por(ID portid){ SQUE *q; VB *ip=(VB*)(TADR_SFR_INT_BASE+TADR_SFR_S0RIC_OFFSET); ER ercd; if (!(1 <= portid && portid <= TNUM_SIOP)) { return(E_ID); /* ポ〖ト戎规のチェック */ } q = get_sque(portid); _syscall(loc_cpu()); if (q->openflag) { /* オ〖プン貉みかのチェック */ ercd = E_OBJ; } else { SFR_uart_initialize(portid); ercd = E_OK; } _syscall(unl_cpu()); return(ercd);}/* * シリアルポ〖トのクロ〖ズ */ERserial_cls_por(ID portid){ SQUE *q; VB *ip=(VB*)(TADR_SFR_INT_BASE+TADR_SFR_S0RIC_OFFSET); ER ercd; if (!(1 <= portid && portid <= TNUM_SIOP)) { return(E_ID); /* ポ〖ト戎规のチェック */ } q = get_sque(portid); _syscall(loc_cpu()); if (!(q->openflag)) { /* オ〖プン貉みかのチェック */ ercd = E_OBJ; } else { sil_wrb_mem((VP)(ip + ((INT)portid-1)*2), 0); sil_wrb_mem((VP)(q->base+TADR_SFR_UC1_OFFSET), C1S_DEF); q->openflag = FALSE; ercd = E_OK; } _syscall(unl_cpu()); return(ercd);}/* * シリアルポ〖トへの流慨 */ER_UINTserial_wri_dat(ID portid, char *buf, UINT len){ SQUE *q; unsigned int i; unsigned char c; if (!(1 <= portid && portid <= TNUM_SIOP)) { return(E_ID); /* ポ〖ト戎规のチェック */ } q = get_sque(portid); if (!(q->openflag)) { /* オ〖プン貉みかのチェック */ return(E_OBJ); } wai_sem(q->ssemid); for (i = 0; i < len; i++) { while((sil_reb_mem((VP)(q->base+TADR_SFR_UC1_OFFSET)) & 0x2) == 0); sil_wrb_mem((VP)(q->base+TADR_SFR_UTB_OFFSET), *buf++); } sig_sem(q->ssemid); return(len);}/* * シリアルポ〖トからの减慨 */ER_UINTserial_rea_dat(ID portid, char *buf, UINT len){ SQUE *q; UINT i; if (!(1 <= portid && portid <= TNUM_SIOP)) { return(E_ID); /* ポ〖ト戎规のチェック */ } q = get_sque(portid); if (!(q->openflag)) { /* オ〖プン貉みかのチェック */ return(E_OBJ); } for (i = 0; i < len; i++) { if (queue_size(q) == 0) wai_sem(q->rsemid); else pol_sem(q->rsemid); _syscall(loc_cpu()); *buf++ = q->buffer[q->tail++]; if (q->tail >= q->size) { q->tail = 0; } _syscall(unl_cpu()); } return(len);}/* * シリアルポ〖トの扩告 */ERserial_ctl_por(ID portid, UINT ioctl){ return(E_OK);}/* * シリアルポ〖ト觉轮の徊救 */ERserial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor){ SQUE *q; if (sns_ctx()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_SIOP)) { return(E_ID); /* ポ〖ト戎规のチェック */ } q = get_sque(portid); if (!(q->openflag)) { /* オ〖プン貉みかのチェック */ return(E_OBJ); } pk_rpor->reacnt = queue_size(q); pk_rpor->wricnt = 0; return(E_OK);}/* * シリアルポ〖ト充哈みサ〖ビスル〖チン */voidserial_handler_in(ID portid){ SQUE *q; int rdata; /* 减慨バッファ */ q = get_sque(portid); if (queue_size(q) < q->size) { rdata = sil_reb_mem((VP)(q->base+TADR_SFR_URB_OFFSET)); /* デ〖タ减慨 */ q->buffer[q->head++] = rdata; if (q->head >= q->size) q->head = 0; isig_sem(q->rsemid); }}/* * 充哈みハンドラ */voidserial_in_handler1(void){ serial_handler_in(1);}voidserial_in_handler2(void){ serial_handler_in(2);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -