如果中了1000万

莫名其妙想起这个问题. 想我有这么多钱怎么花?

发现自己真不知道怎么去花钱了.

首先,我能吃的饱. 我没成家, 没有孩子的问题. 或许买房吧, 想想那也不过是在给自己加负担.

买车吧, 但我出门手机都不想带, 更别提带那么大个车了.

或许我不用工作了. 但是不工作我活着干麻?

关于这个问题的思考突然让我明白了 金钱买不到时间

我现在没有钱, 但我有时间, 如果我不浪费掉, 我可以学到很多东西, 比如长笛,小提琴, 一些外语. 但是如果你老了,有钱了. 但你没办法一下就会说日语,啊拉伯语. 你也不能弹出优美的旋律. 这要时间的积累.

尽可能的利用时间提升自己吧!

游走海口周边

今天第一次参加豆瓣同城活动–12日 周末例行徒步 再寻遵潭古迹

同行不多不少的10人. 除去路费没什么花销, 但感觉比那收门票的地方要有意思. 有图有真相吧.

http://farm8.staticflickr.com/7090/7193201122_c019b1d6ea_z.jpg

美味的菠萝蜜

http://farm8.staticflickr.com/7072/7193235590_80dbae480b_z.jpg

http://farm8.staticflickr.com/7216/7193232972_587802a8e6_z.jpg

很创意的狮子 六神庙, 可以追溯到汉代海南设郡之时.

http://farm6.staticflickr.com/5335/7193241340_f3a7dc345a_z.jpg

一些古村落遗址. http://farm8.staticflickr.com/7235/7193048866_606a11c674_z.jpg

http://farm9.staticflickr.com/8006/7193039430_2d6f4b313d_z.jpg

路上一共发现了三口古井, 应该都有500年历史了. 下到古井里面凉爽呀. 水里有小鱼, 本要抓起来一只, 偶然发现可以做鱼疗. 有几位同学脱鞋子做起了鱼疗, 爽呀! http://farm8.staticflickr.com/7220/7193054818_58c3c4e5ec_z.jpg

http://farm8.staticflickr.com/7211/7193058806_d7d115538b_z.jpg

http://farm8.staticflickr.com/7232/7193055766_8528e79b2f_z.jpg

http://farm9.staticflickr.com/8166/7192979774_10c5b04a2c_z.jpg

海南很多漂亮的大蝴蝶.

有些事会变的

回想过去, 审视现在. 看看自己变了什么?

喜欢上了古典乐

现在不爱听流行歌曲了, 取而代之的是各类纯音乐, 特别是交响乐. 现在听什么类型流行歌曲都感觉心里浮燥的很. 而纯音乐我会听的很认真, 每个音符都想听懂, 每段旋律都要细磨. 很干净, 单纯. 这个变化是因有段时间想学小提琴影响的, 自学了五线谱, 然后学着拉了几首曲子. 虽然小提琴半途而废了, 但养成了听古典乐的喜好.

不太挑食了

在南方待的时间长了, 我开始喜欢吃些很苦的食物, 清炒苦瓜我的最爱哈.

不再纠结与画画

从北京回来后, 相当郁闷, 真的好想在北京画画呀! 不过现在想想都过去了, 画画当我的娱乐吧! 先吃饱吧!

开始照镜子

听上去有点古怪, 可在几年前我一直不喜欢照镜子, 也不知道自己长什么样. 偶尔看到镜子里的自己感觉陌生不舒服. 有点怕生吧. 现在可能是有点自信了吧, 不再怕镜子里的人了.

Sqlite

SQLite 是一个开源的嵌入式关系数据库,实现自包容、零配置、支持事务的SQL数据库引擎。 其特点是高度便携、使用方便、结构紧凑、高效、可靠。 与其他数据库管理系统不同,SQLite 的安装和运行非常简单,在大多数情况下 – 只要确保SQLite的二进制文件存在即可开始创建、连接和使用数据库。如果您正在寻找一个嵌入式数据库项目或解决方案,SQLite是绝对值得考虑。

安装

SQLite on Windows

进入 SQL 下载页面:http://www.sqlite.org/download.html 下载 Windows 下的预编译二进制文件包: sqlite-shell-win32-x86-<build#>.zip sqlite-dll-win32-x86-<build#>.zip 注意: <build#> 是 sqlite 的编译版本好 将 zip 文件解压到你的磁盘,并将解压后的目录添加到系统的 PATH 变量中,以方便在命令行中执行 sqlite 命令。 可选: 如果你计划发布基于 sqlite 数据库的应用程序,你还需要下载源码以便编译和利用其 API sqlite-amalgamation-<build#>.zip

创建首个 SQLite 数据库

现在你已经安装了 SQLite 数据库,接下来我们创建首个数据库。在命令行窗口中输入如下命令来创建一个名为 test.db 的数据库。

sqlite3 test.db

创建表:

sqlite> create table mytable(id integer primary key, value text);
2 columns were created.

该表包含一个名为 id 的主键字段和一个名为 value 的文本字段。

注意: 最少必须为新建的数据库创建一个表或者视图,这么才能将数据库保存到磁盘中,否则数据库不会被创建。

接下来往表里中写入一些数据:

sqlite> insert into mytable(id, value) values(1, 'Micheal');
sqlite> insert into mytable(id, value) values(2, 'Jenny');
sqlite> insert into mytable(value) values('Francis');
sqlite> insert into mytable(value) values('Kerk');

查询数据:

sqlite> select * from test;
1|Micheal
2|Jenny
3|Francis
4|Kerk

设置格式化查询结果:

sqlite> .mode column;
sqlite> .header on;
sqlite> select * from test;
id          value
----------- -------------
1           Micheal
2           Jenny
3           Francis
4           Kerk

.mode column 将设置为列显示模式,.header 将显示列名。

修改表结构,增加列:

sqlite> alter table mytable add column email text not null '' collate nocase;;

创建视图:

sqlite> create view nameview as select * from mytable;

创建索引:

sqlite> create index test_idx on mytable(value);

一些有用的 SQLite 命令

显示表结构:

sqlite> .schema [table]

获取所有表和视图:

sqlite > .tables

获取指定表的索引列表:

sqlite > .indeces [table ]

导出数据库到 SQL 文件:

sqlite > .output [filename ]
sqlite > .dump
sqlite > .output stdout

从 SQL 文件导入数据库:

sqlite > .read [filename ]

格式化输出数据到 CSV 格式:

sqlite >.output [filename.csv ]
sqlite >.separator ,
sqlite > select * from test;
sqlite >.output stdout

从 CSV 文件导入数据到表中:

sqlite >create table newtable ( id integer primary key, value text );
sqlite >.import [filename.csv ] newtable

备份数据库:

/* usage: sqlite3 [database] .dump > [filename] */
sqlite3 mytable.db .dump > backup.sql

恢复数据库:

/* usage: sqlite3 [database ] < [filename ] */
sqlite3 mytable.db < backup.sql

定一个简单的小任务

每天写blog, 相当于日记吧

每天检查下 todo

远程启动电脑

我家里有台台式机挂了动态域名24小时在线的,然后我的笔记本平常是连入局域网时常处于关机状态的。有时候在外面突然记起什么想在家里笔记本上弄点东西,或者想 eix-sync && emerge -DuvN world 一下,老开着吧挺浪费电的,不过好就好在现在大多数的主板都支持 Wake On Lan 远程唤醒的功能,原理就是向其所在的局域网广播地址发送一个特殊的UDP广播包(又叫Magic packet, 9号端口), 这个广播包结构很简单,数据段就是6个0xFF接上需要被唤醒的机器的网卡物理地址(重复16个), 于是结合 perl 和 socat,很容易弄一条命令就能唤醒我的笔记本了,如下:

echo -n 00:18:8B:B9:3A:05 | perl -aF: -ne ‘print chr(0xFF)x6 . join( “”, map{ chr hex } @F )x16′ | socat – UDP4-DATAGRAM:255.255.255.255:9,broadcast

这样就能啥时候想开机就开机了,用完再关,省电节能呵呵。

英语字根 


1, ag=do, act 做,动
2, agri=field 田地,农田(agri也做agro, agr)  
3, ann=year年  
4, audi=hear听  
5, bell=war战争  
6, brev=short短  
7, ced, ceed, cess=go行走  
8, cept=take拿取  
9, cid, cis=cut, kill切,杀  
10, circ=ring环,圈  
11, claim, clam=cry, shout喊叫  
12, clar=clear清楚,明白  
 13, clud=close, shut关闭  
14, cogn=known知道  
15, cord=heart心  
16, corpor=body体  
 17, cred=believe, trust相信,信任  
18, cruc=cross 十字  
19, cur=care关心  
20, cur, curs, cour, cours=run跑  
21, dent=tooth牙齿  
 22, di=day 日  
23, dict=say说  
24, dit=give给  
25, don=give给  
26, du=tow二  
 27, duc, duct=lead引导  
28, ed=eat吃  
29, equ=equal等,均,平  
30, ev=age年龄,寿命,时代,时期  
31, fact=do, make做,作  
32, fer=bring, carry带拿  
33, flor=flower花  
34, flu=flow流  
35, fus=pour灌,流,倾泄  
36, grad=step, go, grade步,走,级  
37, gram=write, draw写,画,文字,图形  
38, graph=write, records写,画,记录器,图形  
39, gress=go, walk 行走  
40, habit=dwell居住  
41, hibit=hold拿,持  
42, hospit=guest客人  
 43, idio=peculiar, own, private, proper特殊的,个人的,专有的  
44, insul=island岛  
 45, it=go行走  
46, ject=throw投掷  
47, juven=young年轻,年少  
48, lectchoose, gather选,收  
49, lev=raise举,升  
50, liber=free自由  
51, lingu=language语言  
 52, liter=letter文字,字母  
53, loc=place地方  
54, log=speak言,说  
55, loqu=speak言,说  
56, lun=moon月亮  
57, man=dwell, stay居住,停留  
58, manu=hand手  
59, mar=sea海  
 60, medi=middle中间  
61, memor=memory记忆  
62, merg=dip, sink 沉,没  
63, migr=remove, move迁移  
64, milit=soldier兵  
65, mini=**all, little小  
 66, mir=wonder惊奇  
67, miss=send 投,送,发(miss也作mit)  
68, mob=move动  
69, mort=death死  
70, mot=move移动,动  
 71, nomin=name名  
72, nov=new新  
73, numer=number 数  
74, onym=name 名  
75, oper=work工作  
76, ori=rise升起  
77, paci=peace和平,平静  
78, pel=push, drive 推,逐,驱  
79, pend, pens=hang悬挂/weigh称量/pay支出,付钱,花费  
80, pet=seek追求  
 81, phon=sound声音  
82, pict=paint画,描绘  
83, plen=full满,全  
84, plic=fold折,重叠  
 85, pon=put放置  
86, popul=people人民  
87, port=carry拿,带,运  
88, pos=put放置  
 89, preci=price价值  
90, punct=point, prick点,刺  
91, pur=pure清,纯,净  
 92, rect=right, straight正,直  
93, rupt=break破  
94, sal=salt盐  
 95, scend, scens=climb爬,攀  
96, sci=know知  
97, sec, sequ=follow跟随  
98, sect=cut 切割  
99, sent, sens=feel感觉  
100, sid=sit坐  
101, sist=stand站立  
102, son=sound声音  
103, spect=look看  
104, spir=breathe呼吸  
105, tail=cut切割  
 106, tain, ten, tin=hold握,持,守  
107, tect=cover掩盖  
108, tele=far远  
 109, tempor=time时  
110, tend(tens, tent)=stretch伸  
111, terr=land, earth土地,陆地  
112, text=weave纺织  
113, tract=draw拉,抽,引  
114, un=one一  
115, urb=city城市  
 116, vac, vacu=empty空  
117, vad, vas=walk, go行走  
118, vari=change变化  
 119, ven=come来  
120, vert, vers=turn转  
121, vi, via=way道路  
122, vis, vid=see看  
 123, vit=life生命  
124, viv=live活  
第二部分,多认词根,多识单词。  
125, aer(o)空气,空中,航空  
 126, alt高  
127, am爱  
128, ambul行走  
129, anim生命,活,心神,意见  
130, anthrop(o)人,人类  
 131, aqu水  
132, arch统治者,首脑archy 统治  
133, avi鸟  
134, bat打  
135, biblio书  
136, birg战斗,打  
137, cad, cas降落,降临  
 138, cert 确定,确信  
139, chron时  
140, cid降落,降临  
141, clin倾  
142, co**(o)世界,宇宙  
143, cracy统治crat支持  
144, cub躺,卧  
145, cult耕,培养  
146, cycl(o)圈,环,轮  
147, dem(o)人民  
 148, dexter右  
149, doc教  
150, dom屋,家  
151, dorm睡眠  
152, drom跑  
153, ego我  
 154, err漫游,走,行  
155, fabl, fabul 言  
156, feder联盟  
157, ferv沸,热  
158, fict, fig塑造,虚构  
159, fid信任  
160, fil线  
 161, flat 吹  
162, flect, flex弯曲  
163, flict打击  
164, frag, fract破,折  
165, frig冷  
166, fug 逃,散  
167, fund, found底,基础  
168, gam婚姻  
169, gram谷物,谷粒  
170, grav重  
171, greg群,集合  
172, gyn, gynce(o)妇女  
173, hal呼吸  
174, helic(o)螺旋  
175, hes, her粘着  
 176, ign火  
177, integr整,全  
178, junct连接,连结  
179, later边  
180, leg读 181, leg, legis法  
182, luc光  
183, lumin光  
184, magn(i)大  
185, matr(i),metro母  
 186, mega大  
187, mens测量  
188, ment心,神,智,思,意  
189, min伸出,突出  
190, misc混合,混杂  
 191, mis(o)恨,厌恶  
192, mon告诫,提醒  
193, mon单独,一个  
194, mur墙  
195, mut变换  
196, nat 诞生  
197, nav船  
198, nect, nex结,系  
199, negr, nigr黑  
200, nihil无  
201, noc, nox伤害  
202, noct(i)夜  
203, norm规范,正规,正常  
204, nutri营养  
205, orn装饰  
206, par生,产  
 207, parl说,谈  
208, past喂,食  
209, path(o),pathy疾病,疗法  
210, patr(i)父,祖  
 211, ped脚,足  
212, ped儿童,小孩  
213, petr(o)石  
214, phag吃  
215, phil(o)爱  
 216, phob(ia)怕  
217, plex重叠,重  
218, polis城市  
219, prim第一,最初  
220, radic根  
 221, ras, rad擦,刮  
222, rid, ris笑  
223, rod, ros咬,啮  
224, rot轮,转  
225, rud原始,粗野  
 226, rur, rus农村  
227, sat, satis, satur足,满,饱  
228, sen老  
229, simil, simul相似,相同  
230, sol单独  
231, sol太阳  
232, soph智慧  
233, sper希望  
234, spers, spars散,撒  
 235, splend发光,照耀  
236, stell星  
237, tact, tag触  
238, the(o)神  
239, ton音  
 240, tort扭  
241, tour迂回,转  
242, trud, trus推,冲  
243, tut, tuit监护,看管  
244, umbr阴影  
245, ut, us用  
246, vas走,漫游  
247, val强  
248, van空,无  
249, ver(i)真实  
 250, voc, vok声音,叫喊  
251, vol, volunt意志,意愿  
252,volu, volv滚,转

可以用来参考的作息时间表

7:30:起床。英国威斯敏斯特大学的研究人员发现,那些在早上5:22―7:21 分起床的人,其血液中有一种能引起心脏病的物质含量较高,因此,在7:21之后起床对身体健康更加有益。 打开台灯。“一醒来,就将灯打开,这样将会重新调整体内的生物钟,调整睡眠和醒来模式。”拉夫堡大学睡眠研究中心教授吉姆·霍恩说。 喝一杯水。水是身体内成千上万化学反应得以进行的必需物质。早上喝一杯清水,可以补充晚上的缺水状态。

7:30―8:00:在早饭之前刷牙。“在早饭之前刷牙可以防止牙齿的腐蚀,因为刷牙之后,可以在牙齿外面涂上一层含氟的保护层。要么,就等早饭之后半小时再刷牙。”英国牙齿协会健康和安全研究人员戈登·沃特金斯说。

8:00―8:30:吃早饭。“早饭必须吃,因为它可以帮助你维持血糖水平的稳定。”伦敦大学国王学院营养师凯文·威尔伦说。早饭可以吃燕麦粥等,这类食物具有较低的血糖指数。

8:30―9:00:避免运动。来自布鲁奈尔大学的研究人员发现,在早晨进行锻炼的运动员更容易感染疾病,因为免疫系统在这个时间的功能最弱。步行上班。马萨诸塞州大学医学院的研究人员发现,每天走路的人,比那些久坐不运动的人患感冒病的几率低25%。

9:30:开始一天中最困难的工作。纽约睡眠中心的研究人员发现,大部分人在每天醒来的一两个小时内头脑最清醒。

10:30:让眼睛离开屏幕休息一下。如果你使用电脑工作,那么每工作一小时,就让眼睛休息3分钟。

11:00:吃点水果。这是一种解决身体血糖下降的好方法。吃一个橙子或一些红色水果,这样做能同时补充体内的铁含量和维生素C含量。

13:00:在面包上加一些豆类蔬菜。你需要一顿可口的午餐,并且能够缓慢地释放能量。“烘烤的豆类食品富含纤维素,番茄酱可以当作是蔬菜的一部分。”维伦博士说。

14:30―15:30:午休一小会儿。雅典的一所大学研究发现,那些每天中午午休30分钟或更长时间,每周至少午休3次的人,因心脏病死亡的几率会下降37%。

16:00:喝杯酸奶。这样做可以稳定血糖水平。在每天三餐之间喝些酸牛奶,有利于心脏健康。

17:00―19:00:锻炼身体。根据体内的生物钟,这个时间是运动的最佳时间,舍菲尔德大学运动学医生瑞沃·尼克说。

19:30:晚餐少吃点。晚饭吃太多,会引起血糖升高,并增加消化系统的负担,影响睡眠。晚饭应该多吃蔬菜,少吃富含卡路里和蛋白质的食物。吃饭时要细嚼慢咽。

21:45:看会电视。这个时间看会儿电视放松一下,有助于睡眠,但要注意,尽量不要躺在床上看电视,这会影响睡眠质量。

23:00:洗个热水澡。“体温的适当降低有助于放松和睡眠。”拉夫堡大学睡眠研究中心吉姆·霍恩教授说。

23:30:上床睡觉。如果你早上7点30起床,现在入睡可以保证你享受8小时充足的睡眠。

任何试图更改生物钟的行为,都将给身体留下莫名其妙的疾病,20、30年之后再后悔,已经来不及了。

一、晚上9-11点为免疫系统(淋巴)排毒时间,此段时间应安静或听音乐。

二、晚间11-凌晨1点,肝的排毒,需在熟睡中进行。

三、凌晨1-3点,胆的排毒,亦同。

四、凌晨3-5点,肺的排毒。此即为何咳嗽的人在这段时间咳得最剧烈,因排毒动作已走到肺;不应用止咳药,以免抑制废积物的排除。

五、凌晨5-7点,大肠的排毒,应上厕所排便。

六、凌晨7-9点,小肠大量吸收营养的时段,应吃早餐。疗病者最好早吃,在6点半前,养生者在7点半前,不吃早餐者应改变习惯,即使拖到9、10点吃都比不吃好。

七、半夜至凌晨4点为脊椎造血时段,必须熟睡,不宜熬夜。

往事–画

2010年在北京的时候. 美好的回忆.

http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-1.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-2.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-3.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-4.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-5.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-6.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-7.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-8.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-9.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-10.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-11.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-12.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-13.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-14.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-15.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-16.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-171.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-18.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-19.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-20.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-21.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-22.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-23.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-24.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-25.jpg http://catpainter.tk/wp-content/uploads/2012/05/wpid-resize-26.jpg

Serial Programming Guide for POSIX Operating Systems

  • Asynchronous Communications
  • Synchronous Communications
  • Accessing Serial Ports
  • Chapter 2, Configuring the Serial Port

    Chapter 3, MODEM Communications

    Chapter 4, Advanced Serial Programming

  • Selecting Input from a Serial Port
  • Appendix A, Pinouts

    Appendix B, ASCII Control Codes


    Introduction

    The Serial Programming Guide for POSIX Operating Systems will teach
    you how to successfully, efficiently, and portably program the serial
    ports on your UNIX® workstation or PC. Each chapter provides
    programming examples that use the POSIX (Portable Standard for UNIX)
    terminal control functions and should work with very few modifications
    under IRIX®, HP-UX, SunOS®, Solaris®, Digital UNIX®, Linux®, and most
    other UNIX operating systems. The biggest difference between operating
    systems that you will find is the filenames used for serial port device
    and lock files.

    This guide is organized into the following chapters and appendices:


    Chapter 1, Basics of Serial
    Communications

    This chapter introduces serial communications, RS-232 and other
    standards that are used on most computers as well as how to access a
    serial port from a C program.

    What Are Serial Communications?

    Computers transfer information (data) one or more bits at a time.
    Serial refers to the transfer of data one bit at a time. Serial
    communications include most network devices, keyboards, mice, MODEMs,
    and terminals.

    When doing serial communications each word (i.e. byte or character)
    of data you send or receive is sent one bit at a time. Each bit is
    either on or off. The terms you’ll hear sometimes are
    mark
    for the on state and space for the off
    state.

    The speed of the serial data is most often expressed as
    bits-per-second (“bps”) or baudot rate (“baud”). This just represents
    the number of ones and zeroes that can be sent in one second. Back at
    the dawn of the computer age, 300 baud was considered fast, but today
    computers can handle RS-232 speeds as high as 430,800 baud! When the
    baud rate exceeds 1,000, you’ll usually see the rate shown in kilo
    baud, or kbps (e.g. 9.6k, 19.2k, etc). For rates above 1,000,000 that
    rate is shown in megabaud, or Mbps (e.g. 1.5Mbps).

    When referring to serial devices or ports, they are either labeled
    as Data Communications Equipment (“DCE”) or Data Terminal
    Equipment
    (“DTE”). The difference between these is simple – every
    signal pair, like transmit and receive, is swapped. When connecting two
    DTE or two DCE interfaces together, a serial null-MODEM cable or
    adapter is used that swaps the signal pairs.

    What Is RS-232?

    RS-232 is a standard electrical interface for serial communications
    defined by the Electronic Industries
    Association (“EIA”)
    . RS-232 actually comes in 3 different flavors
    (A, B, and C) with each one defining a different voltage range for the
    on
    and off levels. The most commonly used variety is
    RS-232C, which defines a mark (on) bit as a voltage between -3V and
    -12V and a space (off) bit as a voltage between +3V and +12V. The
    RS-232C specification says these signals can go about 25 feet (8m)
    before they become unusable. You can usually send signals a bit farther
    than this as long as the baud is low enough.

    Besides wires for incoming and outgoing data, there are others that
    provide timing, status, and handshaking:

    Table 1 – RS-232 Pin
    Assignments
    Pin Description Pin Description Pin Description Pin Description Pin Description
    1 Earth Ground 6 DSR – Data Set
    Ready
    11 Unassigned 16 Secondary RXD 21 Signal Quality Detect
    2 TXD – Transmitted Data 7 GND
    – Logic Ground
    12 Secondary DCD 17 Receiver Clock 22 Ring Detect
    3 RXD – Received Data 8 DCD
    – Data Carrier Detect
    13 Secondary CTS 18 Unassigned 23 Data Rate Select
    4 RTS – Request To Send 9 Reserved 14 Secondary TXD 19 Secondary
    RTS
    24 Transmit Clock
    5 CTS – Clear To Send 10 Reserved 15 Transmit Clock 20 DTR – Data Terminal
    Ready
    25 Unassigned

    Two standards for serial interfaces you may also see are RS-422 and
    RS-574. RS-422 uses lower voltages and differential signals to
    allow cable lengths up to about 1000ft (300m). RS-574 defines the 9-pin
    PC serial connector and voltages.

    Signal Definitions

    The RS-232 standard defines some 18 different signals for serial
    communications. Of these, only six are generally available in the UNIX
    environment.

    GND – Logic Ground

    Technically the logic ground is not a signal, but without it none of
    the other signals will operate. Basically, the logic ground acts as a
    reference voltage so that the electronics know which voltages are
    positive or negative.

    TXD – Transmitted Data

    The TXD signal carries data transmitted from your workstation to the
    computer or device on the other end (like a MODEM). A mark voltage is
    interpreted as a value of 1, while a space voltage is interpreted as a
    value of 0.

    RXD – Received Data

    The RXD signal carries data transmitted from the computer or device
    on the other end to your workstation. Like TXD, mark and space voltages
    are interpreted as 1 and 0, respectively.

    DCD – Data Carrier Detect

    The DCD signal is received from the computer or device on the other
    end of your serial cable. A space voltage on this signal line indicates
    that the computer or device is currently connected or on line. DCD is
    not always used or available.

    DTR – Data Terminal Ready

    The DTR signal is generated by your workstation and tells the
    computer or device on the other end that you are ready (a space
    voltage) or not-ready (a mark voltage). DTR is usually enabled
    automatically whenever you open the serial interface on the
    workstation.

    CTS – Clear To Send

    The CTS signal is received from the other end of the serial cable. A
    space voltage indicates that is alright to send more serial data from
    your workstation.

    CTS is usually used to regulate the flow of serial data from your
    workstation to the other end.

    RTS – Request To Send

    The RTS signal is set to the space voltage by your
    workstation to indicate that more data is ready to be sent.

    Like CTS, RTS helps to regulate the flow of data between your
    workstation and the computer or device on the other end of the serial
    cable. Most workstations leave this signal set to the space voltage all
    the time.

    Asynchronous Communications

    For the computer to understand the serial data coming into it, it
    needs some way to determine where one character ends and the next
    begins. This guide deals exclusively with asynchronous serial
    data.

    In asynchronous mode the serial data line stays in the mark (1)
    state until a character is transmitted. A start bit preceeds
    each character and is followed immediately by each bit in the
    character, an optional parity bit, and one or more stop bits.
    The start bit is always a space (0) and tells the computer that new
    serial data is available. Data can be sent or received at any time,
    thus the name asynchronous.

    Figure 1 – Asynchronous Data Transmission

    The optional parity bit is a simple sum of the data bits indicating
    whether or not the data contains an even or odd number of 1 bits. With
    even parity
    , the parity bit is 0 if there is an even number of 1′s
    in the character. With odd parity, the parity bit is 0 if there
    is an odd number of 1′s in the data. You may also hear the terms
    space parity
    , mark parity, and no parity. Space
    parity means that the parity bit is always 0, while mark parity means
    the bit is always 1. No parity means that no parity bit is present or
    transmitted.

    The remaining bits are called stop bits. There can be 1, 1.5, or 2
    stop bits between characters and they always have a value of 1. Stop
    bits traditionally were used to give the computer time to process the
    previous character, but now only serve to synchronize the receiving
    computer to the incoming characters.

    Asynchronous data formats are usually expressed as “8N1″, “7E1″, and
    so forth. These stand for “8 data bits, no parity, 1 stop bit” and “7
    data bits, even parity, 1 stop bit” respectively.

    What Are Full Duplex and Half Duplex?

    Full duplex means that the computer can send and receive data
    simultaneously – there are two separate data channels (one coming in,
    one going out).

    Half duplex means that the computer cannot send or receive
    data at the same time. Usually this means there is only a single data
    channel to talk over. This does not mean that any of the RS-232 signals
    are not used. Rather, it usually means that the communications link
    uses some standard other than RS-232 that does not support full duplex
    operation.

    Flow Control

    It is often necessary to regulate the flow of data when transferring
    data between two serial interfaces. This can be due to limitations in
    an intermediate serial communications link, one of the serial
    interfaces, or some storage media. Two methods are commonly used for
    asynchronous data.

    The first method is often called “software” flow control and uses
    special characters to start (XON or DC1, 021 octal) or stop (XOFF or
    DC3, 023 octal) the flow of data. These characters are defined in the
    American Standard Code for Information Interchange (“ASCII”)
    . While
    these codes are useful when transferring textual information, they
    cannot be used when transferring other types of information without
    special programming.

    The second method is called “hardware” flow control and uses the
    RS-232 CTS and RTS signals instead of special characters. The receiver
    sets CTS to the space voltage when it is ready to receive more data and
    to the mark voltage when it is not ready. Likewise, the sender sets RTS
    to the space voltage when it is ready to send more data. Because
    hardware flow control uses a separate set of signals, it is much faster
    than software flow control which needs to send or receive multiple bits
    of information to do the same thing. CTS/RTS flow control is not
    supported by all hardware or operating systems.

    What Is a Break?

    Normally a receive or transmit data signal stays at the mark voltage
    until a new character is transferred. If the signal is dropped to the
    space voltage for a long period of time, usually 1/4 to 1/2 second,
    then a break condition is said to exist.

    A break is sometimes used to reset a communications line or change
    the operating mode of communications hardware like a MODEM.
    Chapter 3, Talking to MODEMs
    covers these applications in more
    depth.

    Synchronous Communications

    Unlike asynchronous data, synchronous data appears as a constant
    stream of bits. To read the data on the line, the computer must provide
    or receive a common bit clock so that both the sender and receiver are
    synchronized.

    Even with this synchronization, the computer must mark the beginning
    of the data somehow. The most common way of doing this is to use a data
    packet protocol like Serial Data Link Control (“SDLC”) or High-Speed
    Data Link Control (“HDLC”).

    Each protocol defines certain bit sequences to represent the
    beginning and end of a data packet. Each also defines a bit sequence
    that is used when there is no data. These bit sequences allow the
    computer see the beginning of a data packet.

    Because synchronous protocols do not use per-character
    synchronization bits they typically provide at least a 25% improvement
    in performance over asynchronous communications and are suitable for
    remote networking and configurations with more than two serial
    interfaces.

    Despite the speed advantages of synchronous communications, most
    RS-232 hardware does not support it due to the extra hardware and
    software required.

    Accessing Serial Ports

    Like all devices, UNIX provides access to serial ports via device
    files
    . To access a serial port you simply open the corresponding
    device file.

    Serial Port Files

    Each serial port on a UNIX system has one or more device files
    (files in the /dev directory) associated with it:

    Table 2 – Serial Port Device
    Files
    System Port 1 Port 2
    IRIX® /dev/ttyf1 /dev/ttyf2
    HP-UX /dev/tty1p0 /dev/tty2p0
    Solaris®/SunOS® /dev/ttya /dev/ttyb
    Linux® /dev/ttyS0 /dev/ttyS1
    Digital UNIX® /dev/tty01 /dev/tty02

    Opening a Serial Port

    Since a serial port is a file, the open(2) function is used
    to access it. The one hitch with UNIX is that device files are usually
    not accessable by normal users. Workarounds include changing the access
    permissions to the file(s) in question, running your program as the
    super-user (root), or making your program set-userid so that it runs as
    the owner of the device file.

    For now we’ll assume that the file is accessable by all users. The
    code to open serial port 1 on an sgi® workstation running
    IRIX is:

      Listing 1 – Opening a serial port.

      #include <stdio.h>   /* Standard input/output definitions */
      #include <string.h>  /* String function definitions */
      #include <unistd.h>  /* UNIX standard function definitions */
      #include <fcntl.h>   /* File control definitions */
      #include <errno.h>   /* Error number definitions */
      #include <termios.h> /* POSIX terminal control definitions */
      
      /*
       * 'open_port()' - Open serial port 1.
       *
       * Returns the file descriptor on success or -1 on error.
       */
      
      int
      open_port(void)
      {
        int fd; /* File descriptor for the port */
      
        fd = open("/dev/ttyf1", O_RDWR | O_NOCTTY | O_NDELAY);
        if (fd == -1)
        {
         /*
          * Could not open the port.
          */
      
          perror("open_port: Unable to open /dev/ttyf1 - ");
        }
        else
          fcntl(fd, F_SETFL, 0);
      
        return (fd);
      }
      

    Other systems would require the corresponding device file name, but
    otherwise the code is the same.

    Open Options

    You’ll notice that when we opened the device file we used two other
    flags along with the read+write mode:

      fd = open("/dev/ttyf1", O_RDWR | O_NOCTTY | O_NDELAY);
      

    The O_NOCTTY flag tells UNIX that this program doesn’t want
    to be the “controlling terminal” for that port. If you don’t specify
    this then any input (such as keyboard abort signals and so forth) will
    affect your process. Programs like getty(1M/8) use this feature
    when starting the login process, but normally a user program does not
    want this behavior.

    The O_NDELAY flag tells UNIX that this program doesn’t care
    what state the DCD signal line is in – whether the other end of the
    port is up and running. If you do not specify this flag, your process
    will be put to sleep until the DCD signal line is the space voltage.

    Writing Data to the Port

    Writing data to the port is easy – just use the write(2)
    system call to send data it:

      n = write(fd, "ATZ\r", 4);
      if (n < 0)
        fputs("write() of 4 bytes failed!\n", stderr);
      

    The write function returns the number of bytes sent or -1 if
    an error occurred. Usually the only error you’ll run into is EIO
    when a MODEM or data link drops the Data Carrier Detect (DCD) line.
    This condition will persist until you close the port.

    Reading Data from the Port

    Reading data from a port is a little trickier. When you operate the
    port in raw data mode, each read(2) system call will return
    however many characters are actually available in the serial input
    buffers. If no characters are available, the call will block (wait)
    until characters come in, an interval timer expires, or an error
    occurs. The read function can be made to return immediately by
    doing the following:

      fcntl(fd, F_SETFL, FNDELAY);
      

    The FNDELAY option causes the read function to return
    0 if no characters are available on the port. To restore normal
    (blocking) behavior, call fcntl() without the FNDELAY
    option:

      fcntl(fd, F_SETFL, 0);
      

    This is also used after opening a serial port with the O_NDELAY
    option.

    Closing a Serial Port

    To close the serial port, just use the close system call:

      close(fd);
      

    Closing a serial port will also usually set the DTR signal low which
    causes most MODEMs to hang up.


    Chapter 2, Configuring the Serial
    Port

    This chapter discusses how to configure a serial port from C using
    the POSIX termios interface.

    The POSIX Terminal Interface

    Most systems support the POSIX terminal (serial) interface for
    changing parameters such as baud rate, character size, and so on. The
    first thing you need to do is include the file <termios.h>;
    this defines the terminal control structure as well as the POSIX
    control functions.

    The two most important POSIX functions are tcgetattr(3) and
    tcsetattr(3)
    . These get and set terminal attributes, respectively;
    you provide a pointer to a termios structure that contains all
    of the serial options available:

    Table 3 – Termios
    Structure Members
    Member Description
    c_cflag Control options
    c_lflag Line options
    c_iflag Input options
    c_oflag Output options
    c_cc Control characters
    c_ispeed Input baud (new interface)
    c_ospeed Output baud (new interface)

    Control Options

    The c_cflag member controls the baud rate, number of data bits,
    parity, stop bits, and hardware flow control. There are constants for
    all of the supported configurations.

    Table 4 –
    Constants for the c_cflag Member
    Constant Description
    CBAUD Bit mask for baud rate
    B0 0 baud (drop DTR)
    B50 50 baud
    B75 75 baud
    B110 110 baud
    B134 134.5 baud
    B150 150 baud
    B200 200 baud
    B300 300 baud
    B600 600 baud
    B1200 1200 baud
    B1800 1800 baud
    B2400 2400 baud
    B4800 4800 baud
    B9600 9600 baud
    B19200 19200 baud
    B38400 38400 baud
    B57600 57,600 baud
    B76800 76,800 baud
    B115200 115,200 baud
    EXTA External rate clock
    EXTB External rate clock
    CSIZE Bit mask for data bits
    CS5 5 data bits
    CS6 6 data bits
    CS7 7 data bits
    CS8 8 data bits
    CSTOPB 2 stop bits (1 otherwise)
    CREAD Enable receiver
    PARENB Enable parity bit
    PARODD Use odd parity instead of even
    HUPCL Hangup (drop DTR) on last close
    CLOCAL Local line – do not change “owner” of port
    LOBLK Block job control output
    CNEW_RTSCTS

    CRTSCTS
    Enable hardware flow control (not supported on all
    platforms)

    The c_cflag member contains two options that should always be
    enabled, CLOCAL and CREAD. These will ensure that your
    program does not become the ‘owner’ of the port subject to sporatic job
    control and hangup signals, and also that the serial interface driver
    will read incoming data bytes.

    The baud rate constants (CBAUD, B9600, etc.) are used
    for older interfaces that lack the c_ispeed and c_ospeed
    members. See the next section for information on the POSIX functions
    used to set the baud rate.

    Never initialize the c_cflag (or any other flag)
    member directly; you should always use the bitwise AND, OR, and NOT
    operators to set or clear bits in the members. Different operating
    system versions (and even patches) can and do use the bits differently,
    so using the bitwise operators will prevent you from clobbering a bit
    flag that is needed in a newer serial driver.

    Setting the Baud Rate

    The baud rate is stored in different places depending on the
    operating system. Older interfaces store the baud rate in the c_cflag
    member using one of the baud rate constants in table 4, while newer
    implementations provide the c_ispeed and c_ospeed members
    that contain the actual baud rate value.

    The cfsetospeed(3) and cfsetispeed(3) functions are
    provided to set the baud rate in the termios structure
    regardless of the underlying operating system interface. Typically
    you’d use the following code to set the baud rate:

      Listing 2 – Setting the baud rate.

      struct termios options;
      
      /*
       * Get the current options for the port...
       */
      
      tcgetattr(fd, &options);
      
      /*
       * Set the baud rates to 19200...
       */
      
      cfsetispeed(&options, B19200);
      cfsetospeed(&options, B19200);
      
      /*
       * Enable the receiver and set local mode...
       */
      
      options.c_cflag |= (CLOCAL | CREAD);
      
      /*
       * Set the new options for the port...
       */
      
      tcsetattr(fd, TCSANOW, &options);
      

    The tcgetattr(3) function fills the termios structure you
    provide with the current serial port configuration. After we set the
    baud rates and enable local mode and serial data receipt, we select the
    new configuration using tcsetattr(3). The TCSANOW
    constant specifies that all changes should occur immediately without
    waiting for output data to finish sending or input data to finish
    receiving. There are other constants to wait for input and output to
    finish or to flush the input and output buffers.

    Most systems do not support different input and output speeds, so be
    sure to set both to the same value for maximum portability.

    Table 5 –
    Constants for tcsetattr
    Constant Description
    TCSANOW Make changes now without waiting for data to
    complete
    TCSADRAIN Wait until everything has been transmitted
    TCSAFLUSH Flush input and output buffers and make the
    change

    Setting the Character Size

    Unlike the baud rate, there is no convienience function to set the
    character size. Instead you must do a little bitmasking to set things
    up. The character size is specified in bits:

      options.c_cflag &= ~CSIZE; /* Mask the character size bits */
      options.c_cflag |= CS8;    /* Select 8 data bits */
      

    Setting Parity Checking

    Like the character size you must manually set the parity enable and
    parity type bits. UNIX serial drivers support even, odd, and no parity
    bit generation. Space parity can be simulated with clever coding.

    • No parity (8N1):
    • options.c_cflag &= ~PARENB
      options.c_cflag &= ~CSTOPB
      options.c_cflag &= ~CSIZE;
      options.c_cflag |= CS8;
      
    • Even parity (7E1):
    • options.c_cflag |= PARENB
      options.c_cflag &= ~PARODD
      options.c_cflag &= ~CSTOPB
      options.c_cflag &= ~CSIZE;
      options.c_cflag |= CS7;
      
    • Odd parity (7O1):
    • options.c_cflag |= PARENB
      options.c_cflag |= PARODD
      options.c_cflag &= ~CSTOPB
      options.c_cflag &= ~CSIZE;
      options.c_cflag |= CS7;
      
    • Space parity is setup the same as no parity (7S1):
    • options.c_cflag &= ~PARENB
      options.c_cflag &= ~CSTOPB
      options.c_cflag &= ~CSIZE;
      options.c_cflag |= CS8;
      

    Setting Hardware Flow Control

    Some versions of UNIX support hardware flow control using the CTS
    (Clear To Send) and RTS (Request To Send) signal lines. If the
    CNEW_RTSCTS
    or CRTSCTS constants are defined on your system
    then hardware flow control is probably supported. Do the following to
    enable hardware flow control:

      options.c_cflag |= CNEW_RTSCTS;    /* Also called CRTSCTS */
      

    Similarly, to disable hardware flow control:

      options.c_cflag &= ~CNEW_RTSCTS;
      

    Local Options

    The local modes member c_lflag controls how input characters
    are managed by the serial driver. In general you will configure the
    c_lflag
    member for canonical or raw input.

    Table 6 –
    Constants for the c_lflag Member
    Constant Description
    ISIG Enable SIGINTR, SIGSUSP, SIGDSUSP, and SIGQUIT
    signals
    ICANON Enable canonical input (else raw)
    XCASE Map uppercase \lowercase (obsolete)
    ECHO Enable echoing of input characters
    ECHOE Echo erase character as BS-SP-BS
    ECHOK Echo NL after kill character
    ECHONL Echo NL
    NOFLSH Disable flushing of input buffers after
    interrupt or quit characters
    IEXTEN Enable extended functions
    ECHOCTL Echo control characters as ^char and delete as
    ~?
    ECHOPRT Echo erased character as character erased
    ECHOKE BS-SP-BS entire line on line kill
    FLUSHO Output being flushed
    PENDIN Retype pending input at next read or input char
    TOSTOP Send SIGTTOU for background output

    Choosing Canonical Input

    Canonical input is line-oriented. Input characters are put into a
    buffer which can be edited interactively by the user until a CR
    (carriage return) or LF (line feed) character is received.

    When selecting this mode you normally select the ICANON,
    ECHO
    , and ECHOE options:

      options.c_lflag |= (ICANON | ECHO | ECHOE);
      

    Choosing Raw Input

    Raw input is unprocessed. Input characters are passed through
    exactly as they are received, when they are received. Generally you’ll
    deselect the ICANON, ECHO, ECHOE, and ISIG
    options when using raw input:

      options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
      

    A Note About Input Echo

    Never enable input echo (ECHO, ECHOE) when sending
    commands to a MODEM or other computer that is echoing characters, as
    you will generate a feedback loop between the two serial interfaces!

    Input Options

    The input modes member c_iflag controls any input processing
    that is done to characters received on the port. Like the c_cflag
    field, the final value stored in c_iflag is the bitwise OR of
    the desired options.

    Table 7 –
    Constants for the c_iflag Member
    Constant Description
    INPCK Enable parity check
    IGNPAR Ignore parity errors
    PARMRK Mark parity errors
    ISTRIP Strip parity bits
    IXON Enable software flow control (outgoing)
    IXOFF Enable software flow control (incoming)
    IXANY Allow any character to start flow again
    IGNBRK Ignore break condition
    BRKINT Send a SIGINT when a break condition is detected
    INLCR Map NL to CR
    IGNCR Ignore CR
    ICRNL Map CR to NL
    IUCLC Map uppercase to lowercase
    IMAXBEL Echo BEL on input line too long

    Setting Input Parity Options

    You should enable input parity checking when you have enabled parity
    in the c_cflag member (PARENB). The revelant constants
    for input parity checking are INPCK, IGNPAR, PARMRK
    , and ISTRIP. Generally you will select INPCK and
    ISTRIP
    to enable checking and stripping of the parity bit:

      options.c_iflag |= (INPCK | ISTRIP);
      

    IGNPAR is a somewhat dangerous option that tells the serial
    driver to ignore parity errors and pass the incoming data through as if
    no errors had occurred. This can be useful for testing the quality of a
    communications link, but in general is not used for practical reasons.

    PARMRK causes parity errors to be ‘marked’ in the input
    stream using special characters. If IGNPAR is enabled, a NUL
    character (000 octal) is sent to your program before every character
    with a parity error. Otherwise, a DEL (177 octal) and NUL character is
    sent along with the bad character.

    Setting Software Flow Control

    Software flow control is enabled using the IXON, IXOFF
    , and IXANY constants:

      options.c_iflag |= (IXON | IXOFF | IXANY);
      

    To disable software flow control simply mask those bits:

      options.c_iflag &= ~(IXON | IXOFF | IXANY);
      

    The XON (start data) and XOFF (stop data) characters are defined in
    the c_cc array described below.

    Output Options

    The c_oflag member contains output filtering options. Like
    the input modes, you can select processed or raw data output.

    Table 8 –
    Constants for the c_oflag Member
    Constant Description
    OPOST Postprocess output (not set = raw output)
    OLCUC Map lowercase to uppercase
    ONLCR Map NL to CR-NL
    OCRNL Map CR to NL
    NOCR No CR output at column 0
    ONLRET NL performs CR function
    OFILL Use fill characters for delay
    OFDEL Fill character is DEL
    NLDLY Mask for delay time needed between lines
    NL0 No delay for NLs
    NL1 Delay further output after newline for 100
    milliseconds
    CRDLY Mask for delay time needed to return carriage to
    left column
    CR0 No delay for CRs
    CR1 Delay after CRs depending on current column position
    CR2 Delay 100 milliseconds after sending CRs
    CR3 Delay 150 milliseconds after sending CRs
    TABDLY Mask for delay time needed after TABs
    TAB0 No delay for TABs
    TAB1 Delay after TABs depending on current column
    position
    TAB2 Delay 100 milliseconds after sending TABs
    TAB3 Expand TAB characters to spaces
    BSDLY Mask for delay time needed after BSs
    BS0 No delay for BSs
    BS1 Delay 50 milliseconds after sending BSs
    VTDLY Mask for delay time needed after VTs
    VT0 No delay for VTs
    VT1 Delay 2 seconds after sending VTs
    FFDLY Mask for delay time needed after FFs
    FF0 No delay for FFs
    FF1 Delay 2 seconds after sending FFs

    Choosing Processed Output

    Processed output is selected by setting the OPOST option in
    the c_oflag member:

      options.c_oflag |= OPOST;
      

    Of all the different options, you will only probably use the ONLCR
    option which maps newlines into CR-LF pairs. The rest of the output
    options are primarily historic and date back to the time when line
    printers and terminals could not keep up with the serial data stream!

    Choosing Raw Output

    Raw output is selected by resetting the OPOST option in the
    c_oflag
    member:

      options.c_oflag &= ~OPOST;
      

    When the OPOST option is disabled, all other option bits in
    c_oflag
    are ignored.

    Control Characters

    The c_cc character array contains control character
    definitions as well as timeout parameters. Constants are defined for
    every element of this array.

    Table 9 – Control Characters in
    the c_cc Member
    Constant Description Key
    VINTR Interrupt CTRL-C
    VQUIT Quit CTRL-Z
    VERASE Erase Backspace (BS)
    VKILL Kill-line CTRL-U
    VEOF End-of-file CTRL-D
    VEOL End-of-line Carriage return (CR)
    VEOL2 Second end-of-line Line feed (LF)
    VMIN Minimum number of characters to read
    VTIME Time to wait for data (tenths of seconds)

    Setting Software Flow Control Characters

    The VSTART and VSTOP elements of the c_cc array
    contain the characters used for software flow control. Normally they
    should be set to DC1 (021 octal) and DC3 (023 octal) which represent
    the ASCII standard XON and XOFF characters.

    Setting Read Timeouts

    UNIX serial interface drivers provide the ability to specify
    character and packet timeouts. Two elements of the c_cc array
    are used for timeouts: VMIN and VTIME. Timeouts are
    ignored in canonical input mode or when the NDELAY option is set
    on the file via open or fcntl.

    VMIN specifies the minimum number of characters to read. If
    it is set to 0, then the VTIME value specifies the time to wait
    for every character read. Note that this does not mean that a read
    call for N bytes will wait for N characters to come in. Rather, the
    timeout will apply to the first character and the read call will
    return the number of characters immediately available (up to the number
    you request).

    If VMIN is non-zero, VTIME specifies the time to wait
    for the first character read. If a character is read within the time
    given, any read will block (wait) until all VMIN characters are
    read. That is, once the first character is read, the serial interface
    driver expects to receive an entire packet of characters (VMIN
    bytes total). If no character is read within the time allowed, then
    the call to read returns 0. This method allows you to tell the
    serial driver you need exactly N bytes and any read call will
    return 0 or N bytes. However, the timeout only applies to the first
    character read, so if for some reason the driver misses one character
    inside the N byte packet then the read call could block forever
    waiting for additional input characters.

    VTIME specifies the amount of time to wait for incoming
    characters in tenths of seconds. If VTIME is set to 0 (the
    default), reads will block (wait) indefinitely unless the NDELAY
    option is set on the port with open or fcntl.


    Chapter 3, MODEM Communications

    This chapter covers the basics of dialup telephone
    Modulator/Demodulator (MODEM) communications. Examples are provided for
    MODEMs that use the defacto standard “AT” command set.

    What Is a MODEM?

    MODEMs are devices that modulate serial data into frequencies that
    can be transferred over an analog data link such as a telephone line or
    cable TV connection. A standard telephone MODEM converts serial data
    into tones that can be passed over the phone lines; because of the
    speed and complexity of the conversion these tones sound more like loud
    screeching if you listen to them.

    Telephone MODEMs are available today that can transfer data across a
    telephone line at nearly 53,000 bits per second, or 53kbps. In
    addition, most MODEMs use data compression technology that can increase
    the bit rate to well over 100kbps on some types of data.

    Communicating With a MODEM

    The first step in communicating with a MODEM is to open and
    configure the port for raw input:

      Listing 3 – Configuring the port for raw input.

      int            fd;
      struct termios options;
      
      /* open the port */
      fd = open("/dev/ttyf1", O_RDWR | O_NOCTTY | O_NDELAY);
      fcntl(fd, F_SETFL, 0);
      
      /* get the current options */
      tcgetattr(fd, &options);
      
      /* set raw input, 1 second timeout */
      options.c_cflag     |= (CLOCAL | CREAD);
      options.c_lflag     &= ~(ICANON | ECHO | ECHOE | ISIG);
      options.c_oflag     &= ~OPOST;
      options.c_cc[VMIN]  = 0;
      options.c_cc[VTIME] = 10;
      
      /* set the options */
      tcsetattr(fd, TCSANOW, &options);
      

    Next you need to establish communications with the MODEM. The best
    way to do this is by sending the “AT” command to the MODEM. This also
    allows smart MODEMs to detect the baud you are using. When the MODEM is
    connected correctly and powered on it will respond with the response
    “OK”.

      Listing 4 – Initializing the MODEM.

      int                  /* O - 0 = MODEM ok, -1 = MODEM bad */
      init_modem(int fd)   /* I - Serial port file */
      {
        char buffer[255];  /* Input buffer */
        char *bufptr;      /* Current char in buffer */
        int  nbytes;       /* Number of bytes read */
        int  tries;        /* Number of tries so far */
      
        for (tries = 0; tries < 3; tries ++)
        {
         /* send an AT command followed by a CR */
          if (write(fd, "AT\r", 3) < 3)
            continue;
      
         /* read characters into our string buffer until we get a CR or NL */
          bufptr = buffer;
          while ((nbytes = read(fd, bufptr, buffer + sizeof(buffer) - bufptr - 1)) > 0)
          {
            bufptr += nbytes;
            if (bufptr[-1] == '\n' || bufptr[-1] == '\r')
              break;
          }
      
         /* nul terminate the string and see if we got an OK response */
          *bufptr = '\0';
      
          if (strncmp(buffer, "OK", 2) == 0)
            return (0);
        }
      
        return (-1);
      }
      

    Standard MODEM Commands

    Most MODEMs support the “AT” command set, so called because each
    command starts with the “AT” characters. Each command is sent with the
    “AT” characters starting in the first column followed by the specific
    command and a carriage return (CR, 015 octal). After processing the
    command the MODEM will reply with one of several textual messages
    depending on the command.

    ATD – Dial A Number

    The ATD command dials the specified number. In addition to
    numbers and dashes you can specify tone (“T”) or pulse (“P”) dialing,
    pause for one second (“,”), and wait for a dialtone (“W”):

      ATDT 555-1212
      ATDT 18008008008W1234,1,1234
      ATD T555-1212WP1234
      

    The MODEM will reply with one of the following messages:

      NO DIALTONE
      BUSY
      NO CARRIER
      CONNECT
      CONNECT baud
      

    ATH – Hang Up

    The ATH command causes the MODEM to hang up. Since the MODEM
    must be in “command” mode you probably won’t use it during a normal
    phone call.

    Most MODEMs will also hang up if DTR is dropped; you can do this by
    setting the baud to 0 for at least 1 second. Dropping DTR also returns
    the MODEM to command mode.

    After a successful hang up the MODEM will reply with “NO CARRIER”.
    If the MODEM is still connected the “CONNECT” or “CONNECT baud” message
    will be sent.

    ATZ – Reset MODEM

    The ATZ command resets the MODEM. The MODEM will reply with the
    string “OK”.

    Common MODEM Communication Problems

    First and foremost, don’t forget to disable input echoing.
    Input echoing will cause a feedback loop between the MODEM and
    computer.

    Second, when sending MODEM commands you must terminate them with a
    carriage return (CR) and not a newline (NL). The C character constant
    for CR is “\r”.

    Finally, when dealing with a MODEM make sure you use a baud that the
    MODEM supports. While many MODEMs do auto-baud detection, some have
    limits (19.2kbps is common) that you must observe.


    Chapter 4, Advanced Serial
    Programming

    This chapter covers advanced serial programming techniques using the
    ioctl(2)
    and select(2) system calls.

    Serial Port IOCTLs

    In Chapter 2, Configuring the Serial Port we
    used the tcgetattr and tcsetattr functions to configure
    the serial port. Under UNIX these functions use the ioctl(2)
    system call to do their magic.

    The ioctl system call takes three arguments:

      int ioctl(int fd, int request, ...);
      

    The fd argument specifies the serial port file descriptor.
    The request argument is a constant defined in the
    <termios.h>
    header file and is typically one of the following:

    Table 10 – IOCTL
    Requests for Serial Ports
    Request Description POSIX Function
    TCGETS Gets the current serial port settings. tcgetattr
    TCSETS Sets the serial port settings immediately. tcsetattr(fd, TCSANOW, &options)
    TCSETSF Sets the serial port settings after flushing
    the input and output buffers.
    tcsetattr(fd, TCSANOW,
    &options)
    TCSETSW Sets the serial port settings after allowing
    the input and output buffers to drain/empty.
    tcsetattr(fd, TCSANOW, &options)
    TCSBRK Sends a break for the given time. tcsendbreak, tcdrain
    TCXONC Controls software flow control. tcflow
    TCFLSH Flushes the input and/or output queue. tcflush
    TIOCMGET Returns the state of the “MODEM” bits. None
    TIOCMSET Sets the state of the “MODEM” bits. None
    FIONREAD Returns the number of bytes in the input
    buffer.
    None

    Getting the Control Signals

    The TIOCMGET ioctl gets the current “MODEM”
    status bits, which consist of all of the RS-232 signal lines except
    RXD
    and TXD:

    Table 11 – Control Signal
    Constants
    Constant Description
    TIOCM_LE DSR (data set ready/line enable)
    TIOCM_DTR DTR (data terminal ready)
    TIOCM_RTS RTS (request to send)
    TIOCM_ST Secondary TXD (transmit)
    TIOCM_SR Secondary RXD (receive)
    TIOCM_CTS CTS (clear to send)
    TIOCM_CAR DCD (data carrier detect)
    TIOCM_CD Synonym for TIOCM_CAR
    TIOCM_RNG RNG (ring)
    TIOCM_RI Synonym for TIOCM_RNG
    TIOCM_DSR DSR (data set ready)

    To get the status bits, call ioctl with a pointer to an
    integer to hold the bits:

      Listing 5 – Getting the MODEM status bits.

      #include <unistd.h>
      #include <termios.h>
      
      int fd;
      int status;
      
      ioctl(fd, TIOCMGET, &status);
      

    Setting the Control Signals

    The TIOCMSET ioctl sets the “MODEM” status bits
    defined above. To drop the DTR signal you can do:

      Listing 6 – Dropping DTR with the TIOCMSET ioctl.

      #include <unistd.h>
      #include <termios.h>
      
      int fd;
      int status;
      
      ioctl(fd, TIOCMGET, &status);
      
      status &= ~TIOCM_DTR;
      
      ioctl(fd, TIOCMSET, status);
      

    The bits that can be set depend on the operating system, driver, and
    modes in use. Consult your operating system documentation for more
    information.

    Getting the Number of Bytes Available

    The FIONREAD ioctl gets the number of bytes in
    the serial port input buffer. As with TIOCMGET you pass in
    a pointer to an integer to hold the number of bytes:

      Listing 7 – Getting the number of bytes in the input buffer.

      #include <unistd.h>
      #include <termios.h>
      
      int fd;
      int bytes;
      
      ioctl(fd, FIONREAD, &bytes);
      

    This can be useful when polling a serial port for data, as your
    program can determine the number of bytes in the input buffer before
    attempting a read.

    Selecting Input from a Serial Port

    While simple applications can poll or wait on data coming from the
    serial port, most applications are not simple and need to handle input
    from multiple sources.

    UNIX provides this capability through the select(2) system
    call. This system call allows your program to check for input, output,
    or error conditions on one or more file descriptors. The file
    descriptors can point to serial ports, regular files, other devices,
    pipes, or sockets. You can poll to check for pending input, wait for
    input indefinitely, or timeout after a specific amount of time, making
    the select system call extremely flexible.

    Most GUI Toolkits provide an interface to select; we will
    discuss the X Intrinsics (“Xt”) library later in this chapter.

    The SELECT System Call

    The select system call accepts 5 arguments:

      int select(int max_fd, fd_set *input, fd_set *output, fd_set *error,
                 struct timeval *timeout);
      

    The max_fd argument specifies the highest numbered file
    descriptor in the input, output, and error sets.
    The input, output, and error arguments specify
    sets of file descriptors for pending input, output, or error
    conditions; specify NULL to disable monitoring for the
    corresponding condition. These sets are initialized using three macros:

      FD_ZERO(fd_set);
      FD_SET(fd, fd_set);
      FD_CLR(fd, fd_set);
      

    The FD_ZERO macro clears the set entirely. The FD_SET
    and FD_CLR macros add and remove a file descriptor from the
    set, respectively.

    The timeout argument specifies a timeout value which consists
    of seconds (timeout.tv_sec) and microseconds (timeout.tv_usec
    ). To poll one or more file descriptors, set the seconds and
    microseconds to zero. To wait indefinitely specify NULL
    for the timeout pointer.

    The select system call returns the number of file descriptors
    that have a pending condition, or -1 if there was an error.

    Using the SELECT System Call

    Suppose we are reading data from a serial port and a socket. We want
    to check for input from either file descriptor, but want to notify the
    user if no data is seen within 10 seconds. To do this we’ll need to use
    the select system call:

      Listing 8 – Using SELECT to process input from more than one source.

      #include <unistd.h>
      #include <sys/types.h>
      #include <sys/time.h>
      #include <sys/select.h>
      
      int            n;
      int            socket;
      int            fd;
      int            max_fd;
      fd_set         input;
      struct timeval timeout;
      
      /* Initialize the input set */
      FD_ZERO(input);
      FD_SET(fd, input);
      FD_SET(socket, input);
      
      max_fd = (socket > fd ? socket : fd) + 1;
      
      /* Initialize the timeout structure */
      timeout.tv_sec  = 10;
      timeout.tv_usec = 0;
      
      /* Do the select */
      n = select(max_fd,  NULL, NULL, ;
      
      /* See if there was an error */
      if (n 0)
        perror("select failed");
      else if (n == 0)
        puts("TIMEOUT");
      else
      {
        /* We have input */
        if (FD_ISSET(fd, input))
          process_fd();
        if (FD_ISSET(socket, input))
          process_socket();
      }
      

    You’ll notice that we first check the return value of the select
    system call. Values of 0 and -1 yield the appropriate warning and
    error messages. Values greater than 0 mean that we have data pending on
    one or more file descriptors.

    To determine which file descriptor(s) have pending input, we use the
    FD_ISSET
    macro to test the input set for each file descriptor. If
    the file descriptor flag is set then the condition exists (input
    pending in this case) and we need to do something.

    Using SELECT with the X Intrinsics Library

    The X Intrinsics library provides an interface to the select
    system call via the XtAppAddInput(3x) and
    XtAppRemoveInput(3x)
    functions:

      int XtAppAddInput(XtAppContext context, int fd, int mask,
                        XtInputProc proc, XtPointer data);
      void XtAppRemoveInput(XtAppContext context, int input);
      

    The select system call is used internally to implement
    timeouts, work procedures, and check for input from the X server. These
    functions can be used with any Xt-based toolkit including Xaw, Lesstif,
    and Motif.

    The proc argument to XtAppAddInput specifies the
    function to call when the selected condition (e.g. input available)
    exists on the file descriptor. In the previous example you could
    specify the process_fd or process_socket functions.

    Because Xt limits your access to the select system call,
    you’ll need to implement timeouts through another mechanism, probably
    via XtAppAddTimeout(3x).


    Appendix A, Pinouts

    This appendix provides pinout information for many of the common
    serial ports you will find.

    RS-232 Pinouts

    RS-232 comes in three flavors (A, B, C) and uses a 25-pin D-Sub
    connector:

    Figure 2 – RS-232 Connector

    Table 12 – RS-232 Signals
    Pin Description Pin Description
    1 Earth Ground 14 Secondary TXD
    2 TXD – Transmitted Data 15 Transmit Clock
    3 RXD – Received Data 16 Secondary RXD
    4 RTS – Request To Send 17 Receiver Clock
    5 CTS – Clear To Send 18 Unassigned
    6 DSR – Data Set Ready 19 Secondary RTS
    7 GND – Logic Ground 20 DTR
    – Data Terminal Ready
    8 DCD – Data Carrier Detect 21 Signal Quality Detect
    9 Reserved 22 Ring Detect
    10 Reserved 23 Data Rate Select
    11 Unassigned 24 Transmit Clock
    12 Secondary DCD 25 Unassigned
    13 Secondary CTS

    RS-422 Pinouts

    RS-422 also uses a 25-pin D-Sub connector, but with differential
    signals:

    Figure 3 – RS-422 Connector

    Table 13 – RS-422 Signals
    Pin Description Pin Description
    1 Earth Ground 14 TXD+
    2 TXD- – Transmitted Data 15 Transmit Clock-
    3 RXD- – Received Data 16 RXD+
    4 RTS- – Request To Send 17 Receiver Clock-
    5 CTS- – Clear To Send 18 Unassigned
    6 DSR – Data Set Ready 19 RTS+
    7 GND – Logic Ground 20 DTR-
    – Data Terminal Ready
    8 DCD- – Data Carrier Detect 21 Signal Quality Detect
    9 Reserved 22 Unassigned
    10 Reserved 23 DTR+
    11 Unassigned 24 Transmit Clock+
    12 DCD+ 25 Receiver Clock+
    13 CTS+

    RS-574 (IBM PC/AT) Pinouts

    The RS-574 interface is used exclusively by PC manufacturers and
    uses a 9-pin male D-Sub connector:

    Figure 4 – RS-574 Connector

    Table 14 – RS-574 (IBM PC/AT)
    Signals
    Pin Description Pin Description
    1 DCD – Data Carrier Detect 6 Data Set Ready
    2 RXD – Received Data 7 RTS
    – Request To Send
    3 TXD – Transmitted Data 8 CTS
    – Clear To Send
    4 DTR – Data Terminal Ready 9 Ring Detect
    5 GND – Logic Ground

    SGI Pinouts

    Older SGI equipment uses a 9-pin female D-Sub connector. Unlike
    RS-574, the SGI pinouts nearly match those of RS-232:

    Figure 5 – SGI 9-Pin Connector

    Table 15 – SGI 9-Pin DSUB Signals
    Pin Description Pin Description
    1 Earth Ground 6 DSR – Data Set
    Ready
    2 TXD – Transmitted Data 7 GND
    – Logic Ground
    3 RXD – Received Data 8 DCD
    – Data Carrier Detect
    4 RTS – Request To Send 9 DTR
    – Data Terminal Ready
    5 CTS – Clear To Send

    The SGI Indigo, Indigo2, and Indy workstations use the Apple 8-pin
    MiniDIN connector for their serial ports:

    Figure 6 – SGI 8-Pin Connector

    Table 16 – SGI 8-Pin MiniDIN
    Signals
    Pin Description Pin Description
    1 DTR – Data Terminal Ready 5
    RXD
    – Received Data
    2 CTS – Clear To Send 6 RTS
    – Request To Send
    3 TXD – Transmitted Data 7 DCD
    – Data Carrier Detect
    4 GND – Logic Ground 8 GND
    – Logic Ground


    Appendix B, ASCII Control Codes

    This chapter lists the ASCII control codes and their names.

    Control Codes

    The following ASCII characters are used for control purposes:

    Table 17 – ASCII Control Codes
    Name Binary Octal Decimal Hexadecimal
    NUL 00000000 000 0 00
    SOH 00000001 001 1 01
    STX 00000010 002 2 02
    ETX 00000011 003 3 03
    EOT 00000100 004 4 04
    ENQ 00000101 005 5 05
    ACK 00000110 006 6 06
    BEL 00000111 007 7 07
    BS 00001000 010 8 08
    HT 00001001 011 9 09
    NL 00001010 012 10 0A
    VT 00001011 013 11 0B
    NP, FF 00001100 014 12 0C
    CR 00001101 015 13 0D
    SO 00001110 016 14 0E
    SI 00001111 017 15 0F
    DLE 00010000 020 16 10
    XON, DC1 00010001 021 17 11
    DC2 00010010 022 18 12
    XOFF, DC3 00010011 023 19 13
    DC4 00010100 024 20 14
    NAK 00010101 025 21 15
    SYN 00010110 026 22 16
    ETB 00010111 027 23 17
    CAN 00011000 030 24 18
    EM 00011001 031 25 19
    SUB 00011010 032 26 1A
    ESC 00011011 033 27 1B
    FS 00011100 034 28 1C
    GS 00011101 035 29 1D
    RS 00011110 036 30 1E
    US 00011111 037 31 1F