posted @
2015-03-24 14:57 MEYE 阅读(778) |
评论 (2) |
编辑 收藏
小技术团队管理工具大比拼
posted @
2015-03-24 14:52 MEYE 阅读(388) |
评论 (0) |
编辑 收藏
Node.JS超越jQuery成为Github上第二受欢迎的开源项目
前十大受欢迎语言
自从2013年JavaScript成为Github上最流行的语言之后,基于JavaScript的开源项目数量旦越来越多,正不断拉开与其它语言的距离。注* 基于Python,Ruby,Java,PHP开源项目的数量相当。
目前排名:
156,118 JavaScript
87,411 Python
87,272 Ruby
71,920 Java
69,370 PHP
41,166 C
32,229 C++
30,715 Objective-C
21,548 Shell
20,358 C#
统计基于Github上2个人以上关注(star:>1)的开源项目的数量(去除没有人和只有作者本身关注的情况),
Github趋势地址。
注* 2013年的排名
没有去除关注数<2的情况,想看过去几年的情况可以查看
原文地f址Rank | Language | # Repositories Created |
---|
1 | JavaScript | 264131 |
2 | Ruby | 218812 |
3 | Java | 157618 |
4 | PHP | 114384 |
5 | Python | 95002 |
posted @
2015-03-18 14:06 MEYE 阅读(341) |
评论 (0) |
编辑 收藏
视频: 励志片:你有多想要成功?
posted @
2015-02-24 12:37 MEYE 阅读(361) |
评论 (0) |
编辑 收藏
创业及野心的一定要看
1、一个年轻人,如果三年的时间里,没有任何想法,他这一生,就基本这个样子,没有多大改变了。
2、成功者就是胆识加魄力,曾经在火车上听人谈起过温州人的成功,说了这么三个字,“胆子大”。这其实,就是胆识,而拿得起,放得下,就是魄力。
3、这个世界,有这么一小撮的人,打开报纸,是他们的消息,打开电视,是他们的消息,街头巷尾,议论的是他们的消息,仿佛世界是为他们准备的,他们能够呼风唤雨,无所不能。你的目标,应该是努力成为这一小撮人。
4、如果,你真的爱你的爸妈,爱你的女朋友,就好好的去奋斗,去拼搏吧,这样,你才有能力,有经济条件,有自由时间,去陪他们,去好好爱他们。
5、这个社会,是快鱼吃慢鱼,而不是慢鱼吃快鱼。
6、这个社会,是赢家通吃,输者一无所有,社会,永远都是只以成败论英雄。
7、如果你问周围朋友词语,如果十个人,九个人说不知道,那么,这是一个机遇,如果十个人,九个人都知道了,就是一个行业。
8、任何一个行业,一个市场,都是先来的有肉吃,后来的汤都没的喝。
9、这个世界上,一流的人才,可以把三流项目做成二流或更好,但是,三流人才,会把一流项目,做的还不如三流。
10、趁着年轻,多出去走走看看。读万卷书,不如行万里路,行万里路,不如阅人无数。
11、与人交往的时候,多听少说。这就是,上帝为什么给我们一个嘴巴两个耳朵的原因。
12、日常工作之外应当多注意自身修养的提高及自身技能的培训。随着计算机技术的广泛应用,为了不被社会所淘汰,就必须加强计算机技术的培训与提高。无论是企业培训还是个人培训都是不可或缺的。
13、不要装大,对于装大的人,最好的办法就是,捡块砖头,悄悄跟上去,一下子从背后放倒他。
14、不要随便说脏话,这会让别人觉得你没涵养,不大愿意和你交往。即使交往,也是敷衍。因为他内心认定你素质很差。
15、想要抽烟的时候,先问下周围的人可不可以,要学会尊重别人。少在女生面前耍酷抽烟,你不知道,其实她们内心很反感。
16、买衣服的时候,要自己去挑,不要让家人给你买,虽然你第一第二次买的都不怎么样,可是,你会慢慢有眼光的。
17、要想进步,就只有吸取教训,成功的经验都是歪曲的,成功了,想怎么说都可以,失败者没有发言权,可是,你可以通过他的事例反思,总结。教训,不仅要从自己身上吸取,还要从别人身上吸取。
18、学习,学习,再学习,有事没事,去书店看看书,关于管理,金融,营销,人际交往,未来趋势等这些,你能获得很多。这个社会竞争太激烈了,你不学习,就会被淘汰。中国2008底,有一百多万大学生找不到工作。竞争这么激烈,所以,一定要认识一点,大学毕业了,不是学习结束了,而是学习刚刚开始。还有,我个人推荐一个很好的视频节目,《谁来一起午餐》。
19、如果你不是歌手,不是画家,也不是玩行为艺术的,那么,请在平时注意你的衣着。现在这个社会,衣着能表现出你属于哪一个群体,哪一个圈子。
20、记住,平均每天看电视超过三个小时以上的,一定都是那些月收入不超过两千元的,如果你想要月收入超过两千,请不要把时间浪费在电视上。同样的道理,那些平均每天玩网络游戏或聊天超过三个小时以上的,也都是那些月收入不超过两千的。
21、因为穷人很多,并且穷人没有钱,所以,他们才会在网络上聊天抱怨,消磨时间。你有见过哪个企业老总或主管经理有事没事经常在QQ群里闲聊的?
22、无论你以后是不是从事销售部门,都看一下关于营销的书籍。因为,生活中,你处处都是在向别人推销展示你自己。
23、平时的时候,多和你的朋友沟通交流一下,不要等到需要朋友的帮助时,才想到要和他们联系,到了社会,你才会知道,能够认识一个真正的朋友,有多难?
24、如果你想知道自己将来的年收入如何。找你最经常来往的六个朋友,把他们的年收入加起来,除以六,就差不多是你的了。这个例子,可以充分的说明一点,物以类聚。
25、不要听信身边人的话,大一不谈恋爱,好的女孩子就被别人都挑走了。想想,刚上大一就耐不住寂寞,受不住诱惑,而去谈恋爱的女孩子,值得自己去追吗?大学里,可以有一场爱情,可是,不要固执地认为,刚上大一,就必须要谈恋爱。
26、记得,要做最后出牌的人,出让别人觉得出其不意的牌,在他们以为你要输掉的时候,这样,你才能赢得牌局。
27、关于爱情,有这么一句话,没有面包,怎么跳舞?无论什么时候,你决定去好好爱一个人的时候,一定要考虑给她你能给予的最好的物质生活。
28、给自己定一个五年的目标,然后,把它分解成一年一年,半年半年的,三个月的,一个月的。这样,你才能找到自己的目标和方向。
29、无论什么时候,记住尊严这两个字,做人是要有尊严,有原则,有底线的。否则,没有人会尊重你。
30、如果,我只能送你一句忠告,那就是,这个世界上没有免费的午餐,永远不要走捷径!
posted @
2012-01-04 09:50 MEYE 阅读(925) |
评论 (1) |
编辑 收藏
posted @
2011-12-19 19:26 MEYE 阅读(515) |
评论 (0) |
编辑 收藏
[转] 身体器官工作表一览,别熬夜
任何试图更改生物钟的行为,都将给身体留下莫名其妙的疾病,20、30年之后再后悔,已经来不及了。
一、晚上9-11点为免疫系统(淋巴)排毒时间,此段时间应安静或听音乐 。
二、晚间11-凌晨1点,肝的排毒,需在熟睡中进行。
三、凌晨1-3点,胆的排毒,亦同。
四、凌晨3-5点,肺的排毒。此即为何咳嗽的人在这段时间咳得最剧烈,因排毒动作已走到肺;不应Medicine,以免抑制废积物的排除。
五、凌晨5-7点,大肠的排毒,应上厕所排便。
六、凌晨7-9点,小肠大量吸收营养的时段,应吃早餐。疗病者最好早吃,在6点半前,养生者在7点半前,不吃早餐者应改变习惯,即使拖到9、10点吃都比不吃好。
七、半夜至凌晨4点为脊椎造血时段,必须熟睡,不宜熬夜
手、脚、身体各个穴位所对应的内脏 (图)
下面这几张图显示了,咱们的手、脚、身体各个穴位所对应的内脏。按摩的时候,对准穴位下力,才能对我们身体有益。
如图所示,比如我们的脚趾分别代表了我们眼睛和耳朵,而整个脚底就相当于人体身体的主干。
下面是手
身体是革命的本钱,学会了自己给自己按摩一下吧。
拉拉耳朵养护全身器官
肾是人体重要脏器之一,乃先天之本。肾脏功能是否正常,对健康长寿有着举足轻重的作用。
中医五行学说认为,肾主藏精,开窍于耳,医治肾脏疾病的穴位有很多在耳部。所以经常进行双耳锻炼法,可起到健肾壮腰、养身延年的作用。
一、提拉耳垂法 双手食指放耳屏内侧后,用食指、拇指提拉耳屏、耳垂,自内向外提拉,手法由轻到重,牵拉的力量以不感疼痛为限,每次3~5分钟。此法可治头痛、头昏、神经衰弱、耳鸣等疾病。
二、手摩耳轮法 双手握空拳,以拇、食二指沿耳轮上下来回推摩,直至耳轮充血发热。此法有健脑、强肾、聪耳、明目之功,可防治阳痿、尿频、便秘、腰腿痛、颈椎病、心慌、胸闷、头痛、头昏等病症。
三、提拉耳尖法 用双手拇、食指夹捏耳廓尖端,向上提揪、揉、捏、摩擦15~20次,使局部发热发红。此法有镇静、止痛、清脑明目、退热、抗过敏、养肾等功效,可防治高血压、失眠、咽喉炎和皮肤病。
四、搓弹双耳法 两手分别轻捏双耳的耳垂,再搓摩至发红发热。然后揪住耳垂往下拉,再放手让耳垂弹回。每天两三次,每次20下。此法可促进耳朵的血液循环,有健肾壮腰之功效。
五、双手拉耳法 左手过头顶向上牵拉右侧耳朵数十次,然后右手牵拉左耳数十次。这一锻炼还可促进颌下腺、舌下腺的分泌,减轻喉咙疼痛,治慢性咽炎。
六、双手掩耳法 两手掌掩两耳廓,手指托后脑壳,用食指压中指弹击24下,可听到“隆隆”之声,曰击“天鼓”。此刺激可活跃肾脏,有健脑、明目、强肾之功效。
七、全耳按摩法 双手掌心摩擦发热后,向后按摩腹面(即耳正面),再向前反折按摩背面,反复按摩5~6次。此法可疏通经络,对肾脏及全身脏器均有保健作用。
八、双手扫耳法 以双手把耳朵由后面向前扫,这时会听到“嚓嚓”的声音。每次20下,每日数次,只要长期坚持,必能强肾健身。
以上八法,可根据各人所需选择,或单项或几项配合进行,只要能持之以恒,一定能收到理想的效果。
简单易学的强肾健体保健法
祖国传统医学认为,肾为先天之本,生命之源,肾气充盈,则精力充沛,筋骨强健,步履轻快,神思敏捷,肾气亏损则阳气虚弱,腰膝酸软,易感风寒,生疾病等。 肾虚病症有阴虚、阳虚之分。 肾阴虚者,有肺热、咽燥、腰膝酸软、头晕耳鸣、舌苔偏红等症状。
肾阳虚者,常见有肢体畏寒、精神萎靡、腰酸耳鸣、舌淡、体胖等症状。
中医认为,肢体的功能活动,包括关节、筋骨等组织的运动,皆由肝肾所支配,故有“肾主骨,骨为肾之余”的说法,因此坚持体育锻炼,以取得养筋健肾、舒筋活络、畅通气脉、增强自身抵抗力之功效,从而达到强肾健体目的。散步、慢跑、打球、做操、练拳舞剑等,都是不错的锻炼项目。下面介绍几个简单的保健方法,您可以试试。
搓擦腰眼:两手搓热后紧按腰部,用力搓30次。“腰为肾之府”,搓擦腰眼可疏通筋脉,增强肾脏功能。
揉按丹田:两手搓热,在腹部丹田处按摩30~50次。丹田乃人之真气、真精凝聚之所,为人体生命之本。此法常用之,可增强人体的免疫功能,提高人体的抵抗力,从而达到强肾固本的目的,有利于延年益寿。
发“吹”音 “吹”与肾相应,肾属水,故有滋养肾水的功效。反复做6~9遍。
另外,心脏对应的是“呵”音,肝脏对应的是“嘘”的音,脾对应的是“呼”的音,肺对应的是“斯”的音,三焦对应的是“唏”的音。发音的时间长一些,次数多一些。
健脾通胃肠气的保健方法:
双手重叠,顺时针绕肚脐揉腹,以通为主,可促进胃肠气通畅,逆时针绕肚脐揉腹,则以补为主,可起到健脾作用,便秘患者,多顺时针揉,脾虚者,则加逆时针揉,每次300~500下,每天1~2次。
posted @
2011-12-17 14:19 MEYE 阅读(523) |
评论 (0) |
编辑 收藏
摘要: [转] 一堂价值39万元的课,把它看完,你一定会有收获的 如果你能认真看完这篇文章,你真的会收获很多,虽然你不会像身历其境一样得到课 程的内容,但如果你懂得思考,你真的会有很打的收获! 幸福是自己去争取的,不管是友情或爱情很多事情,错过了就没有了,所以如果你没有 认真看完这篇文章,以后你就没有了! &...
阅读全文
posted @
2011-12-17 14:07 MEYE 阅读(584) |
评论 (0) |
编辑 收藏
[转] 俞敏洪+马云+牛根生+史玉柱 不看会一辈子失败
俞敏洪经典语录:
1.女人如果因为觉得一个男生帅就跟嫁给他,这是好色;男生因为女生漂亮而娶她,是审美。
2.为什么你不要自傲和自卑?
你可以说自己是最好的,但不能说自己是全校最好的、全北京最好的、全国最好的、全世界最好的,所以你不必自傲;同样,你可以说自己是班级最差的,但你能证明自己是全校最差的吗?能证明自己是全国最差的吗?所以不必自卑。
3.年纪大了,人们看重不再是外表,不是你帅不帅,而是看你的内心的魅力:你的气魄、气概。
4.这个世界上有很多天才,天才是用来欣赏的,不是用来攀比的。
5.你说我是猪,不对,其实我连猪都不如。
很多人失去了快乐,是因为他太敏感了。别人一句话、一个评论就使自己生气一个月。这时非常无聊的。严重了就成了马家爵,因为别人不请自己吃饭就郁闷地要杀人。
6.要每天多努力一些,比别人多努力一个小时。
7.使这个世界灿烂的不是阳光,而是女生的微笑。
8. 要引人敬意,就要研究一个非常专业的领域,在那个领域中,你是最顶尖的,至少是中国钱10名,这样无论任何时候你都有话说,有事情可作。我俞敏洪原来想成为中国研究英语的前100名,但后来发现根本不可能。所以我就背单词,用1年的时间背诵了一本英文词典,成为中国单词专家,现在我出版的红宝书系列:从初中到GRE词汇有十几本,年销量100万册,稿费比我正式工作都高的多。
9.大学生应该做的事情是:
(1)专业方面,成为中国前100名;
(2)人文方面,读500本书。
(3)英语。
10.如果你要引人注目,就要使得自己成为一棵树,傲立于大地之间;而不是做一颗草,你见过谁踩了一棵草,还抱歉地对草说:对不起?
11.学英语好比学鸟叫,你在树林里学鸟叫,当有四只鸟落在你肩上时,说明你过了英语四级,当有六只鸟落在你肩上时,说明你过了英语六级,当有许多鸟落在你肩上,说明你成了鸟人。
12.女人的温柔和男人的成就是成正比的。
13、俞敏洪在《赢在中国》点评语录
蜗牛的壳是自己加上的。
既靠天,也靠地,还靠自己。
心平气和地接受失败。
做人要大方、大气,不放弃!
世界上没有绝对的公平,公平只在一个点上。
心中平,世界才会平。
学会给别人机会。
名次和荣誉,就像天上的云,不能躺进去,躺进去就跌下来了。名次和荣誉其实是道美丽的风景,只能欣赏。
只要出于同情心和面子做的事,几乎都会失败。
每条河流都有一个梦想:奔向大海。长江、黄河都奔向了大海,方式不一样。长江劈山开路,黄河迂回曲折,轨迹不一样。但都有一种水的精神。水在奔流的过程中,如果沉淀于泥沙,就永远见不到阳光了。
14、俞敏洪:人要像树一样活着
于《赢在中国》第三赛季36进12现场演讲
人的生活方式有两种,
第一种方式是像草一样活着,
你尽管活着,每年还在成长,
但是你毕竟是一棵草,
你吸收雨露阳光,
但是长不大。
人们可以踩过你,
但是人们不会因为你的痛苦,而他产生痛苦;
人们不会因为你被踩了,而来怜悯你,
因为人们本身就没有看到你。
所以我们每一个人,
都应该像树一样的成长,
即使我们现在什么都不是,
但是只要你有树的种子,
即使你被踩到泥土中间,
你依然能够吸收泥土的养分,
自己成长起来。
当你长成参天大树以后,
遥远的地方,人们就能看到你;
走近你,你能给人一片绿色。
活着是美丽的风景,
死了依然是栋梁之才,
活着死了都有用。
这就是我们每一个同学做人的标准和成长的标准。
马云经典语录:
1.当你成功的时候,你说的所有话都是真理。
2.我永远相信只要永不放弃,我们还是有机会的。最后,我们还是坚信一点,这世界上只要有梦想,只要不断努力,只要不断学习,不管你长得如何,不管是这样,还是那样,男人的长相往往和他的的才华成反比。今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。
3.孙正义跟我有同一个观点,一个方案是一流的Idea加三流的实施;另外一个方案,一流的实施加三流的Idea,哪个好?我们俩同时选择一流的实施,三流的Idea。
4.我既要扔鞭炮,又要扔炸弹。扔鞭炮是为了吸引别人的注意,迷惑敌人;扔炸弹才是我真正的目的。不过,我可不会告诉你我什么时候扔鞭炮,什么时候扔炸弹。游戏就是要虚虚实实,这样才开心。如果你在游戏中感到很痛苦,那说明你的玩法选错了。
5.“其实,有的时候人的最大问题就在于他说的都是对的” 。
6.那些私下忠告我们,指出我们错误的人,才是真正的朋友。
7.我生平最高兴的,就是我答应帮助人家去做的事,自己不仅是完成了,而且比他们要求的做得更好,当完成这些信诺时,那种兴奋的感觉是难以形容的……
8.注重自己的名声,努力工作、与人为善、遵守诺言,这样对你们的事业非常有帮助。
9. 商业合作必须有三大前提:一是双方必须有可以合作的利益,二是必须有可以合作的意愿,三是双方必须有共享共荣的打算。此三者缺一不可。
10.服务是全世界最贵的产品,所以最佳的服务就是不要服务,最好的服务就是不需要服务.
11.永远不要跟别人比幸运,我从来没想过我比别人幸运,我也许比他们更有毅力,在最困难的时候,他们熬不住了,我可以多熬一秒钟、两秒钟。
12.今天到北大演讲心里特别激动。我一直把北大的学子当做我的偶像,一直考却考不进,所以我想如果有一天我一定要到北大当老师。
13.看见10只兔子,你到底抓哪一只?有些人一会儿抓这个兔子,一会儿抓那个兔子,最后可能一只也抓不住。CEO的主要任务不是寻找机会而是对机会说NO。机会太多,只能抓一个。我只能抓一只兔子,抓多了,什么都会丢掉.
14.我们公司是每半年一次评估,评下来,虽然你的工作很努力,也很出色,但你就是最后一个,非常对不起,你就得离开。
15.我们与竞争对手最大的区别就是我们知道他们要做什么,而他们不知道我们想做什么。我们想做什么,没有必要让所有人知道。
16.网络上面就一句话,光脚的永远不怕穿鞋的。
17.中国电子商务的人必须要站起来走路,而不是老是手拉手,老是手拉着手要完蛋。我是说阿里巴巴发现了金矿,那我们绝对不自己去挖,我们希望别人去挖,他挖了金矿给我一块就可以了。
18.我深信不疑我们的模式会赚钱的,亚马逊是世界上最长的河,8848是世界上最高的山,阿里巴巴是世界上最富有的宝藏。一个好的企业靠输血是活不久的,关键是自己造血。
19.我为什么能活下来?第一是由于我没有钱,第二是我对INTERNET一点不懂,第三是我想得像傻瓜一样。
20.发令枪一响,你是没时间看你的对手是怎么跑的。只有明天是我们的竞争对手。
21.如果早起的那只鸟没有吃到虫子,那就会被别的鸟吃掉。
22.听说过捕龙虾富的,没听说过捕鲸富的。
23.好的东西往往都是很难描述的。
24.在我看来有三种人,生意人:创造钱;商人:有所为,有所不为。企业家:为社会承担责任。企业家应该为社会创造环境。企业家必须要有创新的精神。
25.一个公司在两种情况下最容易犯错误,第一是有太多的钱的时候,第二是面对太多的机会,一个CEO看到的不应该是机会,因为机会无处不在,一个CEO更应该看到灾难,并把灾难扼杀在摇篮里。
牛根生经典语录:
1.小胜凭智,大胜靠德。
2.有干劲,你就洒下汗水;有知识,你就献出智慧;二者都不具备,请你让出岗位。
3.城市多喝一杯奶,农村致富一家人。
4.财散人聚,财聚人散。
5.一个产品,抓眼球,揪耳朵,都不如暖人心。
6.一个人智力有问题,是次品;一个人的灵魂有问题,就是危险品。经营人心就是经营事业。
7.好心态才有好状态。
8.帮助别人,但不伤害别人。
9.要想知道,打个颠倒。
10.从无到有,是件快乐的事。而从有到无,同样是种快感。
11.产品市场是亿万公民,资本市场是千万股民,原料市场是百万农民。
12.让认识你的人受益,还不能算好;让不认识你的人也受益,那才是真好。
13.吃亏吃到再也吃不进的时候,就不会吃亏了。苦多了,甜就大了。
14.想赢个三回两回,三年五年,有点智商就行;想做个百年老店,想一辈子赢,没有德商绝对不行。
15.学得辛苦,做得舒服;学得舒服,做得辛苦。
16.产品等于人品,质量就是生命。
17.看别人不顺眼,首先是自己修养不够。
18.从最不满意的客户身上,学到的东西最多。
19.管理是严肃的爱。
20.经营企业就是经营人心。
21.人不能把金钱带入坟墓,但金钱却可以把人带入坟墓。
22.一个人快乐不是因为他拥有得多,而是因为计较得少。
23.一个事业能不能成功,关键靠制度设计。
24.别人从零起步,而我从负数起步。
25.听不到奉承的人是一种幸运,听不到批评的人却是一种危险。
26.善待每一头牛,因为它们都是母亲。
27.布局决定结局。
28.世界上还有很多事情,只要你把它做透了,做成专家,你就能够为自己创造成功的机会。
29.会说话的产品卖得快,哑巴产品走得慢。
30.你如果拿五分的力量跟别人较劲,别人会拿出十二分的力量跟你较劲。
史玉柱经典语录:
1.90%的困难你现在想都没有想到,你都不知道那是困难。
2。团队核心成员有人要提出辞职时,不要挽留,既然提出了,他迟早是要走的。
3。如果没有价格上的优势与技术上的绝对优势,千万不要进入红海市场,否则你会必输无疑!
4。做连锁经营业务,一定要做一套傻瓜版的营销手册与管理手册,只有这样,才能实现远距离的管理。
5。做成功一个店之后离你大的成功就不远了,所以你首先就是脚踏实地、集中精力地先做出一家,也是要放弃掉连锁的这种,不要在将来如何做连锁方面做太多的梦,先脚踏实地做出第一家。
6。做全国性市场,一定要先做一个试销市场,要一点点来,快不得;做成了,真到做全国市场时,要快半步,慢不得!
7。初中水平跟博士后没啥区别。只要能干就行,我一直是这个观点,不在乎学历,只要能干能做出贡献就行。
8。作为我们曾经失败过,至少有过失败经历的人,应该经常从里面学点东西。人在成功的时候是学不到东西的,人在顺境的时候,在成功的时候,沉不下心来,总结的东西自然是很虚的东西。只有失败的时候,总结的教训才是深刻的,才是真的。
9.对过去成功的经验再好好总结总结,尤其是对失败的教训,下半夜夜深人静的时候你仔细想一想。反正睡觉也想,想一想实际上对你有很大收获比你看书更有用。因为有的书离你远,那是看自己过去写的东西。
10。最痛苦的时候,压力最大的时候,脑子里面只有一件事儿的时候,我把全国分公司经理招到荒山脚下北大门那个地方,招待所里面,然后在那个地方闭门开批判会。大家批判我,批判了三天三夜,我觉得那个就很有用。
11。要改变消费者固有的想法,比登太阳还难;但不是不可能的。
12。现在的时代,战略正确之后细节决定因素,有很多细节处理不好,你的战略正确了也会失败。
13。不要只看塔尖,二三线市场比一线的更大。
14。管理无情,人有情。
15。所谓人才,就是你交给他一件事情,他做成了;你再交给他一件事情,他又做成了。
posted @
2011-12-17 14:03 MEYE 阅读(498) |
评论 (0) |
编辑 收藏
习惯--成大事者必备十二种良好习惯(1)
第一种习惯 争分夺秒:学会和时间赛跑
第二种习惯 敏而善思:用思想改变人生,感想才能敢干,会想才能巧成
第三种习惯 行动之上:心动不如行动,永不停止、时刻追求进步
第四种习惯 勤奋俭朴:储蓄是成功的助手,养成节俭的习惯(世界首富排行榜上的很多数人都有节俭的习惯)
第五种习惯 积极学习:每天抽出十五分钟时间读书,书籍是人类进步的阶梯。你不学习就落后,因为别人在进步。如同逆水行舟不进则退
第六种习惯 健康快乐:健康是生命之源,学会控制坏情绪,生活不是缺少美,而是缺少发现
第七种习惯 诚实守信:品质的魅力高于一切,诚信是经商的基础,是一笔宝贵的财富,
是人生存在的重要条件
第八种习惯 宽容忍让:容忍的力量是无穷的,是成大事者必备的品格
第九种习惯 乐观自信:完美人生强大支点
永远只看事物的光明面,微笑的生活人们都喜欢与乐观的人相处,希望
他们的喜乐感染自己。乐观者把挫折视为机会,他们把这种健康向上的
心态向四周传播。
第十种习惯 持之以恒:度过一切难关的保障
度过一切难关的保障,成败之间往往只差一点,让你无往而不胜,
毅力是成功的保证,永不言败
第十一种习惯 坚决果断:养成决断习惯的良策,不要被他人意见左右
第十二种习惯 团结合作:双赢生于单赢
成大事者必备的十二种良好习惯
第一种习惯 争分夺秒:学会和时间赛跑
一.时间就是生命:
时间不能储存,不能倒转。它比金钱宝贵,时间是构成生命的基本单位。时间是用来衡量的,善用时间就是珍惜生命。如果你热爱自己的生命,你就珍惜时间吧。
你一天的价值是一百元,上午你去娱乐,或躺在沙发上磨了半天,不要以为你损失了五十元,请记住:钱能生钱。好比你杀死一头产在的猪,不仅是一头猪,还有他所有的子孙后代。你毁掉了五十元,也就毁掉了它所产生的一切,也许是一座美元之山。
二.时间创造价值
爱默生曾说过:“你若是爱永恒,就应当爱现在。昨日不能换回,明天还不存在,你能确实把握的只有现在。”
杰明·弗兰克林的书店,一名男子徘徊很久,问:“这本书多少钱?”“1美元”“弗兰克林在吗?我要见他。”弗兰克林正在忙于印刷工作,当他被叫出来后告诉他1.25美元,客人很诧异,刚刚你的店员告诉我只要一美元,怎么会这样呢?弗兰克林说:“没错,可你耽误我时间比一美元要大得多,”那人又说道:“哪这本书最低要多少钱呢?”“1.5美元”“天哪!你刚刚不是说要1。25美元吗?”“没错,”弗兰克林冷静地说:“你现在耽误我的时间远远大于1。5美元。”这个男子默不作声地把钱放在柜台上拿着书离开了书店。
三.你的时间为何总是被偷走
窃取时间的“大盗”就潜伏在我们身边——它总是在你不留意的瞬间出击,偷走你的那些宝贵时间。
你的性格决定“大盗”的光顾
1. 迟疑不决的人:如果你是一个做事思前想后,犹豫不决的人,那你想一想此役的结果是浪费了时间又加大了工作压力?改掉这个毛病不是一朝一夕的事情,可悲的是有很多人并不知道自己有这种坏习惯。
2. 完美主义者:完美主义者并不令人尊敬,这种性格也并非高人一等。因为这世间本没有完美的事情,而且要求完美经常导致沮丧以及对工作的不满足。
你最好将时间花在如何准确高效地完成工作上,而不是浪费在不必要的细节修饰上。
3. 不会拒绝别人:非常不幸的事,经常有一些人习惯于将自己的工作推给别人,如果你太软弱没有说不得习惯,你将花大量时间去完成别人的工作,这种状况会影响你的心理健康因为唯唯诺诺的人总是感到愤怒、迷惑、被利用,更糟的是连他们也不知道为什么自己会变成这样。
如果你没有以上三种情况尝试下列做法,捉拿时间“大盗。”
1. 保持重点:一次只做一件事情,一个时期只有一个重点。学会抓住重点远离琐碎。
2. 二八定律:百分之八十的利益是由百分之二十的人完成的。
3. 格式化;借助电脑完成工作。
4. 立即行动:许多人习惯“等候好情绪”花费很多时间“进入状态,”请记住:栽第一棵树的最佳时间时20年前,第二个最佳时间是现在。
5. 立即离开:不要被无聊的人缠住,也不要再不必要的地方逗留太久。
6. 避开高峰:如乘车、购物、进餐等等
7. 巧用电话:直奔主题,不要在电话里说一些无关紧要的或不相关的信息。
8. 成本观念:生活中常有的“一分钱智慧,几小时愚蠢,”为省块八角的步行三站地,为节约几毛钱排队购物等等。
9. 精选朋友:多而无益的朋友是有害的,他们浪费你的时间金钱、精力和感情,甚至会危及你的事业,要和有时间观念的任何公司来往。
10. 避免争论:无为的争论不仅影响情绪和人际关系,还会浪费大量时间,往往解决不了问题。说得越多做得越少。
11. 积极休闲:不同的休闲会带来不同的结果。积极的休闲有利于身心的放松、精神的陶冶和人际的交流
12. 集腋成裘(求):零碎的时间可以利用起来,等车时间看报纸、思考问题、背单词。
13. 提前休息:在疲劳之前休息片刻,既避免了因过度疲劳导致的超时休息,又可使自己始终保持较好的竞技状态,从而大大提高工作效率。
14. 搁置的哲学;如足球左路打不开,攻右路。解决不来的问题记在心里,由潜意识去解决,不要转牛角尖。
四.做计划是珍惜时间的有效途径
做出计划不仅能赢得工作的时间,与家人团聚的时间,还可以改变自己的生活方式。让自己的人生更有意义。可以日、周、月、年为单位计划你的人生。
五.掌握时间管理的法则
在世间管理上,要兼顾长远性与急迫性,要高度重视对眼前虽不紧急但有深远影响的事物的处理。
(一)优先重要法则:
将要做的事情分类,如:A类、B类、C类,A类为自己必做的,B类为请他人代做的事情,C类是不必做的事。A类中又可以分为A1、A2、A3等各种级别。
(二)长远重要法则
既要强调优先重要,又要强调长远重要。也就是一些不紧迫却重要长远的事,如锻炼身体。既要兼顾长远性与急迫性,又要重视眼前不紧急但有深远影响的事。
(三)一举两得法则
一举两得、一石多鸟,国外有名的“超级学习法”就是在睡觉时收听外语录音,效果很好。睡前给自己下达指令,睡醒后难题往往都能找到答案,这叫“一遍睡觉一遍成功”
(四)标本兼治法则
如果没有积极兴奋的情绪,掌握多少时间的管理法则技巧也无济于事,当你产生了厌倦怠惰的情绪时必须及时除掉这些情绪的垃圾,否则时间必遭浪费。
(五)打破时间管理的瓶颈
如果你是一个高级经理,想找出瓶颈所在,就立即将你的办公桌上待处理的卷宗待办事项表处理好,尽快把桌上的文件处理到别人的桌子上,效率会提高。
六.珍惜时间存在的误区
有一些人总以为珍惜时间就是把每一分钟、每一秒钟都用于工作上,因为害怕浪费时间,总是来也匆匆,去也匆匆,心急火燎,结果却适得其反。
误区一:欲速则不达
有紧急意识并不错,急可以让大脑动得快一些,但过于着急却是头脑无法正常运转。这个时候,你需要平静自己的心情,经过客观冷静分析判断之后,才能保证速度又保证质量。
误区二:无事瞎忙,有事乱忙
没有计划的人,在没制定好计划的条件下,因急于求成,所以莽撞地开始了行动。结果,这种无顺序前计划的行动把事情搞乱,越乱越遭,想成功太困难了。
误区三:工作狂
这种人把工作看成生活的全部内容,目光仅停留在如何完成工作上,对其他的事务中是不屑一顾,目光的短浅和停滞使他们看不到周围情况的变化,看不到事情的发展,看不到时机的来临,也看不到萋萋的危险。一旦事情发生变化,则使他们来不及防备,或错失良机。工作狂的敬业精神可嘉,然而,忽略了家庭朋友等人生其他美好的东西则太可惜了,适当兼顾,人生会变得更加美好。
误区四:只作计划
完没主义者将计划作的特别精确细致,唯恐出现一点失误,做事追求尽善尽美。江日程表安排得满满的,没有一点空隙从不留下一点应付意外事件的缓冲时间,所以一旦事情发生变化,则往往措手不及。
敏而善思:用思想改变人生,感想才能敢干,会想才能巧成
第二种习惯
一个人如果缺少创新思维,他注定平庸永远成不了大事。
例一:网络神话靠创新而成
现在是网络时代,人们的生活时刻都离不开网络。也造就了一批亿万富翁,网易的CEO丁磊就是其中的一个。他不到而立之年就拥有公司六成多的股份。他一手缔造了网易在中国网络界不可动摇的地位,也造就了中国因特网经济时代个人致富的神话,他传版的网易公司短短数载,价值就达到了四亿人民币。
丁磊凭借自己在编写软件方面的天赋,大学毕业第一年赚了一百万,又凭借自己敏锐的洞察力率先进入因特网,以一连串的免费行动让因特网在中国逐渐火爆起来。他无疑是技术方面的天才,他牢牢掌握网易的发展方向,使网易始终走在世界的前面,从1979年成立伊始倒1998年初,网易没有赚到一分钱。因为所有的钱都投资开发软件上面了,把开发软件卖掉,然后再进行公司的扩张,由于缺少足够的资金和帮助,只能靠开发软件赚钱扩大公司。丁磊在谈到成长的过程中说:“网易的成长没有得到任何帮助,没有人会贷款给一家网络公司。”
例二:不断创新使他成为董事长
北京赛特集团董事长兼总裁杨壮椎管狭窄,腰腿不便,但他酷爱登山,他说不到山顶就不是爬山。他于1991年做赛特总经理的,但是赛特负债3000万,濒临破产,员工人浮于事,他接过这个“烂摊子”,不仅没有放弃,还不断对公司进行改革,对管理经营管理、员工的积极性方面做了大的改进,而且在制度方面不断推陈出新。管理方面他追求中西合璧,取其精华为己所用借鉴外国的先进经验,保持中国的优良传统,更重要的是不断创新,这是塞特集团的业绩蒸蒸日上关键。
杨壮认为塞特的成功重要的一点是超前意识和创新意识。
posted @
2011-12-17 13:33 MEYE 阅读(558) |
评论 (0) |
编辑 收藏
35岁之前成功的12条法则
一、一个目标
一艘没有航行目标的船,任何方向的风都是逆风
1、你为什么是穷人,第一点就是你没有立下成为富人的目标
2、你的人生核心目标是什么?
杰出人士与平庸之辈的根本差别并不是天赋、机遇,而在于有无目标。
3、起跑领先一步,人生领先一大步:成功从选定目标开始
4、贾金斯式的人永远不会成功
为什么大多数人没有成功?真正能完成自己计划的人只有5%,大多数人不是将自己的目标舍弃,就是沦为缺乏行动的空想
5、如果你想在35岁以前成功,你一定在25至30岁之间确立好你的人生目标
6、每日、每月、每年都要问自己:我是否达到了自己定下的目标
二、两个成功基点
站好位置,调正心态,努力冲刺,35岁以前成功
(一)人生定位
1、人怕入错行:你的核心竞争力是什么?
2、成功者找方法,失败者找借口
3、从三百六十行中选择你的最爱
人人都可以创业,但却不是人人都能创业成功
4、寻找自己的黄金宝地
(二)永恒的真理:心态决定命运,35岁以前的心态决定你一生的命运
1、不满现状的人才能成为富翁
2、敢于梦想,勇于梦想,这个世界永远属于追梦的人
3、 35岁以前不要怕,35岁以后不要悔
4、出身贫民,并非一辈子是贫民,只要你永远保持那颗进取的心。中国成功人士大多来自小地方
5、做一个积极的思维者
6、不要败给悲观的自己
有的人比你富有一千倍,他们也会比你聪明一千倍么?不会,他们只是年轻时心气比你高一千倍。
人生的好多次失败,最后并不是败给别人,而是败给了悲观的自己。
7、成功者不过是爬起来比倒下去多一次
8、宁可去碰壁,也不要在家里面壁
克服你的失败、消极的心态
(1)找个地方喝点酒
(2)找个迪厅跳跳舞
(3)找帮朋友侃侃山
(4)积极行动起来
三:三大技巧
1、管理时间:你的时间在哪里,你的成就就在哪里。
把一小时看成60分钟的人,比看作一小时的人多60倍
2、你不理财,财不理你
3、自我管理,游刃有余
(1)创业不怕本小,脑子一定要好
(2)可以开家特色店
(3)做别人不愿做的生意
四:四项安身立命的理念
35岁以前一定要形成个人风格
1、做人优于做事
做事失败可以重来,做人失败却不能重来
(1)做人要讲义气
(2)永不气馁
2、豁达的男人有财运,豁达的女人有帮夫运
35岁以前搞定婚姻生活
3、忠诚的原则:35岁以前你还没有建立起忠诚美誉,这一缺点将要困扰你的一生
4、把小事做细,但不要耍小聪明
中国人想做大事的人太多,而愿把小事做完美的人太少
五:五分运气
比尔·盖茨说:人生是不公平的,习惯去接受它吧
1、人生的确有很多运气的成人:谋事在人,成事在天:中国的古训说明各占一半
2、机会时常意外地降临,但属于那些决不放弃的人
3、抓住人生的每一次机会
机会就像一只小鸟,如果你不抓住,它就会飞得无影无踪
4、智者早一步,愚者晚一步
六:六项要求
1、智慧
(1)别人可你以拿走你的一切,但拿不走你的智慧
(2)巧妙运用自己的智慧
(3)智者与愚者的区别
2、勇气
(1)勇气的力量有时会让你成为“超人”
(2)敢于放弃,敢于“舍得”
3、培养自己的“领导才能、领袖气质”
(1)激情感染别人
(2)“三·七法则”实现领袖气质
(3)拍板决断能力
(4)人格魅力
4、创造性:不要做循规蹈矩的人
25-35岁是人生最有创造性的阶段,很多成功人士也都产生在这一阶段
5、明智
(1)知道自己的长处、短处,定向聚焦
(2)尽量在自己的熟悉的领域努力
6、持之以恒的行动力:在你选定行业坚持十年,你一定会成为大赢家
七:七分学习
1、知识改变命运
2、35岁以前学会你行业中必要的一切知识
a)每天淘汰你自己
b)在商言商
3、太相信的书人,只能成为打工仔
4、思考、实践、再思考、再实践
八.八分交际
朋友多了路好走
1、智商很重要,情商更重要:35岁以前建立起人际关系网
2、人脉即财脉:如何搞好人际关系
3、交友有原则
4、善于沟通:35岁以前要锻炼出自己的演讲才能
九:九分习惯
习惯的力量是惊人的,35岁以前养成的习惯决定着你的成功的大小
1、积极思维的好习惯
2、养成高效工作的好习惯
(1)办公室
(2)生活可以不拘小节,但要把工作做细
(3)学习聆听,不打断别人说话
3、养成锻炼身体的好习惯
4、广泛爱好的好习惯
5、快速行动的好习惯
十:十分自信
1、自信是成功的精神支柱
2、自信方能赢得别人的信任
3、把自信建立在创造价值的基础上
4、如何建立自信
(1)为自己确立目标
(2)发挥自己的长处
(3)做事要有计划
(4)做事不拖拉
(5)轻易不要放弃
(6)学会自我激励
(7)不要让自己成为别人
十一: 11个需要避开的成功陷阱
1、只有功劳,没有苦劳
2、不要“怀才不遇“,而要寻找机遇
3、不要想发横财
4、不要为钱而工作,而让钱为你工作
5、盲目跟风,人云亦云,人做我也做
6、小富即安,不思进取,知足常乐
7、承认错误而非掩饰错误
8、脚踏实地而非想入非非
9、野心太大而不是信心十足
10、反复跳槽不可取
11、眼高手低
12、不择手段
十二:十二分努力
没有人能随随便便成功
1、小不是成功,大不是成功,由小变大才是成功
2、中国社会进入微利时代:巧干+敢干+实干=成功
3、努力尝试就有成功的可能
4、做任何事情,尽最大努力
5、把事情当成事业来做
6、我看打工者
7、祝你早日掘到第一桶金
posted @
2011-12-17 13:08 MEYE 阅读(495) |
评论 (0) |
编辑 收藏
posted @
2011-12-08 21:34 MEYE 阅读(867) |
评论 (0) |
编辑 收藏
图度Talk:只要五秒,秒杀街边的各类远程桌面软
http://www.linuxren.net/news/120R632010.html
五秒钟什么概念!让你瞬间打开世界上任何地点的主机的远程桌面。如果你用过VNC、teamview、微软RDP(远程桌面)、logmein、QQ远程协助等等,你就知道五秒钟意味着什么了,而且还是基于穿透内网主机的远程桌面,对于图度Talk来说哪些神马远程桌面软件都是浮云。废话少说,先说下图度Talk是啥东东….
图度Talk是一个基于图度在线工作管理系统上使用的一款IM聊天工具,远程协助采用了还未发布的向日葵3.0的急速远程桌面协议(www.sunlogin.com),通过远程协助帮助远端同事、朋友解决PC使用中所遇到的各类问题。
下载—图度talk五秒钟版(1.0正式版)地址http://www.tudu.com/tudutalk_1.0final.exe,各位千万注意了,这个要配套图度系统使用的,所有的账户都是由你自主建立的,完全你说了算。开通图度系统可以到www.tudu.com申请开通,现在开通除了可以拿到一个很好的三级域名yourname.tudu.com域名,还将获得18个用户的图度商业版的永久免费使用权。
说了白说,无图无真相,上图。
安装:没什么好说,针对现在免费软件安装包的特点,最大的优点是纯洁无暇,安装过程中没有任何地方忽悠你装垃圾插件。这个logo采用四色,包含了三原色,代表了沟通和融合,比较贴切协同IM的定位。 内容来自Linuxren.net
主界面:市面上大部分能找到的功能基本都有,换肤、透明层、签名、自定义头像、天气预报等,几个亮点支持多国语言(简、繁、英)、显示列表可以定义直板排列(gtalk样式,我喜欢)或分组排列(QQ样式),由于是协同工作用IM,可以自定义登录页面logo、查看组织构架和相关的联系人各类信息等。界面风格你喜欢不喜欢,俺说了不算,俺的评价就是简单实用而不失个性,布局结构方面有自己独特的地方,不会直接让你联想到某一款IM软件。 内容来自Linuxren.net
聊天窗口:聊天界面很简单,没有广告,也没有什么乱七八糟的东西,还集成了屏幕截图和闪屏功能。采用了比较独特的黏贴和堆叠技术(用过gtalk的人应该了解),让你有一种盖楼的冲动,人足够多的情况下可以自动盖出n栋大楼,俺的分辨率高可以一次盖出35层的楼,通过楼房跟人聊天很醒目快捷。另外每天读下签名也是我工作中的一大快乐。
聊天和远程协助:远程协助想必搞IT的兄弟都用过某软件集成的远程协助,其中的辛酸俺就不多说了。我只能说图度Talk的远程协助绝对不一般,强大的工具栏支持键盘快捷、色彩调整、分辨率调整、远程白板、粘贴板同步等功能。完全支持内网穿透,打开远程的屏幕的速度两个字—秒杀街边的各类远程桌面软件,图度Talk首个嵌入了向日葵远控3.0远程桌面加速技术(要知道3.0还没有发布呢)。
图度Talk 1.0正式版更新说明:
1. 开启远程协助按钮; 内容来自Linuxren.net
2. 支持向日葵3.0版急速远程桌面协议;
3. 支持64位windows系统虚拟显卡驱动; copyright Linuxren.net
4. 支持自定义分组和联系人拖拉;
5. 支持超长签名名片显示;
下载—图度talk五秒钟版(1.0正式版)地址http://www.tudu.com/tudutalk_1.0final.exe,各位千万注意了,这个要配套图度系统使用的,所有的账户都是由你自主建立的,你说了算。开通图度系统可以到www.tudu.com申请开通,现在开通除了可以拿到一个很好的三级域名yourname.tudu.com域名,还将获得18个用户的图度商业版的永久免费使用权。
新闻来源:未知
posted @
2011-11-29 20:17 MEYE 阅读(503) |
评论 (0) |
编辑 收藏
PMD是一款采用BSD协议发布的Java程序代码检查工具。该工具可以做到检查Java代码中是否含有未使用的变量、是否含有空的抓取块、是否含有不必要的对象等。该软件功能强大,扫描效率高,是Java程序员debug的好帮手。
它可以为您检查Java代码中存在的如下问题:
1、隐藏的bug,例如空的try catch,switch
2、未调用的代码,例如没有使用的局部变量、参数和私有方法
3、未优化的代码,例如String的不正确使用
4、过于复杂的表达式,没有必要的表达式循环,判断
5、重复代码
PMD支持的编辑器包括:
JDeveloper、Eclipse、JEdit、JBuilder、BlueJ、CodeGuide、NetBeans/Sun Java Studio Enterprise/Creator、IntelliJ IDEA、TextPad、Maven、Ant,、Gel、JCreator和Emacs。
此次版本的主要变化:
1、修复了已有规则的一些bug
2、修改了 CPD 算法
3、JSP/JSF 解析器支持 Unicode
4、可处理 标签;
5、AST HtmlScript 节点包含内容,支持 Ecmascript 等等
下载地址:http://sourceforge.net/projects/pmd/files/
posted @
2011-09-22 09:06 MEYE 阅读(524) |
评论 (0) |
编辑 收藏
Ubuntu如何备份和恢复系统
http://wsfei.iteye.com/blog/1100534
在 使用Ubuntu之前,相信很多人都有过使用Windows系统的经历。如果你备份过Windows系统,那么你一定记忆犹新:首先需要找到一个备份工 具(通常都是私有软件),然后重启电脑进入备份工具提供的软件环境,在这里备份或者恢复Windows系统。Norton Ghost是备份Windows系统时经常使用的备份工具。
在备份Windows系统的时候你可能想过,我能不能把整个C盘都放到一个ZIP文件里去呢。这在Windows下是不可能的,因为在Windows中有很多文件在它们运行时是不允许拷贝或覆盖的,因此你需要专门的备份工具对Windows系统进行特殊处理。
和 备份Windows系统不同,如果你要备份Ubuntu系统(或者其它任何Linux系统),你不再需要像Ghost这类备份工具。事实上,Ghost 这类备份工具对于Linux文件系统的支持很糟糕,例如一些Ghost版本只能完善地支持Ext2文件系统,如果你用它来备份Ext3文件系统,你可能会 丢失一些宝贵的数据。
1. 备份系统
我该如何备份我的Ubuntu系统呢?很简单,就像你备份或压缩其它东西一样,使用TAR。和Windows不同,Linux不会限制root访问任何东西,你可以把分区上的所有东西都扔到一个TAR文件里去!
首先成为root用户:
$ sudo su
然后进入文件系统的根目录(当然,如果你不想备份整个文件系统,你也可以进入你想要备份的目录,包括远程目录或者移动硬盘上的目录):
# cd /
下面是我用来备份系统的完整命令:
# tar cvpzf backup.tgz –exclude=/proc –exclude=/lost+found –exclude=/backup.tgz –exclude=/mnt –exclude=/sys /
让我们来简单看一下这个命令:
“tar”当然就是我们备份系统所使用的程序了。
“cvpfz”是tar的选项,意思是“创建档案文件”、“保持权限”(保留所有东西原来的权限)、“使用gzip来减小文件尺寸”。
“backup.gz”是我们将要得到的档案文件的文件名。
“/”是我们要备份的目录,在这里是整个文件系统。
在 档案文件名“backup.gz”和要备份的目录名“/”之间给出了备份时必须排除在外的目录。有些目录是无用的,例如“/proc”、“/lost+ found”、“/sys”。当然,“backup.gz”这个档案文件本身必须排除在外,否则你可能会得到一些超出常理的结果。如果不把“/mnt”排 除在外,那么挂载在“/mnt”上的其它分区也会被备份。另外需要确认一下“/media”上没有挂载任何东西(例如光盘、移动硬盘),如果有挂载东西, 必须把“/media”也排除在外。
有人可能会建议你把“/dev”目录排除在外,但是我认为这样做很不妥,具体原因这里就不讨论了。
执行备份命令之前请再确认一下你所键入的命令是不是你想要的。执行备份命令可能需要一段不短的时间。
备份完成后,在文件系统的根目录将生成一个名为“backup.tgz”的文件,它的尺寸有可能非常大。现在你可以把它烧录到DVD上或者放到你认为安全的地方去。
在备份命令结束时你可能会看到这样一个提示:’tar: Error exit delayed from previous errors’,多数情况下你可以忽略它。
你还可以用Bzip2来压缩文件,Bzip2比gzip的压缩率高,但是速度慢一些。如果压缩率对你来说很重要,那么你应该使用Bzip2,用“j”代替命令中的“z”,并且给档案文件一个正确的扩展名“bz2”。完整的命令如下:
# tar cvpjf backup.tar.bz2 –exclude=/proc –exclude=/lost+found –exclude=/backup.tar.bz2 –exclude=/mnt –exclude=/sys /
2. 恢复系统
在进行恢复系统的操作时一定要小心!如果你不清楚自己在做什么,那么你有可能把重要的数据弄丢,请务必小心!
接着上面的例子。切换到root用户,并把文件“backup.tgz”拷贝到分区的根目录下。
在 Linux中有一件很美妙的事情,就是你可以在一个运行的系统中恢复系统,而不需要用boot-cd来专门引导。当然,如果你的系统已经挂掉不能启动了, 你可以用Live CD来启动,效果是一样的。你还可以用一个命令把Linux系统中的所有文件干掉,当然在这里我不打算给出这个命令!
使用下面的命令来恢复系统:
# tar xvpfz backup.tgz -C /
如果你的档案文件是使用Bzip2压缩的,应该用:
# tar xvpfj backup.tar.bz2 -C /
注意:上面的命令会用档案文件中的文件覆盖分区上的所有文件。
执行恢复命令之前请再确认一下你所键入的命令是不是你想要的,执行恢复命令可能需要一段不短的时间。
恢复命令结束时,你的工作还没完成,别忘了重新创建那些在备份时被排除在外的目录:
# mkdir proc
# mkdir lost+found
# mkdir mnt
# mkdir sys
等等
当你重启电脑,你会发现一切东西恢复到你创建备份时的样子了!
Linux备份策略研究
世界上没有绝对安全的系统。如果想获得绝对安全的系统,只有不连接网络,不让管理员之外的人使用,刷卡管制人员进出,使用监视器监视录像,甚至于不 要开机。但是这是完全不切实际的,我们仅能寄望尽量让系统能在承担低风险的情况下工作,因为任何操作系统都不可能毫无漏洞。那么怎样才能让系统承担最低的 风险呢?回答因该是在保障系统尽量安全的基础上,做好各个系统上的数据备份工作。一旦系统遭受到毁灭性的打击,可将平时做好的备份数据及时恢复,这样才能 使被破坏的系统迅速恢复正常,以避免不必要的损失。
下面针对Linux操作系统上的数据备份方法发表一下自己的看法。
数据备份种类
总的来说,在Linux操作系统中将备份分为两类:系统备份,实现对操作系统和应用程序的备份;用户备份,实现对用户文件的备份。在下面我们会看到,系统备份和用户备份是不同的。
系统备份
系统备份就是对操作系统和应用程序的备份,进行系统备份的原因是尽量在系统崩溃以后能快速简单完全地恢复系统的运行。进行备份的最有效方法是仅仅备份那些对于系统崩溃后恢复所必需的数据。
Linux系统中很多重要的文件位于/etc目录之下,如:
/etc/group : 组用户信息;
/etc/passwd : 包含所有的用户信息,如密码,登录shell等;
/etc/fstab : 配置系统有哪些文件系统;
/etc/inittab : 配置init在不同运行级别下分别如何启动系统;
/etc/hosts : 域名解析的配置信息;
/etc/inetd.conf : 进程控制信息;
/etc/printcap:配置如何与打印机通信;
/etc/XF86Config:包含XFree86的初始配置;
上面这些重要的配置文件都需要定期的做备份。
不 同的系统可能有很多重要配置文件,可以看到/etc目录下的配置文件非常重要。当然,某些程序使用了其他目录下的一些文件,但是Linux的基本配置文件 绝大多数都位于/etc目录下。很多人曾经花费了好长时间才正确的配置了XF86Config文件,想到如果重新再做一遍,就很费时费力。再举个例子, /etc目录下的passwd文件,如果误操作,将此文件更改,或删除了,则整个系统用户无法正常登录,如果定期或及时的对其备份,遇到上面的情况后,就 可以非常快速的恢复。
如果修改了某个程序所使用的配置文件,一般不能将其搬移到其它的地方,因为程序通常在固定的地方寻找配置文件。因此记录对系统所做的修改也非常重要,无论所做的修改如何小,当系统崩溃时才能轻松的恢复系统。
用户备份
用户备份不同于系统备份,因为用户的数据变动更加频繁一些。当备份用户数据时,只是为用户提供一个虚拟的安全网络空间,合理的放置最近用户数据文件的备份,当出现任何问题,例如,误删除某些文件或者硬盘发生故障时,用户可以恢复自己的数据。
用户备份应该比系统备份更加频繁,也许每天都需要进行备份,或使用cron程序自动定期运行某个程序的方法来备份数据。
数据备份策略
不 管系统多么可靠,总会发生一些意想不到的事情,致使系统数据丢失。因此使用备份来保护数据不丢失是一种非常重要的手段,尤其在系统数据非常重要的时候。经 常进行数据备份能够减少偶然破坏造成的损失,保证系统能够从错误中恢复正常运行。备份不应该成为一个长时间痛苦的事情,但它是作为系统管理必不可少的工 作,在着手之前进行详细的考虑和计划是应该的。
在进行备份之前,首先要选择合适的备份策略,这将决定何时需要备份,以及出现故障时进行恢复的方式。通常使用的备份方式有三种:
完全备份: 每隔一定时间就对系统进行一次全面的备份,这样在备份间隔期间出现数据丢失等问题,可以使用上一次的备份数据恢复到前次备份时数据状况。这是最基本的备份 方式,但是每次都需要备份所有的数据,并且每次备份的工作量也很大,需要大量的备份介质,因此这种备份不能进行的太频繁,只能每隔一段较长时间才进行一次 完整的备份。但是这样一旦发生数据丢失,只能恢复到上次备份的数据,这期间内更新的数据就有可能丢失。
增量备份: 首先进行一次完全备份,然后每隔一个较短时间进行一次备份,但仅仅备份在这个期间更改的内容。当经过一个较长的时间后再重新进行一次完全备份,开始前面的 循环过程。由于只有每个备份周期进行一次完全备份,其他只进行更新数据的备份,因此工作量小,可以进行频繁的备份。例如以一个月为一个周期,一个月进行一 次完全备份,每天晚上0点进行这一天改变的数据备份。这样一旦发生数据丢失,首先恢复到前一个完全备份,然后按日期一个一个恢复每天的备份,就能恢复到前 一天的情况。这种备份方法比较经济。
累计备份:这种备份方法与增量备份相似,首先每月进行一次完全备 份,然后每天进行一次更新数据的备份。但不同在于,增量备份是备份该天更改的数据,而累计备份是备份从上次进行完全备份后更改的全部数据文件。一旦发生数 据丢失,可以使用前一个完全备份恢复到前一个月的状态,再使用前一个累计备份恢复到前一天的情况。这样做的缺点是每次做累计备份工作的任务比增量备份的工 作量要大,但好处在于,增量备份每天都备份,因此要保存数据备份数量太多,而累计备份则不然,只需保存一个完全备份和一个累计备份就可以恢复故障以前的状 态。另外在进行恢复工作时,增量备份要顺序进行多次备份的恢复,而累计备份只需两次恢复,因此它的恢复工作相对简单。
增量备份和累计备份 都能以比较经济的方式对系统进行备份,在这些不同的策略之间进行选择不但与系统数据更新的方式相关,也依赖于管理员的习惯。通常在系统数据更新不是太频繁 的话,可以选用更新备份的方式。但是如果系统数据更新太快,使每个备份周期后的几次累计备份的数据量相当大。这时候可以考虑增量备份或混用累计备份和增量 备份的方式,或者缩短备份周期。
数据备份命令
在Linux系统中常用的备份命令通常有下面几种:
1.使用tar命令
Linux的实用程序tar最初是为了制作磁带存档而设计的(把文件和目录复制到磁带中,然后从存档中提取或恢复文件),而现在的应用中可以把它用于任何设备,它是数据备份中最常用的命令之一。
下面具体介绍tar命令的使用方法:
(1)格式:tar 参数 ......
(2)参数:
c: 创建备份(Create)
v: 表示回显模式(Verbose),将产生一系列备份的文件列表
f: 指定使用的备份文件,它后面的参数为输出的备份文件名
x: 展开备份文件
t: 显示备份文件的内容
T: 后面跟随一个文件参数,指定从这个文件中读取要备份的各个文件的路径。如果不使用T参数,那么就需要一个参数,指明进行备份文件和目录的路径
Z: 使用压缩方式创建和解开备份文件,这是GNU的新版tar的功能,需要同时安装gzip。
例如:
$ tar cvf backup.tar /etc
上 面的命令将/etc下的所有文件打包成tar存档文件backup.tar。tar的第一个参数“cvf”,是tar的命令参数,“c”告诉tar创建一 个存档文件;“v”选项迫使tar采用冗长模式,即在存档时打印每个文件名;“f”选项告诉tar下一个参数backup.tar是创建的存档文件名。
下面一行的命令将tar文件backup.tar解开并放到当前工作目录下。必须说明的是这样做是有危险的,因为在从tar文件中解开文件时,旧文件将被覆盖。
$ tar xvf backup.tar
在解开tar文件之前,知道在何处打开文件是非常重要的。例如,假设存档以下文件:/etc/hosts,/etc/group和/etc/passwd。如果用下述命令:
$ tar cvf backup.tar /etc/hosts /etc/group /etc/passwd
目录/etc会被加到每个文件名前。为了将文件展开到正确位置,需要用下述命令:
$ cd /
$ tar xvf backup.tar
这是因为文件从存档文件中抽取出路径名,如果用下述命令存档文件:
$ cd /etc
$ tar cvf hosts group passwd
这样目录名就不存在存档文件中,因此需要在展开文件之前用“cd /etc”命令进入目录etc。由此可见,tar文件的创建方式与在何处展开有很大关系。
命令:
$ tar tvf backup.tar
在解开tar文件之前显示tar文件的索引,用这种方式可以看到存档文件中与文件名有关的目录名,从而在正确位置上展开存档文件。
2.gzip和compress 命令
与MS-DOS的存档程序不同, tar在存档过程中并不压缩文件。因此,如果存储两个1MB的文件,那么tar文件大小为2MB,gzip命令用来压缩文件(被压缩的文件并不需要是tar格式)。
例如:
$ gzip -9 backup.tar
压缩backup.tar文件,产生的文件为backup.tar.gz,开关“-9”告诉gzip用最高的压缩比。gunzip命令用来解开一个gzip压缩的文件,用“gzip -d”也可以达到同样效果。
例如:
$ gunzip backup.tar.gz
$ gzip -d backup.tar.gz
3. 联合使用
介绍了这些命令之后,我们来尝试组合使用这些命令。为了压缩存储一组文件,可以用下述命令:
$ tar cvf backup.tar /etc
$ gzip -9 backup.tar
结果是形成文件backup.tar.gz。展开该文件时,用相反的命令:
$ gunzip backup.tar.gz
$ tar xvf backup.tar
tar命令还包括“z”选择项,它会自动采用gzip压缩算法来联机压缩/解压文件。例如,下列命令:
$ tar cvfz backup.tar.gz /etc
上面一行的命令等价于:
$ tar cvf backup.tar /etc
$ gzip backup.tar
而命令:
$ tar xvfz backup.tar.Z
可以用来代替下述命令:
$ uncompress backup.tar.Z
$ tar xvf backup.tar
案例实验
案例:使用tar进行备份。
选定了备份方式之后,可以使用tar、cpio、dump等备份工具软件将数据备份到磁带上。对于一般的备份,使用tar就足够了。tar能够创建备份文档,能够备份到磁带上或者产生一个文件,如:
$ tar cvf root.tar /root
将/root目录下的所有文档备份到root.tar文件中,root.tar为指定输出的备份文件,/roo t指出要做备份的目录。如果要备份到磁带上,将输出的备份文件指定为磁带设备文件即可:
$ tar cvf /dev/rmt/0h /root
如果设置了环境变量TAPE,则可以不使用选项“f”指定输出磁带设备名字:
$ TAPE=/dev/rmt/0h; export TAPE
$ tar cv /root
要进行增量备份,必须找出哪些文件在这个期间进行更新。这个任务可以由命令find来完成,例如查找过去七天更改的文件,并使用tar的“-T”参数制定进行备份的文件,命令如下:
$ find / -mtime -7 -print > /tmp/filelist
$ tar -c -T /tmp/filelist -f /dev/rmt/0h
由 于要使用find来找出需要备份的文件列表,那么就需要利用文件的修改时间进行查询,需要使用“-mtime” 参数。另一个更有用的参数是“-newer”,可以查找出所有比某个文件更新的文件,由于备份是周期进行的,因此可以在完全备份之后生成一个标记文件,那 么所有比这个文件新的文件都需要进行更新备份。
$ find / -newer full_back_tag_file -print > /tmp /filelist
进 行数据备份需要定期执行,不能完全依赖于管理员手工进行备份。备份也应该选择在系统比较空闲时进行,以免影响系统的正常处理任务。通常可以选择半夜 0:00点之后进行备份,这样更不能将这个任务由管理员手工完成了。但Linux提供了定时服务cron程序,能够在确定的时间中执行一系列任务,因此数 据备份必须和cron合作来完成,或者使用/etc下的daily,weekly,monthly文件做定时备份的操作。
posted @
2011-08-25 12:56 MEYE 阅读(11638) |
评论 (2) |
编辑 收藏
如何学习Android应用程序的开发
命令行启动程序如:
shell am start -n com.testZ/com.testZ.Test
昨天一同学问我,如何快速的学习Android应用程序开发? 之前的一位同事也问过我,我也只是大概的说说看哪些资料。为避免更多的人问我,所以有必要写写。
1. 开发环境搭建。自行Google。英文好的,看官方网 http://developer.android.com/ 访问不了的,可以访问它的镜像 http://androidappdocs.appspot.com/index.html
2. 在模拟器上运行 ApiDemos,全部点一遍,看看Android都提供了些什么界面效果,心里有个印象。最好把ApiDemos的代码,看它个两三遍。我到过深圳南山 书城,看了好几本国内出的Android书籍,一本书都没翻多久,就看完了,没啥看头,因为大部分内容ApiDemos都有了呀。
3. Java的学习。
Android应用程序是用Java写的,像我这样从C/C++阵营过来的,开始真的很抵触。《Thinking in Java》 ??? No! 没时间玩这东西,当做参考书还行,不懂就翻翻。宝岛台湾的林信良老师写的《Java学习笔记》,还不错。
http://caterpillar.onlyfun.net/Gossip/JavaGossip-V1/JavaGossip.htm
http://caterpillar.onlyfun.net/Gossip/JavaGossip-V2/JavaGossip2.htm
大约花一个礼拜的晚上时间学习,基本够用。
4. 学习资料
(1) 网站
官网 developer.android.com,英文差的同学,也要硬着头皮看,在网上搜来搜去,其实大部分东西都是从这拷贝过去的,从而浪费了大把的时间。国内的android论坛,好像就javaeye文章质量高一点,其他的不知道。我一直上国外的 http://www.anddev.org/ 它有两个版面 Novice Tutorials和Code Snippets for Android,有教程,可以下载代码编译运行,初学者最喜欢这样的了。不像一些网站,下载代码还要扣积分等其他7788的,一看就没什么好感。
(2) 书籍
就只推荐三本,其他的没看过,不好评论。
Mark L. Murphy: 《The Busy Coder’s Guide to Android Development》
Chris Haseman:《Android Essentials》
高煥堂:《Android 應用框架原理與程式設計36 技》
初学者最好不要第一本书就看高的书,因为一些东西他讲起来莫名其妙,搞复杂了,一看developer.android.com英文原版的资料,噢!英文描述这么简单啊。
(3) Blogs
请参看 http://wiki.andmob.org/blogs
(4) 阅读代码
除了上面所说的ApiDemos的代码,还有SDK下提供的Samples目录下其他示例代码,还有Google公司提供的Demo代码,它们在:
http://code.google.com/p/apps-for-android/
———–
2010/6/11 补充内容:今天在网上找chrome代码阅读,看到Venus神庙的 Android学习入门http://www.cnblogs.com/duguguiyu/archive/2010/01/23/1654559.html
感觉不错,也推荐给大家,Venus神庙写作水平不错,比我好N倍。
http://blog.csdn.net/sdhjob/
http://www.anddev.org/
http://dev.10086.cn/cmdn/wiki/index.php?doc-view-3882.html
http://blog.csdn.net/sdhjob/default.aspx?PageNumber=2
posted @
2011-05-24 09:04 MEYE 阅读(1990) |
评论 (0) |
编辑 收藏
Android网络应用开发
http://blog.lytsing.org/archives/574.html
Android网络应用开发
反复研究了 Android Market,总结一下,之前发在新浪微博上,但不够详细,主要是提高用户体验。
1.网络异常处理,重试机制。
上wifi常常网络断开,那就看运用程序是否健壮。可以用Android 提供的 frameworks/base/core/java/android/net/NetworkConnectivityListener.java 监控网络变化,然后做相应的处理。
2.Cache
这个是必须的。比如手机QQ的头像,不可能每一次登录,重新把头像下载一遍。可以是内存cache,也可以写入SD卡。
3. 本地数据与服务器同步机制
4.请求异步处理机制
给一个app打分,打分后,马上回到之前的界面,而不是一直在等是否把数据发送到了服务器再响应。
5. push消息通知
有软件可以更新,在状态栏提示。新浪微博在右上方显示有新数据。
6.lazyload
延时加载,比如图标,头像,分页。
7.数据交换格式:对象序列化/protobuf/json/xml。
8. 设计模式:MVC,chain。
posted @
2011-05-24 08:59 MEYE 阅读(451) |
评论 (0) |
编辑 收藏
经典语录1:
哈佛有一个著名的理论:人的差别在于业余时间,而一个人的命运决定于晚上8点到10点之间。每晚抽出2个小时的时间用来阅读、进修、思考或参加有意的演讲、讨论,你会发现,你的人生正在发生改变,坚持数年之后,成功会向你招手。不要每天抱着QQ/MSN/游戏/电影/肥皂剧……奋斗到12点都舍不得休息,看就看一些励志的影视或者文章,不要当作消遣;学会思考人生,学会感悟人生,慢慢的,你的人生将会发生变化……
经典语录2:
无论你的收入是多少,记得分成五份进行规划投资:增加对身体的投资,让身体始终好用;增加对社交的投资,扩大你的人脉;增加对学习的投资,加强你的自信;增加对旅游的投资,扩大你的见闻;增加对未来的投资,增加你的收益。好好规划落实,你会发现你的人生逐步会有大量盈余。
经典语录3:
过去的一页,能不翻就不要翻,翻落了灰尘会迷了双眼。有些人说不出哪里好,但就是谁都替代不了! 那些以前说着永不分离的人,早已经散落在天涯了。收拾起心情,继续走吧,错过花,你将收获雨,错过这一个,你才会遇到下一个。
经典语录4:
被人误解的时候能微微的一笑,这是一种素养;受委屈的时候能坦然的一笑,这是一种大度;吃亏的时候能开心的一笑,这是一种豁达;无奈的时候能达观的一笑,这是一种境界;危难的时候能泰然一笑,这是一种大气;被轻蔑的时候能平静的一笑,这是一种自信;失恋的时候能轻轻的一笑,这是一种洒脱。
经典语录5:
人生途中,有些是无法逃避的,比如命运;有些是无法更改的,比如情缘;有些是难以磨灭的,比如记忆;有些是难以搁置的,比如爱恋……与其被动地承受,不如勇敢地面对;与其鸟宿檐下,不如击翅风雨;与其在沉默中孤寂,不如在抗争中爆发……路越艰,阻越大,险越多,只要走过去了,人生就会更精彩。
经典语录6:
你改变不了环境,但你可以改变自己;你改变不了事实,但你可以改变态度;你改变不了过去,但你可以改变现在;你不能控制他人,但你可以掌握自己;你不能预知明天,但你可以把握今天;你不可以样样顺利,但你可以事事尽心;你不能延伸生命的长度,但你可以决定生命的宽度。
经典语录7:
魅力女人:1、善于发现生活里的美。2、养成看书的习惯。3、拥有品位。4、跟有思想的人交朋友。5、远离泡沫偶像剧。6、学会忍耐与宽容。7、培养健康的心态,重视自己的身体。8、离开任何一个男人,都会活得很好。9、有着理财的动机,学习投资经营。10、尊重感情,珍惜缘分。
经典语录8:
愚人向远方寻找快乐,智者则在自己身旁培养快乐。生活里的每一个细节都蕴藏着快乐,只是在于你是否感受到了而已。快乐着的人,每一件事,每一个人身上,他都能发现能令自己欢悦的因素来,并让快乐扩张,鼓舞和影响了周围的人。
经典语录9:
【给自己安慰的10句温馨话】1、最重要的是今天的心;2、别总是自己跟自己过不去;3、用心做自己该做的事;4、不要过于计较别人评价;5、每个人都有自己的活法;6、喜欢自己才会拥抱生活;7、不必一味讨好别人;8、木已成舟便要顺其自然;9、不妨暂时丢开烦心事;10、自己感觉幸福就是幸福。
经典语录10:
没有永远的缘份,没有永远的生命,我们所能拥有的,可能只是平凡的一生。然而因为有你,生命便全然不同,不用誓言,不必承诺,我们只需依了爱缘,以目光为媒,印证三生石上的约定,便牵了手,不必紧握,却永不放松,以自己设计的爱的程式,去演绎一种精典的永恒。
经典语录11:
我们之所以会心累,就是常常徘徊在坚持和放弃之间,举棋不定。我们之所以会烦恼,就是记性太好,该记的,不该记的都会留在记忆里。我们之所以会痛苦,就是追求的太多。我们之所以不快乐,就是计较的太多,不是我们拥有的太少,而是我们计较的太多。
经典语录12:
男人吸引女人的10个特质:1.真实 2.深刻 3.胸怀 4.敢为 5.风度 6.机灵 7.幽默 8.进取 9.浪漫 10.冒险.女人吸引男人的10个特点:1.温柔 2.知性 3.直性 4.涵养 5.朦胧 6.小动作 7.勤于家事 8.肤白 9.性感着装 10.香氛
经典语录13:
真正的爱,是接受,不是忍受;是支持,不是支配;是慰问,不是质问;真正的爱,要道谢也要道歉。要体贴,也要体谅。要认错,也好改错;真正的爱,不是彼此凝视,而是共同沿着同一方向望去。其实,爱不是寻找一个完美的人。而是,要学会用完美的眼光,欣赏一个并不完美的人。
经典语录14:
身边总有些人,你看见他整天都开心,率真得像个小孩,人人都羡慕他;其实,你哪里知道:前一秒人后还伤心地流着泪的他,后一秒人前即刻洋溢灿烂笑容。他们其实没有能力独处,夜深人静时,总坐在窗前对着夜空冥想失意的苦楚。他们就像向日葵,向着太阳的正面永远明媚鲜亮,在照不到的背面却将悲伤深藏。
经典语录15:
生命中,有些人来了又去,有些人去而复返,有些人近在咫尺,有些人远在天涯,有些人擦身而过,有些人一路同行。或许在某两条路的尽头相遇,结伴同行了一段路程,又在下一个分岔路口道别。无论如何,终免不了曲终人散的伤感。远在天涯的朋友:或许已是遥远得无法问候,但还是谢谢您曾经的结伴同行。
经典语录16:
爱情很简单,因为每个人都会说:“我爱你,会为你付出一切!”,爱情很难,因为没有多少人做到了他的承诺。如果真心爱一个人,不承诺也会去爱;如果不爱一个人,曾经承诺也会背叛。
经典语录17:
【你最后悔什么】某杂志对全国60岁以上的老人抽样调查:第一名:75%的人后悔年轻时努力不够,导致一事无成。第二名:70%的人后悔在年轻的时候选错了职业。第三名:62%的人后悔对子女教育不当。第四名:57%的人后悔没有好好珍惜自己的伴侣。第五名:49%的人后悔没有善待自己的身体。
经典语录18:
【做人十心机】⒈做人不能太单纯 适度伪装自己 ⒉凡事留余地 要留退路 ⒊话不说绝口无遮拦难成大事 ⒋成熟而不世故 ⒌心态好 想得开活得不累 ⒍懂方圆之道:没事不惹事,来事不怕事 ⒎不可少二礼:礼仪与礼物 ⒏人在江湖飘 防挨朋友刀 ⒐偶尔"势利眼" 寻可靠伙伴 ⒑放下面子来做人。
经典语录19:
人生旅途中,总有人不断地走来,有人不断地离去。当新的名字变成老的名字,当老的名字渐渐模糊,又是一个故事的结束和另一个故事的开始。在不断的相遇和错开中,终于明白:身边的人只能陪着自己走过或近或远的一程,而不能伴自己一生;陪伴一生的是自己的名字和那些或清晰或模糊的名字所带来的感动。
经典语录20:
从现在开始,聪明一点,不要问别人想不想你,爱不爱你?若是要想你或者爱你自然会对你说,但是从你的嘴里说出来,别人会很骄傲和不在乎你。再也不要太在意一些人,太在乎一些事,顺其自然以最佳心态面对,因为这个世界就是这样:往往在最在乎的事物面前,我们最没有价值。
经典语录21:
一个人的成就,不是以金钱衡量,而是一生中,你善待过多少人,有多少人怀念你。生意人的账簿,记录收入与支出,两数相减,便是盈利。人生的账簿,记录爱与被爱,两数相加,就是成就。
posted @
2011-04-27 08:46 MEYE 阅读(506) |
评论 (0) |
编辑 收藏
http://bbs.imp3.net/thread-963148-1-1.html
find . -name ".svn" -exec rm -rf {} \;
source insight
http://hengxing2009.javaeye.com/blog/809622
http://hi.baidu.com/steven926/blog/item/57bc18f971ff85056d22eb88.html
http://blog.csdn.net/philips_629/archive/2010/03/05/5350510.aspx
http://hi.baidu.com/dai493400349/blog/item/c4c8f3f17326ecfd7709d769.html
posted @
2011-03-16 18:26 MEYE 阅读(431) |
评论 (0) |
编辑 收藏
效果预览点这里:http://www.miaov.com/miaov_demo/3dLable/miaov_demo.html
下载效果点这里:http://www.miaov.com/miaov_demo/3dLable/3dLable.rar
使用说明:
一般需要修改的,应该是3D球面的大小,也就是半径,修改了大小,就可以随意放进自己页面的任何地方。
半径大小修改:
下载后,打开 miaov.js 文件,第一行:var radius = 120; 这就是半径大小值了。
文字的修改在 miaov_demo.html 文件中,可以任意添加关键词的个数;
如果希望修改文字颜色、鼠标经过的样式,可以打开 miaov_style.css 文件,修改相关的样式即可。
效果原理:
制作这个效果需要重新回顾一下高中的数学知识:
球坐标系
例如:
r∈[0,+∞),
φ∈[0, 2π],
θ∈[0, π] .
r = 常数,即以原点为心的球面;
θ= 常数,即以原点为顶点、z轴为轴的圆锥面;
φ= 常数,即过z轴的半平面。
……
在这里,我们就不展开讲了,由数学老师来说明更合适些^_^
有兴趣的朋友可以看看百度百科的球坐标系原理:http://baike.baidu.com/view/1196991.htm
关键代码:
for( var i=1; i<max+1; i++){
if( distr )
{
phi = Math.acos(-1+(2*i-1)/max);
theta = Math.sqrt(max*Math.PI)*phi;
}
else{
phi = Math.random()*(Math.PI);
theta = Math.random()*(2*Math.PI);
}
//���任
mcList[i-1].cx = radius * Math.cos(theta)*Math.sin(phi);
//这里有点疑问,mcList[i-1].cx=radius* Math.cos(phi)*Math.sin(theta);
mcList[i-1].cy = radius * Math.sin(theta)*Math.sin(phi);
mcList[i-1].cz = radius * Math.cos(phi);
//这里有点疑问,mcList[i-1].cz = radius * Math.cos(theta);
aA[i-1].style.left=mcList[i-1].cx+oDiv.offsetWidth/2-mcList[i-1].offsetWidth/2+'px';
aA[i-1].style.top=mcList[i-1].cy+oDiv.offsetHeight/2-mcList[i-1].offsetHeight/2+'px';
}
posted @
2010-10-27 09:06 MEYE 阅读(891) |
评论 (0) |
编辑 收藏
哈佛校训:
此刻打盹,你将做梦;而此刻学习,你将圆梦。
看到一篇关于哈佛大学学生是如何学习的文章,贴出来与大家共勉之。如果管理员觉得本文不合适放在首页,可以放在其他地方,谢谢!
哈佛老师经常给学生这样的告诫:如果你想在进入社会后,在任何时候任何场合下都能得心应手并且得到应有的评价,那么你在哈佛的学习期间,就没有晒太阳的时间。
作为闻名于世的学府,哈佛大学培养了许多名人,他们中有33位诺贝尔奖获得者、7位美国总统以及各行各业的职业精英。究竟是什么使哈佛成为精英的摇篮?哈佛学子接受了什么样的精神和理念?这些问题吸引着成千上万的人去探知其中的答案。
哈佛图书馆墙上的20条训言似乎已经给出了答案。短短数语,引发深思,给人启迪。
哈佛图书馆的二十条训言:
1.此刻打盹,你将做梦;而此刻学习,你将圆梦。
2.我荒废的今日,正是昨日殒身之人祈求的明日。
3.觉得为时已晚的时候,恰恰是最早的时候。
4.勿将今日之事拖到明日。
5.学习时的苦痛是暂时的,未学到的痛苦是终生的。
6.学习这件事,不是缺乏时间,而是缺乏努力。
7.幸福或许不排名次,但成功必排名次。
8.学习并不是人生的全部。但既然连人生的一部分―――学习也无法征服,还能做什么呢?
9.请享受无法回避的痛苦。
10.只有比别人更早、更勤奋地努力,才能尝到成功的滋味。
11.谁也不能随随便便成功,它来自彻底的自我管理和毅力。
12.时间在流逝。
13.现在流的口水,将成为明天的眼泪。
14.狗一样地学,绅士一样地玩。
15.今天不走,明天要跑。
16.投资未来的人,是忠于现实的人。
17.受教育程度代表收入。
18.一天过完,不会再来。
19.即使现在,对手也不停地翻动书页。
20.没有艰辛,便无所获。
此刻打盹,你将做梦;而此刻学习,你将圆梦
哈佛老师经常给学生这样的告诫:如果你想在进入社会后,在任何时候任何场合下都能得心应手并且得到应有的评价,那么你在哈佛的学习期间,就没有晒太阳的时间。在哈佛广为流传的一句格言是“忙完秋收忙秋种,学习,学习,再学习。”
人的时间和精力都是有限的,所以,要利用时间抓紧学习,而不是将所有的业余时间都用来打瞌睡。
有的人会这样说:“我只是在业余时间打盹而已,业余时间干吗把自己弄得那么紧张?”爱因斯坦就曾提出:“人的差异在于业余时间。”我的一位在哈佛任教的朋友也告诉我说,只要知道一个青年怎样度过他的业余时间,就能预言出这个青年的前程怎样。
20世纪初,在数学界有这样一道难题,那就是2的76次方减去1的结果是不是人们所猜想的质数。很多科学家都在努力地攻克这一数学难关,但结果并不如愿。1903年,在纽约的数学学会上,一位叫做科尔的科学家通过令人信服的运算论证,成功地证明了这道难题。
人们在惊诧和赞许之余,向科尔问道:“您论证这个课题一共花了多少时间?”科尔回答:“3年内的全部星期天。”
同样,加拿大医学教育家奥斯勒也是利用业余时间作出成就的典范。奥斯勒对人类最大的贡献,就是成功地研究了第三种血细胞。他为了从繁忙的工作中挤出时间 读书,规定自己在睡觉之前必须读15分钟的书。不管忙碌到多晚,都坚持这一习惯不改变。这个习惯他整整坚持了半个世纪,共读了1000多本书,取得了令人 瞩目的成绩。
我荒废的今日,正是昨天殒身之人祈求的明日
闻名于世的约翰霍普金斯学院的创始人、牛津大学医学院的讲座教授、被英国国王册封为爵士的威廉。奥斯勒在年轻时,也曾为自己的前途感到迷茫。一次,他在读书时看到了一句话,给了他很大的启发。这句话是“最重要的就是不要去看远方模糊的事,而是做手边清楚的事。”
对此,哈佛提醒学生说“我荒废的今日,正是昨天殒身之人祈求的明日”。明天再美好,也不如抓住眼下的今天多做点实事。
获得哈佛大学荣誉学位的发明家、科学家本杰明。富兰克林有一次接到一个年轻人的求教电话,并与他约好了见面的时间和地点。当年轻人如约而至时,本杰明的房门大敞着,而眼前的房子里却乱七八糟、一片狼藉,年轻人很是意外。
没等他开口,本杰明就招呼道:“你看我这房间,太不整洁了,请你在门外等候一分钟,我收拾一下,你再进来吧。”然后本杰明就轻轻地关上了房门。
不到一分钟的时间,本杰明就又打开了房门,热情地把年轻人让进客厅。这时,年轻人的眼前展现出另一番景象―――房间内的一切已变得井然有序,而且有两杯倒好的红酒,在淡淡的香气里漾着微波。
年轻人在诧异中,还没有把满腹的有关人生和事业的疑难问题向本杰明讲出来,本杰明就非常客气地说道:“干杯!你可以走了。”
手持酒杯的年轻人一下子愣住了,带着一丝尴尬和遗憾说:“我还没向您请教呢……”
“这些……难道还不够吗?”本杰明一边微笑一边扫视着自己的房间说,“你进来又有一分钟了。”
“一分钟……”年轻人若有所思地说,“我懂了,您让我明白用一分钟的时间可以做许多事情,可以改变许多事情的深刻道理。”
珍惜眼前的每一分每一秒,也就珍惜了所拥有的今天。哈佛的这句话实际上揭示了一种人生哲学,那就是人生要以珍惜的态度把握时间,从今天开始,从现在做起。
觉得为时已晚的时候,恰恰是最早的时候
安曼曾经是纽约港务局的工程师,工作多年后按规定退休。开始的时候,他很是失落。但他很快就高兴起来,因为他有了一个伟大的想法。他想创办一家自己的工程公司,要把办公楼开到全球各个角落。
安曼开始一步一个脚印地实施着自己的计划,设计的建筑遍布世界各地。在退休后的三十多年里,他实践着自己在工作中没有机会尝试的大胆和新奇的设计,不停 地创造着一个又一个令世人瞩目的经典:埃塞俄比亚首都亚的斯亚贝巴机场,华盛顿杜勒斯机场,伊朗高速公路系统,宾夕法尼亚州匹兹堡市中心建筑群……这些作 品被当作大学建筑系和工程系教科书上常用的范例,也是安曼伟大梦想的见证。86岁的时候,他完成最后一个作品―――当时世界上最长的悬体公路桥―――纽约 韦拉扎诺海峡桥。
生活中,很多事情都是这样,如果你愿意开始,认清目标,打定主意去做一件事,永远不会嫌晚。
今天不走,明天要跑
在哈佛,教授们会时常提醒学生们要做好时间管理,并列举如下事例:
当今世界上最大的化学公司―――杜邦公司的总裁格劳福特。格林瓦特,每天挤出一小时来研究蜂鸟,并用专门的设备给蜂鸟拍照。权威人士把他写的关于蜂鸟的书称为自然历史丛书中的杰出作品。
休格。布莱克在进入美国议会前,并未受过高等教育。他从百忙中每天挤出一小时到国会图书馆去博览群书,包括政治、历史、哲学、诗歌等方面的书,数年如一日,就是在议会工作最忙的日子里也从未间断过。后来他成了美国最高法院的法官。
一位名叫尼古拉的希腊籍电梯维修工对现代科学很感兴趣,他每天下班后到晚饭前,总要花一小时时间来攻读核物理学方面的书籍。随着知识的积累,一个念头跃 入他的脑海。1948年,他提出了建立一种新型粒子加速器的计划。这种加速器比当时其他类型的加速器造价便宜而且更强有力。他把计划递交给美国原子能委员 会做试验,又再经改进,这台加速器为美国节省了7000万美元。尼古拉得到了1万美元的奖励,还被聘请到加州大学放射实验室工作。
在人生的道路上,你停步不前,但有人却在拼命赶路。也许当你站立的时候,他还在你的后面向前追赶,但当你再一回望时,已看不到他的身影了,因为,他已经跑到你的前面了,现在需要你来追赶他了。所以,你不能停步,你要不断向前,不断超越。
狗一样地学,绅士一样地玩
我们说要珍惜时间,努力为实现理想而打拼,但有一点要注意,那就是不要一味地拼命,也要有适度的休息和放松。对此,哈佛有个很贴切的说法,叫做“狗一样地学,绅士一样地玩”。话虽略显粗俗,但揭示的道理却很深刻。
在哈佛,虽然学习强度很大,学生们承受着很大的学习压力,但他们也不提倡学生把所有的时间都用来学习。他们认为,学要尽力,玩也不能忽视。哈佛的学生也 说,哈佛的课余生活要胜过正规学习。而哈佛也意识到适度的课外活动不但不会背离教育使命,而且还会给教育使命以支持。因此,他们提出要像“绅士一样地 玩”。
在哈佛,学生们除了紧张地学习,还会参加学校组织的多种艺术活动,比如音乐会、戏剧演出、舞蹈表演及各种艺术展览等,此外,哈佛每年还 会举办艺术节,以活跃学生的业余生活。这些充满着浓厚艺术氛围的活动不仅让学生接受了艺术教育和熏陶,而且提高了学生的艺术修养和审美能力。
哈佛的理念就是要求你在紧张的学习和工作后,能够暂时地完全忘记它们,像投入工作那样投入玩耍,尽情地放松。的确,在你尽心休闲的时候,所得到的体力和精力的恢复会为你下一阶段的奋斗增添无穷的动力。所以,在前进的路上,你不仅要勤奋努力,更要学会放松。
现在流的口水,将成为明天的眼泪
成功与安逸是不可兼得的,选择了其一,就必定放弃了另一结局。正像哈佛所提醒的那样:现在流的口水,将成为明天的眼泪。今天不努力,明天必定遭罪。
我的邻居查尔斯曾经在哈佛度过4年的大学时光,他现在就职于纽约的一家软件公司,做他最擅长的行政管理工作,九九读书人。不久前,他的公司被一家法国公 司兼并了。在兼并合同签订的当天,公司的新总裁宣布:“我们不会随意裁员,但如果你的法语太差,导致无法和其他员工交流,那么,不管是多高职位的人,我们 都不得不请你离开。这个周末我们将进行一次法语考试,只有考试及格的人才能继续在这里工作。”
散会后,几乎所有的人都拥向了图书馆,他们这时才意识到要赶快补习法语了。只有查尔斯像平常一样直接回家了,同事们都认为他已经准备放弃这份工作了,毕竟,哈佛的学习背景和公司管理层的工作经验会帮助他轻而易举地找到另一份不错的工作。
然而,令所有人都想不到的是,考试结果出来后,这个在大家眼中没有希望的人却考了最高分。原来,查尔斯在毕业后来到这家公司后,他在工作中发现与法国人 打交道的机会特别多,不会法语会使自己的工作受到很大的限制,所以,他很早就开始自学法语了。他利用可利用的一切时间,每天坚持学习,最终学有所获。
在哈佛,你从来看不到学生在偷懒,在消磨时间。当若干年后回想起曾经的梦想时,希望带给你的是无尽的欣慰笑容,而不是因蹉跎而流下的悔恨泪水。
投资未来的人,是忠于现实的人
作为世界知名的学府,哈佛十分强调要有长远眼光,为未来投资。要投资未来,就要定好未来的投资方向,也就是要及早地设定人生目标。没有目标,就谈不到发展,更谈不上成功。
哈佛大学曾进行过这样一项跟踪调查,对象是一群在智力、学历和环境等方面条件差不多的年轻人。调查结果发现:27%的人没有目标;60%的人目标模糊;10%的人有着清晰但比较短期的目标;其余3%的人有着清晰而长远的目标.
以后的岁月,他们行进在各自的人生旅途中。25年后,哈佛再次对这群学生进行了跟踪调查。结果是这样的:
3%的人,在25年间朝着一个方向不懈努力,几乎都成为社会各界的成功人士,其中不乏行业领袖和社会精英;10%的人,他们的短期目标不断地实现,成为 各个领域中的专业人士,大都生活在社会的中上层;60%的人,他们安稳地生活与工作,但都没有什么特别成绩,几乎都生活在社会的中下层;剩下27%的人, 他们的生活没有目标,过得很不如意,并且常常在抱怨他人,抱怨社会,当然,也抱怨自己。
其实,他们之间的差别仅仅在于:25年前,他们中的一些人就已经知道自己最想要做的是什么,而另一些人则不清楚或不很清楚。这个调查生动地说明了明确生活目标对于人生成功的重要意义。
posted @
2010-09-01 09:19 MEYE 阅读(601) |
评论 (0) |
编辑 收藏
也谈谈如何做演讲
作为一个经常做演讲的人,我很高兴的看到CatChen在他的文章里介绍了如何做演讲。洪超大哥在MVP openday上的培训是非常好的,我没去成很可惜。
话说回来,演讲这事我一年大概搞个小100次,如果算上我的各种Cast则要更多,所以不才就在这里随便说说关于演讲的东西。
1.演讲的目的
正本清源的说,演讲这事的目的只有一个,就是让对方相信你让他相信的,赞同你提出的,反对你反对的。演讲是宣传的工具,宣传则是包装的工具,对好事我们所做的一切叫宣传,对坏事我们所做的一切叫炒作。但是本质上,两者做的是同一种事。也就是说,你演讲的目的大体只有一个,也就是宣传或者说炒作。如果你不赞同这一观点,可以参考下面的文字《什么是炒作》
2.演讲的技巧
演讲最重要的技巧就是了解你的受众,人们只希望听见自己希望听见的话,喜欢听见自己喜欢听见的话,记住自己愿意记住的话,而其它的话,则全是废话。牢记这一点有助于你进行演讲,在开始演讲之前,你非常有必要了解你的听众,他们是谁、为什么来着、想听什么?
为了不让这个事情说的像国产教科书,我简单的把这事做如下表述“你的记忆就像一幢房子,里面是精装修,家具电器一应俱全,就是没有男主人,后来天长日久就老旧了,你选择性记忆把那些你觉的好的留下了,然后对记忆修饰一新,涂上腻子雕梁画栋,没事的时候还不断拉人来参观粉饰太平,最后你也分不清那些是原来的哪些是后弄的。简单的说,你把自己给糊弄了。”
大体上,我们在成长和衰老过程中进行着不断肯定的自我记忆修复,我们不断回忆自己做的好的往事,然后通过这一肯定让自己有继续生活的勇气,少部分人因为脑部受了损伤,总是记住自己做的坏事,然后自我否定,我们一般称呼这种病为“抑郁症”,患者都有自杀倾向,要吃百忧解才能继续生活,不幸的是,越是善于客观、理智思考的人,越不能随便忘记过失和盲目自我肯定,这也就造就了的他们早夭。人类社会千百年来没什么进步,且一茬不如一茬的根本症结就在于此。
2.1 做好自我定位
我们人类社会大体是分小圈子的,一个人的穿着打扮就说明了他的小圈子,你在演讲的时候,你和你受众必须是一个小圈子,否则一切说法就无从谈起,不信的话,你可以参考那些到处游说的职业政客,每个人走进工人的时候都是蓝领子的衬衫,走向农民的时候都是灰色尼龙绸夹克,绝对不会穿衬衫和西装。跟知识分子握手的时候则必然西装笔挺,还要带着领结。要知道,这些随着外部环境变化的形象工程是演讲成功的关键,你传的衣服,行为举止让对方感觉你不是这个圈子的,则你不用开口,就已经输了。
2.2 目标导向明确
演讲要有宣传的目的,我一开头就说了,这里再强调并非是说还要在演讲中不断的强调你的目标,刚好相反,你应该尽量回避告诉你的听众你的目标,外国PPT开头最喜欢告诉受众,我这个PPT要讲的内容是什么,然后1.2.3一列举,坦白讲,这种演讲的影响力其实很有限,因为听众会在一开头就知道,哦,原来你要讲这些啊,而且会根据内容选择性收听或者不听,因为他们想,反正我有PPT可看,还听你废话干什么。外国这么搞当然是有原因的,因为外国人是实在,来听演讲一定就是来听演讲,一定一心一意的,因为他们是自愿来的,他们对这个演讲感兴趣,但是多数情况下,来听你演讲的同胞们很多情况下完全是因为“无聊,被迫,不来听就要去干活”等等纯粹的消极因素来听演讲。所以对他们来说,PPT前面的123可以跟讲的东西完全不搭调,123是给他们一个来的理由,而他们听到的东西则决定了他们的反馈。
除了不要照本宣科以外,我还得说,演讲的诀窍之一就是把你的目的弄成简单的口号,人们对母语中有韵脚的语序有特殊的好感,大脑会选择记住他们,并且简短的东西便于口口相传,比如“不要迷恋哥,哥只是传说。”十个字,体现了很高的境界,再比如“哥抽的不是烟,燃烧的是寂寞。”11个字,体现了品位,最后比如“做人勿装B,装B被雷劈”10个字,提前了对以上所有说法的否定,如果你想让你的演讲也能深入人心,那么一定要把主题弄在10个字里,并且让他们押韵,比如…
3.演讲常见悖论
演讲需要做大量准备,反复对这镜子练习,注意观察自己的口型和神态。
凡提供这一说法的都是上过MBA课,或者被外国人忽悠了,大体上国外进口的演讲入门书籍里都这么说,这种说法很适合受众固定,内容统一的演讲,也就是说,如果你长年累月就说着一套话,那么再最开始,你应该可以通过这样准备而获得比较好的提高。但是,实际上,多说情况下,这种准备对你的帮助有限,对演讲的内容最好的准备是,在演讲之前对稿子熟练,然后扩充各种相关内容,仔细分析各种相关书籍和文章,尽量在演讲的时候说听众没想到或者没听说过的。这比口型神态什么的管用的多。
演讲需要口齿清楚,逻辑流畅,这样才能打动人。
有兴趣的人可以参加一下安利的讲座,或者跟保险推销员以及任何直销销售人员聊天,如果您有机会现场听学校辅导员老师讲课,则您更会理解我说的内容。这里就不多谈了。
演讲只是交流的手段,演讲的目的是为了交流,激荡出智力的火花。
这跟两个已经势同水火的平级领导在年会上频频碰杯,并高呼“我们是一个Team”,或者一对早就貌合神离却总在媒体前如胶似漆,还说“我们一直很恩爱”的演员伉俪一样。这种说法源于虚伪,其实更像那些想骗你钱的打电话给你推销东西的人说的一样,“我们都是为你好。”
以上是我关于演讲能想起来的大部分细节,最后还有一句老话,卖油的大爷说的“无他,手熟尔。”勤学苦练总是一个亘古不变的好方法。
下面说说题外话,面试的紧张。
任何人面试都紧张,因为要被质问,谁都不喜欢被质问,另外就是心里很想得到这个工作很怕失去这个机会,其实站在人生这个长度看问题,面试连小插曲都算不上,顶多算打一个喷嚏,既不新鲜也不有趣。任何机会如果被标上“一旦错过,永不可能”,则应该坦然让这机会走开,因为谁也不能妄论别人的生死乃至前程,世界充满未知和不确定,一份工作的得失其实微不足道,人,无论伟大或者渺小,最后都是一个终极目标,所以在这过程中尽力耍宝就好,压根用不着为了别人的评价烦恼。
posted @
2010-08-26 19:25 MEYE 阅读(412) |
评论 (0) |
编辑 收藏
人生如戏,谈如何面对困难
看见好多人都说困难,家里困难,工作困难,等等逐日此类不一而足,我也随便说两句,我得看法,怎么解决外部环境问题,战天斗地这些我不想说了,我就想说说自己怎么调整心态吧。
其实调整心态挺简单的,就四个字,人生如戏。
人生如戏何解呢,也很简单,就是把你现在所发生的事都当一处话剧,你,你爸爸,你妈妈,你同事,你朋友,你领导,你下属,你老婆,你情人,其实都是演员,大伙兴冲冲的你方唱罢我登场,其实都是演戏,没人跟你来真的,也没有真的。你也就演这几十年,演好演坏无所谓,反正最后都是眼一闭腿一蹬,所以得想开。
当然这话说着容易做着难。首先是得知道自己演的什么角色,您在外面威风八面,回家都得演孝子贤孙,中国人讲究这个。所以记得跟你爸爸妈妈说话的时候要当孝子贤孙,所谓孝是孝敬,尊敬的程度多一点。不是孝顺,没有顺从的必要。你一完全行为能力责任人,你干什么都可以自己负责,压根不用你爸爸妈妈操心。为了避免老有人说看不懂,我再说透亮点。你爸你妈说什么,就答应什么,回头一扭脸,你演别的角色了,就完全不用管答应过他们什么了,因为那是俩角色,不能混着来,你爸你妈苦口婆心跟你说,也是他们的责任,他们作为老演员演了几十年,眼看到最后一班岗了,非得站的敬业一点才好。敬着他们,就是说什么都答应,不顺着他们,就是只捡自己觉得好的做。
角色一时一变,语言、行动也得跟着变。上班的时候你是个积极的程序员,跟你女朋友在一起的时候你就是好男朋友、好老公,这俩角色不交叉,台词也不能混着来,不信你跟你同事聊韩剧,跟女朋友聊.NET,你肯定得倒霉。好多人犯拧巴,非得一天到晚一个腔调,这就是所谓没事找抽型,活该别人不给你好脸色。
跟女朋友打完电话,你又摇身一变成积极青年了,大半夜不睡觉,你得学习新技术,这时候问你女朋友叫什么,你都不用搭理他,因为你这会不演这个角色,这个角色的台词你就不需要记得。
大部分的角色其实都挺好找的,人家一叫你,你一答应就全找到了。人家叫你儿子,你就知道你演儿子呢,人家叫你孙子,你就知道你演孙子呢,人家叫你老公,你就知道你演老公呢,人家叫你SB,你就知道,你演SB呢。前三种都知道怎么演,就最后一种好多人拿不住,人家一叫他这个他就不知道怎么办了,你想想看,一个SB没思考能力,能怎么办?这事稍微一过脑子就能明白,低等动物受到攻击怎么办,脊椎反射都知道,挨骂就骂回去挨打就打回去,不用担心什么礼貌一类,因为你在演一个SB。
诸如此类,社会角色也定义了,演也演了,好多人不满意,非要当角儿,要跟一帮演员里拔得头筹,觉得不这样不算混这一场演出。要我说这事没必要,大伙都是演这一阵,谁知道谁什么时候就下场了。为这点电光石火之间的事争长短,犯不上。
最后就是演着演着好多人谢幕了,有些老演员匆匆忙忙就谢幕了,有些提前还假装不舒服,让演医生的出来串串场,有些则干脆不打招呼就溜号了,这时候你也别太难过,这不是没有戏德的表现,实在是老演员太辛苦了,演了那么长时间,需要休息,你也别难过,没准哪天就在街上碰见了,虽然彼此都装着不认识,但是心里还是认识的。我小时候就这么想,所以姥姥姥爷走了以后不怎么难过,今天我劝大家都这么想,也许就少难过一点。(要依着我自己写,这句话就不加,但又怕说看不懂)
对于女朋友,人家漂亮姑娘肯定得赶场,档期实在排不开就不能陪你演着一阵你也更不用难过,人家跟谁不是演这一阵子啊,换句话说,你不是得找那个能跟你演一辈子的吗,所以别着急。别犯牛劲。
然后就是事业不顺,那就更看得开了。韩信跟漂母讨饭,秦琼卖马,赵匡胤跟街上摆象棋摊,哪个大人物不是从挫折戏演起的,换句话说,没有挫折戏这一出,哪能体现后面飞黄腾达的刺激呢,所以演这出戏是必由之路,一旦导演给您派了这出戏,您应该高兴,那是您要飞黄腾达的了,这会忍住以后就能吃香的喝辣的。
况且导演哪能真把您逼得绝路上,前面肯定给您安排了峰回路转的情节,无论如何都得静观其变,中途罢演那就没劲了。
最后就是希望大家都好,别管有钱没有,有吃的没有,总把这一切都当成一出戏,有演的有看的,就能乐在其中,其乐融融了。
posted @
2010-08-26 19:23 MEYE 阅读(418) |
评论 (0) |
编辑 收藏
摘要: [转载:]
http://www.ideasandroid.com/?p=328
本文将介绍在android平台下如何实现多线程下载,大家都知道,android平台使用java做为开发语言,所以java中支持的多线程下载方式在android平台下都支持,其中主要有两种方式可以实现多线程下载。
一种方式是使用很多个线程分别下载文件的不同部分,最后把所有下载完的文件合并成一个文...
阅读全文
posted @
2010-08-17 17:16 MEYE 阅读(2360) |
评论 (0) |
编辑 收藏
样式是用于描述一个View或是一个窗口的显示属性的集合,样式可以指定如高度,填充,字体颜色,字体大小,背景颜色等属性。样式是从布局文件中分离出来的一个XML资源文件。Android中的样式就像Web开发中的css样式表,它使用我们的样式独立于内容进行设计开发。
例如,通过使用一个样式可以让如下的布局文件
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#00FF00"
android:typeface="monospace"
android:text="@string/hello" />
简化为:
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
所有和样式有关的属性都被从布局XML文件中移动到一个叫“CodeFont”的样式定义中,然后使用一个style属性指定样式名称。你将会在以下的内容中看到如何定义一个样式。
应用于一个Activity或应用程序的样式称为主题(theme),而不是刚才说的一个View。所有在当前Activity或应用下的视图(VIEW)都会应用相同的主题样式。例如,您可以让一个Activity使用”CodeFont”主题,那么这个Activity下的所有视图的的文本都将是绿色等宽字体。
定义样式
定义样式我们需要在 res/values/目录下新建一个XML文件,文件名自已随便命名,但必须以.xml为文件后缀。Xml的根节点必须为。
我们用style标签来定义一个样式,用- 标签来定义样式属性。如下所示:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="@android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
Style标签的name属性是必须有的,- 节点可以定义颜色、高度或者是另一个资源的引用。所有节点的子节点在编译时都会做为应用程序的一个资源。所以我们可以通过style节点的name属性值来引用这个资源。比如在布局文件中使用@style/CodeFont来引用这个样式。parent 属性是可选的,用它来标识本样式是继承哪个样式,在父样式中的所有属性都将被应用于本样式中,同时可以覆盖父样式中的样式(和java的继承相似)。
样式的继承
这里有两种方式可以实现样式继承,如上例中所示的,我们可以在定义样式时使用parent属性来继承样式,使用这种方式,我们可以继承一个我们自己定义好的样式,也可以继承一个android平台自带的样式(后文中会介绍android平台自带的所有样式)。如下所示,我们继承一个android平台默认的文本样式,并把它的字体颜色改为我们需要的颜色。
<style name="GreenText" parent="@android:style/TextAppearance">
<item name="android:textColor">#00FF00</item>
</style>
另一种继承的方式是使用用户自定义的样式作为前缀即可。这种方式只适用于继承用户自定义样式。如下所示:
<style name="CodeFont.Red">
<item name="android:textColor">#FF0000</item>
</style>
这样,新定义的样式就会继承CodeFont样式的所有属性,然后把字体颜色变为#FF0000。我们可以这样引用新的样式: @style/CodeFont.Red
相同的方法,我们可以再继承下去,如下所示:
<style name="CodeFont.Red.Big">
<item name="android:textSize">30sp</item>
</style>
这样新的样式文子的大小就和CodeFont.Red样式不同了。
样式属性
到这里为止,你已经知道了如何定义一个样式,你还需要知道有多少种样式属性可以通过- 节点来定义。你可能已经对其中的一些比较熟悉了,如layout_width 、textColor等。当然,还有很多的样式属性是你可以使用的。
最好的方法查询一个视图支持哪些样式属性的方法是查询视图类的文档中XML Attributes表格,如TextView的XML attributes如链接中所示: http://www.ideasandroid.com/android/sdk/docs/reference/android/widget/TextView.html#lattrs
如需所有可用的样式属性的,请参阅R.attr: http://www.ideasandroid.com/android/sdk/docs/reference/android/R.attr.html
不是所有的视图都支持上面的样式属性,如果遇到不支持的样式属性,您定义的属性将会被忽略。
应用样式和主题
应用样式和主题的方法很简单,在布局定义文件(layout)中,使用style属性直接引用样式资源,如下所示:
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
在AndroidManifest.xml文件中可以引用样式主题,可以为一个Activity定义一个主题,也可以为整个应用程序定义一个主题,如下所示:
<application android:theme="@style/CustomTheme">
或者:
<activity android:theme="@style/CustomDialogTheme">
Android平台的样式和主题
样式见:http://www.ideasandroid.com/android/sdk/styles.xml
主题见:http://www.ideasandroid.com/android/sdk/themes.xml
posted @
2010-08-17 17:14 MEYE 阅读(1082) |
评论 (0) |
编辑 收藏
ListView的Adapter的作用如下图所示:
Adapter的作用就是ListView界面与数据之间的桥梁,当列表里的每一项显示到页面时,都会调用Adapter的getView方法返回一个View。想过没有? 在我们的列表有1000000项时会是什么样的?是不是会占用极大的系统资源?
先看看下面的代码:
public View getView(int position, View convertView, ViewGroup parent) {
View item = mInflater.inflate(R.layout.list_item_icon_text, null);
((TextView) item.findViewById(R.id.text)).setText(DATA[position]);
((ImageView) item.findViewById(R.id.icon)).setImageBitmap(
(position & 1) == 1 ? mIcon1 : mIcon2);
return item;
}
怎么样?如果超过1000000项时,后果不堪设想!您可千万别这么写!
我们再来看看下面的代码:
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item, null);
}
((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);
((ImageView) convertView.findViewById(R.id.icon)).setImageBitmap(
(position & 1) == 1 ? mIcon1 : mIcon2);
return convertView;
}
怎么样,上面的代码是不是好了很多?系统将会减少创建很多View。性能得到了很大的提升。
还有没有优化的方法呢? 答案是肯定的:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(DATA[position]);
holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
return convertView;
}
static class ViewHolder {
TextView text;
ImageView icon;
}
怎么样?会不会又给您的系统带来很大的提升呢?看看下面三种方式的性能对比图您就知道了!
本文是Google I/O 2009 Romain Guy 所讲的内容,这里只做简单介绍,相信一看代码就能看懂!有问题请留言!
posted @
2010-08-17 17:13 MEYE 阅读(2914) |
评论 (1) |
编辑 收藏
摘要: 当您需要在您的应用程序中提供搜索服务时,您第一个想到的是您的搜索框要放哪呢?通过使用Android的搜索框架,应用程序将显示一个自定义搜索对话框来处理用户的搜索请求。通过一个简单的搜索按钮或从您的应用程序中调用API,搜索对话框就会显示在屏幕的顶部,并会自动显示您的应用程序图标。如下图所示:
本文将教你如何为你的应用程序提供一个自定义搜索对话框。这样做,给您的用户提供一个标准化的搜索体验,并...
阅读全文
posted @
2010-08-17 17:12 MEYE 阅读(1028) |
评论 (0) |
编辑 收藏
Android开发又将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多多相当优秀的应用。其中也有许许多多的开发者提供了应用开源项 目,贡献出他们的智慧和创造力。学习开源代码是掌握技术的一个最佳方式。下面推荐几个应用开源项目,这些项目不仅提供了优秀的创意,也可以直接掌握 Android内核的接口使用:
1.Android团队提供的示例项目
如果不是从学习Android SDK中提供的那些样例代码开始,可能没有更好的方法来掌握在Android这个框架上开发。由Android的核心开发团队提供了15个优秀的示例项 目,包含了游戏、图像处理、时间显示、开始菜单快捷方式等。
地址:http://code.google.com/p/apps-for-android/
2.Remote Droid
RemoteDroid是一个Android应用,能够让用户使用自己的无线网络使用无线键盘、触摸屏操作手机。这个项目为开发者提供了如网络连接、触 摸屏手指运动等很好的样例。
地址:http://code.google.com/p/remotedroid/
3.TorProxy和Shadow
TorProxy应用实现了Android手机无线电电传通讯(TOR),和Shadow应用一起使用,可以使用手机匿名上网。从该项目源代码中,可以 掌握socket连接、管理cookie等方法。
地址:http://www.cl.cam.ac.uk/research/dtg/code/svn/android-tor/
http://www.cl.cam.ac.uk/research/dtg/android/tor/
4、 Android SMSPopup
SMSPopup可以截获短信内容显示在一个泡泡形状的窗口中。从这个项目中可以掌握到如何使用内置的短信SMS接口。
地址:http://code.google.com/p/android-smspopup/
5、 Standup Timer
Standup Timer应用用于控制站立会议时间,类似秒表倒计时,可以提醒每个人的讲话时间已到,从而保证每个与会者使用时间一样。从该项目的代码中,可以学会如何 使用时间函数。另外,这个项目的代码是采用视图view、模型model严格分离的设计思路。
地址:http://github.com/jwood/standup-timer
6、
是.com的一个客户端应用,该应用主要分为两个模块API(com.joelapenna.foursquare)和界面前端 (com.joelapenna.foursquared)两部分。从该项目代码中,可以学会如何同步、多线程、HTTP连接等技术。
地址:http://code.google.com/p/foursquared/
7、 Pedometer
Pedometer应用用于记录你每天走路步数的。尽管记录不一定精准,但是从这个项目中,可以学习几个不同的技术:加速器交互、语音更新、后台运行服 务等。
地址:http://code.google.com/p/pedometer/
8、 OpenSudoku-android
OpenSudoku是一个简单的九宫格数独游戏。从代码中可以学习到如何在视图中显示表格数据,以及如何和一个网站交互等技术。
地址:http://code.google.com/p/opensudoku-android/
9、 ConnectBot
ConnectBot是Android平台的一个客户端安全壳应用。从该项目代码中,可以学习到很多Android安全方面的内容,这些是你在开发应用 时经常需要考虑的安全问题。
地址:http://code.google.com/p/connectbot/
10、 WordPress的Android应用
当然在最后不能不提WordPress的Android应用了,这是WordPress官方开发团队提供的一个项目。从代码中可以学习到XMLRPC调 用(当然还有更多的优秀内容)。
地址:http://android.svn.wordpress.org/trunk/
posted @
2010-08-17 17:06 MEYE 阅读(538) |
评论 (0) |
编辑 收藏
Ubuntu环境安装配置Bugzilla
|
|
http://www.bugzilla.org/download/#v218
http://www.bugzilla.org/download
1 Bugzilla简介
1.1 产生
Bugzilla是一个共享的免费的产品缺陷记录及跟踪工具。由Mozilla公司提供。创始人是Terry Weissman,开始时使用一种名为“TCL”的语言创建的,后用Perl语言实现,并作为Open source发布。
1.2 特点
Bugzilla能够为你建立一个完善的bug跟踪体系,包括报告bug、查询bug记录并产生报表、处理解决bug、管理员系统初始化和设置四部分。Bugzilla具有如下特点:
1.基于Web方式,安装简单、运行方便快捷、管理安全。
2.有利于缺陷的清楚传达。本系统使用数据库进行管理,提供全面详尽的报告输入项,产生标准化的bug报告。 提供大量的分析选项和强大的查询匹配能力,能根据各种条件组合进行bug统计。当缺陷在它的生命周期中变化时,开发人员、测试人员、及管理人员将及时获得 动态的变化信息,允许你获取历史记录,并在检查缺陷的状态时参考这一记录。
3.系统灵活,强大的可配置能力。Bugzilla工具可以对软件产品设定不同的模块,并针对不同的模块设定开发人员和测试人员。这样可以实现提交报告时 自动发给指定的责任人,并可设定不同的小组,权限也可划分。设定不同的用户对bug记录的操作权限不同,可有效控制进行管理。允许设定不同的严重程度和优 先级。可以在缺陷的生命期中管理缺陷。从最初的报告到最后的解决,确保了缺陷不会被忽略。同时可以使注意力集中在优先级和严重程度高的缺陷上。
4.自动发送Email,通知相关人员。根据设定的不同责任人,自动发送最新的动态信息,有效的帮助测试人员和开发人员进行沟通。
2 安装Step by Step
Bugzilla是一个基于WEB的缺陷管理系统。前台用 Perl语言实现,后台使用MySQL数据库。因为Bugzilla除了通过WEB来跟踪处理bug外,还同时通过Email来跟踪bug的处理过程。如 果不通过Email来跟踪bug的话,Email电子邮件系统并不是必要的。但是,如果要正常运行Bugzilla,必须设置一个smtp邮件发送服务 器。
安装Bugzilla需要MySQL、Perl等等配套软件。为了简化Bugzilla的安装过程,让大家少走弯路,我们把Bugzilla及其配套软件的安装包都整合到一个目录Bugzilla-2.20.1下,并以Step by Step的方式介绍安装及配置过程:
Bugzilla-2.20.1
01.mysql
02.perl
03.bugzilla
04.ReadMe
|
我刚刚入手UNIX系统学习,学着安装配置Bugzilla。被不少的问题折腾着浪费不少时间,查了不少资料,最终还是圆满成功了。在这作个总结,希望这篇博文能帮助初学者。欢迎各位朋友共同探讨学习。
emial:zongguo.zhang@gmail.com
欢迎转载,请注明出处。
bugzilla安装工具 apache2+mysql5.1+perl+bugzilla3.2.2
Step by step
安装篇
1.安装apache2
Ubuntu就可以直接用命令行可以安装 #sudo apt-get install apache2 系统自动安好,打开浏览器在地址栏输入http://ip (你的ip地址或者127.0.0.1)就会在 页面上出现 “ It works”则表明apache安装成功。
出了问题的话,进入/etc/apache2 目录下 用#vi httpd.conf打开文件添加ServerName 127.0.0.1:80即可.
2.安装mysql
用命令#sudo apt-get install mysql-server 系统自动安装,我装的是mysql5.1.
安装时要输入密码这是进入root的密码(建议用你ubuntu系统密码),(mysql -uroot -p密码),然后用上述命令行来登录,登录成功显示版本信息和 mysql> ,OK!
mysql 服务启动/停止/重启命令#service mysql start/stop/restart.
3.安装Bugzilla
bugzilla到官网去下载(一般为tar.gz包),这个不用我说了吧!不懂google一下,然后cd到下载目录解压包#tar -xzf bugzilla.xx.xx.tar.gz ,再改名#mv bugzilla.xx.xx bugzilla ,再移动到/var/www下面#mv bugzilla /var/www 完毕~~~~ok!
4.安装perl
先进入到bugzilla目录#cd /var/www/bugzilla,在命令行输入#./checksetup.pl命令检查一下还有哪些perl模块没有安装,因为在系统自动安转apache和mysql时就已安装一部分,
Checking perl modules...
Checking for CGI.pm (v3.33) ok: found v3.49
Checking for TimeDate (v2.21) ok: found v2.24
Checking for PathTools (v0.84) ok: found v3.31
Checking for DBI (v1.41) ok: found v1.611
Checking for Template-Toolkit (v2.15) ok: found v2.22
Checking for Email-Send (v2.00) ok: found v2.198
Checking for Email-MIME (v1.861) ok: found v1.903
Checking for Email-MIME-Modifier (v1.442) ok: found v1.903
Checking available perl DBD modules...
Checking for DBD-Pg (v1.45) not found
Checking for DBD-mysql (v4.00) ok: found v4.012
Checking for DBD-Oracle (v1.19) not found
第一组要全装,第二组就看你装的什么数据库了,这里装的是mysql就选DBD-mysql,not found表示没有安装,用下面提的COMMANDS TO INSTALL:需要什么就复制粘贴就可安装好。
到这里Buglilla所需要的组件全安装完毕,第一篇OK!
配置篇
1.apache2配置
A.修改 apache的配置文件apache2.conf:进入/etc/www/apache2目录下面 vi /apache2.conf 找到ServerRoot,修改ServerRoot 为bugzilla所在的目录“/var/www”,即如下:(注释原来的添加修改)
#ServerRoot "/etc/apache2"
ServerRoot "/var/www"
B.修改apache的配置文件apache2.conf: 设置 apache访问bugzilla的用户及用户组,本安装中将用户及用户组都设置为www-data:如下:
#User ${APACHE_RUN_USER}
#Group ${APACHE_RUN_GROUP}
User www-data
Group www-data
C.修改apache的配置文件apache2.conf:添加bugzilla所在目录:即在apache.conf文件末添加如下
Alias /bug/ "/var/www/bugzilla"
<Directory "/var/www/bugzilla">
AddHandler cgi-script .cgi
Options +Indexes +ExecCGI +FollowSymLinks
DirectoryIndex index.cgi
AllowOverride None
Order allow,deny
Allow from all
</Directory>
D: 修改 www-data对bugzilla的访问权限
chown -R www-data:www-data /var/www/bugzilla
最后,重启apache2服务 #/etc/init.d/apache2 restart ~~~~~OK!
2.mysql配置
用#mysql -uroot -p密码 登录mysql 。
首先,创建数据库bugs mysql> create database bugs;
其次,创建用户bugs mysql> use mysql;
再次,授权 mysql> GRANT SELECT, INSERT,UPDATE, DELETE, INDEX, ALTER, CREATE, LOCK TABLES,CREATE TEMPORARY TABLES, DROP, REFERENCES ON bugs.*TO bugs@localhost IDENTIFIED BY '前面root密码';
最后,mysql> FLUSH PRIVILEGES;
退出mysql:mysql>exit或quit
注:mysql命令以(;)结束,不区分大小写。
3.Bugzilla配置
先#cd /var/www/bugzilla 运行bugzilla目录下的checksetup.pl (#.checksetup.pl)自动生成loacalconfig文件(原本bugzilla目录里没有),打开文件localconfig(#vi localconfig),配置如下:
$webservergroup = 'www-data';
$db_driver = 'mysql';
$db_host = 'localhost';
$db_name = 'bugs';
$db_user = 'bugs';
$db_pass = '密码'; 注意:为了防止出错,建议所有密码都设置为ubuntu系统密码。
其它不变。
现的配置文件都设置完成,重启apache2 #/etc/init.d/apache2 restart
重启mysql #service mysql restart
重新运行checksetuo.pl #./checksetup.pl
结果会出现如下错误:
SESSION variable 'max_allowed_packet' is read only. Use SET GLOBAL to assign
the value
上面错误的原因是bugzilla3.3.2对mysql5.1及以上新版本的兼容性不好。需要修改几处源码文件Bugzilla/Config/Attachment.pm和Bugzilla/Config/Common.pm等,地址:https://bug480001.bugzilla.mozilla.org/attachment.cgi?id=364818其中(-)表示删除(+)表示添加。
bugzilla的预编译和生成相应的配置信息等,如下提示:
Precompiling templates...done.
Fixing file permissions...
Initializing "Dependency Tree Changes" email_setting ...
Marking closed bug statuses as such...
Now filling the 'status_workflow' table with valid bug status transitions...
Adding foreign key: attachments.submitter_id -> profiles.userid...
Adding foreign key: bugs_activity.who -> profiles.userid...
Adding foreign key: bugs_fulltext.bug_id -> bugs.bug_id...
·
·
·
并且会提示输入以下信息:
Enter the e-mail address of the administrator: test@uestc.edu.cn
Enter the real name of the administrator: 用户名
Enter a password for the administrator account: password
Please retype the password to verify: password
根据以上提示输入bugzilla管理员的相关信息
成功后,在浏览器输入:http://127.0.0.1/bugzilla会出现bugzilla的管理主页面
应用篇
Bugzilla网上有很多使用文档,我就不再细述。主要想说一下bugzilla发不出去邮件的问题。
配置smtp。
登录后点击administrator进行参数设置,点击parameter进入,再点击email设置。
mail_delivery_method : smtp
mailfrom : 设置成我的真实邮箱 例 me@163.com 可能有的mail server会验证邮箱的真实性以及是否属于该mail server
sendmailnow : on
smtpserver : 设置成smtp authentication服务器 例smtp.163.com
smtp_username : 我的邮箱 例 me@163.com
smtp_password : 密码
注意后两个parameters(选项)是2.22.1 debian所没有的。
但是接下来我在测试发送邮件的时候总是报
“The new value for smtp_username is invalid: Error requiring
Authen::SASL: ‘Can’t locate Authen/SASL.pm in @INC (@INC contains: .
lib c:/perl/site/lib c:/perl/lib) at (eval 84) line 3. ‘.”
这个错误要求我们安装Authen::SASL 可以回到checksetup.pl处按照提示安装,但是我在这里却出现了问题。
由于之前已经将bugzilla3.2.2文件夹的访问权限设置给了www-data组,现在无法进入到bugzilla3.2.2文件夹内执行任何操作,总报permissions access
采用 sudo –s –H 并输入密码,可以以root权限进入该文件夹操作,安装好Authen::SASL后,发送邮件功能ok。
|
|
posted @
2010-08-13 14:00 MEYE 阅读(2027) |
评论 (1) |
编辑 收藏
摘要: 这些道理不懂,你注定就是穷打工的命
http://kb.cnblogs.com/page/57888/
首先声明:如果你是“愤青”或“类愤青”,对不起,请放下此书,因为文中的观点可能会伤害你的心灵(不是对“愤青”有偏见,而是“愤青”们多数都是“纯洁”得不识人间烟火...
阅读全文
posted @
2010-08-12 22:28 MEYE 阅读(477) |
评论 (0) |
编辑 收藏
摘要: Ubuntu 6.06/7.04 安装bugzilla
弄了好久才安装成功,记下来备忘!
1.安装mysql
sudo apt-get install mysql-server
mysql -uroot
create database bugzilla;
2.安装apache2
sudo apt-get in...
阅读全文
posted @
2010-08-12 22:14 MEYE 阅读(680) |
评论 (1) |
编辑 收藏
在windows下配置svn服务器(方法一,无apache
1.下载文件
2.安装Subversion 服务器
由于我下载的是setup.exe版本,安装程序安装后会自动设置系统变量.如果你下载的是zip版就需要手动设置系统变量.
setup.exe版直接安装就可以了.安装到D:\Program Files\Subversion
首先创建SVN储存库(repository)
svnadmin create F:\lava\svn\
【注】创建仓库的方法也可以使用TortoiseSVN,在目的文件夹上右键->Create Repository
repository创建完毕后会在目录下生成若干个文件和文件夹,dav目录是提供给Apache与mod_dav_svn使用的目录,让它们存储内部数据;db目录就是所有版本控制的数据文件;hooks目录放置hook脚本文件的目录;locks用来放置Subversion文件库锁定数据的目录,用来追踪存取文件库的客户端;format文件是一个文本文件,里面只放了一个整数,表示当前文件库配置的版本号;
3.配置SVN服务器
打开svn目录中配置文件conf\svnserve.conf,修改配置参数。
例:d:\svnhome\conf\svnserve.conf去掉以下内容之前的注释符#
[general]
anon-access = none
auth-access = write
password-db = passwd
realm = My First Repository
说明:
anon-access = none
--不允许匿名访问!这个很重要,不然谁都能访问这个代码仓库了。
auth-access = write
-- 允许提交修改
password-db = passwd
--密码文件名字
【注】如果需要控制访问的用户身份,则:
# [general]
# password-db = passwd
去之每行开头的#,其中第二行是指定身份验证的文件名,即passwd文件
同样打开passwd文件,将
# [users]
# harry = harryssecret
# sally = sallyssecret
这几行的开头#字符去掉,这是设置用户,一行一个,存储格式为“用户名 = 密码”,如可插入一行:admin = admin888,即为系统添加一个用户名为admin,密码为admin888的用户
4.运行SVN服务器
运行SVN服务
在命令行执行
svnserve --daemon --root F:\lava\svn
服务启动,--daemon可简写为-d,--root可简写为-r,可以建立一个批处理文件并放在windows启动组中便于开机就运行SVN服务,或者在这个地址http://clanlib.org/~mbn/svnservice/下载那个svnservice.exe文件,拷贝到E:\svn\bin目录下,再从命令行下执行:
svnservice -install --daemon --root "E:\svn\Repository"
sc config svnservice start= auto
net start svnservice
5、添加为系统服务
方法1(推荐):
在Windows NT中(包括Windows XP, Windows 2000, Windows 2003 Server)本身包含了一个安装服务的工具,叫做"Service Control",也就是sc.exe。
1.安装为服务:
例:我的Subversion安装在"D:\program files\Subversion",版本库在"D:\svn_root",而我希望对应的Subversion服务名为svnservice,安装这个svn服务的命令就可以这样写:
sc create svnservice
binpath= "D:\ Program Files\Subversion\bin\svnserve.exe --service -r D:\svn_root"
displayname= "SVNService"
depend= Tcpip
请注意,因为便于察看,上面的命令分为多行,但在实际执行时应该在一行里。另外,在以前启动svnserve时会使用"-d"选项,也就是守护进程模式,在这里不能使用,会导致服务无法启动。同样,"-i"和"-t"选项也不能使用。
另外还有两点需要小心处理。首先,如果路径中包括空格,一定要用“\”处理“"”号,例如上面的例子中如果svnserve.exe在“c:\ program files\subversion\”中,则命令应该写为“binpath= "\"c:\program files\subversion\bin\svnserve.exe\"”(“”中的内容),整个命令如下,红色部分是改变部分:
sc create svnservice
binpath= "\"D:\ Program Files\Subversion\bin\svnserve.exe\" --service -r D:\svnroot"
displayname= "SVNService"
depend= Tcpip
其次,sc对选项的格式还有要求,例如“depend= Tcpip”不能写为“depend = Tcpip”或“depend=Tcpip”,也就是“=”前不能有空各,而后面必须有空格。
2.启动服务
在命令行窗口执行完这个命令之后,服务还没有启动,你可以继续运行"net start svnservice"启动这个服务。
3.停止服务
然后使用"net stop svnservice"停止服务。
4.删除服务
如果服务安装的有问题,你可能需要删除服务。要删除前面添加的服务,只需要运行"sc delete svnservice","svnservice"就是我们创建服务时使用的名字。
5.配置服务是自动启动
默认情况下安装的服务不会随Windows的启动而启动,为了使svn服务能够随Windows启动而启动,需要修改一下"sc create"命令(首先要删除),增加"start= auto"选项:
sc create svnservice
binpath= "D:\ Program Files\Subversion\bin\svnserve.exe --service -r D:\svn_root"
displayname= "SVNService"
depend= Tcpip
start= auto
当然你也可以使用图形化的工具修改服务的属性,你可以在“开始->运行...”中执行"services.msc",然后在界面中修改。
方法2:
建立一个批处理文件并放在windows启动组中便于开机就运行SVN服务。
方法3:
这个地址http://clanlib.org/~mbn/svnservice/下载那个svnservice.exe文件,拷贝到E:\svn\bin目录下,再从命令行下执行:
svnservice --install --daemon --root "E:\svn\Repository"
sc config svnservice start= auto
net start svnservice
此文件会将SVN变成windows系统的一个服务,并默认为自启动,注意:执行第三句时确保前面以命令行方式运行的SVN服务已经停止,如果没停止可在其窗口中按Ctrl+C中止运行。
轻松搭建一个Windows SVN服务器
前文所述SVN客户端使用的时候,用的SVN服务器通常为外部,例如Google Code的服务器,不过,做为一个程序开发人员,就算自己一个人写程序,也应该有一个SVN版本控制系统,以便对开发代码进行有效的管理。这里我就介绍一个在Windows环境下简单快速搭建SVN服务器的方法。
通常的SVN服务器是搭建在Linux等系统下,例如用Apache+SVN配置,Linux下的SVN性能会非常好,但配置有些繁琐,如果SVN服务器只有自己使用,那么可以直接把SVN服务器搭建在个人Windows环境下使用。
目前较为简单的方案是VisualSVN Server。该SVN服务器是免费的,支持Windows NT, 2000, XP and 2003等环境,安装非常简单。
安装的时候可以选择SVN走http协议还是https协议,http协议速度快一些,而https协议安全性好。两者均可以从浏览器直接访问SVN项目。
安装完成后打开,可以看到一个微软的MMS管理界面,在里面可以轻松添加设置项目。用户权限可以使用Windows的用户,也可以单独新建用户。如果原先有一个SVN数据,则可以在界面上导入原有的SVN数据。
SVN客户端依旧推荐使用Windows下的TortoiseSVN,两者搭配起来,非常好用。
posted @
2010-03-10 13:16 MEYE 阅读(1291) |
评论 (0) |
编辑 收藏
http://blog.163.com/dahebaobao@126/blog/static/50974483201002745726971/
posted @
2010-01-30 20:08 MEYE 阅读(655) |
评论 (1) |
编辑 收藏
PCI驱动程序实现(linux)收藏
1. 关键数据结构
PCI 设备上有三种地址空间:PCI的I/O空间、PCI的存储空间和PCI的配置空间。CPU可以访问PCI设备上的所有地址空间,其中I/O空间和存储空间提供给设备驱动程序使用,而配置空间则由Linux内核中的PCI初始化代码使用。内核在启动时负责对所有PCI设备进行初始化,配置好所有的PCI设备,包括中断号以及I/O基址,并在文件/proc/pci中列出所有找到的PCI设备,以及这些设备的参数和属性。
Linux驱动程序通常使用结构(struct)来表示一种设备,而结构体中的变量则代表某一具体设备,该变量存放了与该设备相关的所有信息。好的驱动程序都应该能驱动多个同种设备,每个设备之间用次设备号进行区分,如果采用结构数据来代表所有能由该驱动程序驱动的设备,那么就可以简单地使用数组下标来表示次设备号。
在PCI驱动程序中,下面几个关键数据结构起着非常核心的作用:
pci_driver
这个数据结构在文件include/linux/pci.h里,这是Linux内核版本2.4之后为新型的PCI设备驱动程序所添加的,其中最主要的是用于识别设备的id_table结构,以及用于检测设备的函数probe( )和卸载设备的函数remove( ):
struct pci_driver {
struct list_head node;
char *name;
const struct pci_device_id *id_table;
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id);
void (*remove) (struct pci_dev *dev);
int (*save_state) (struct pci_dev *dev, u32 state);
int (*suspend)(struct pci_dev *dev, u32 state);
int (*resume) (struct pci_dev *dev);
int (*enable_wake) (struct pci_dev *dev, u32 state, int enable);
};
pci_dev
这个数据结构也在文件include/linux/pci.h里,它详细描述了一个PCI设备几乎所有的硬件信息,包括厂商ID、设备ID、各种资源等:
struct pci_dev {
struct list_head global_list;
struct list_head bus_list;
struct pci_bus *bus;
struct pci_bus *subordinate;
void *sysdata;
struct proc_dir_entry *procent;
unsigned int devfn;
unsigned short vendor;
unsigned short device;
unsigned short subsystem_vendor;
unsigned short subsystem_device;
unsigned int class;
u8 hdr_type;
u8 rom_base_reg;
struct pci_driver *driver;
void *driver_data;
u64 dma_mask;
u32 current_state;
unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE];
unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE];
unsigned int irq;
struct resource resource[DEVICE_COUNT_RESOURCE];
struct resource dma_resource[DEVICE_COUNT_DMA];
struct resource irq_resource[DEVICE_COUNT_IRQ];
char name[80];
char slot_name[8];
int active;
int ro;
unsigned short regs;
int (*prepare)(struct pci_dev *dev);
int (*activate)(struct pci_dev *dev);
int (*deactivate)(struct pci_dev *dev);
};
2. 基本框架
在用模块方式实现PCI设备驱动程序时,通常至少要实现以下几个部分:初始化设备模块、设备打开模块、数据读写和控制模块、中断处理模块、设备释放模块、设备卸载模块。下面给出一个典型的PCI设备驱动程序的基本框架,从中不难体会到这几个关键模块是如何组织起来的。
/* 指明该驱动程序适用于哪一些PCI设备 */
static struct pci_device_id demo_pci_tbl [] __initdata = {
{PCI_VENDOR_ID_DEMO, PCI_DEVICE_ID_DEMO,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEMO},
{0,}
};
/* 对特定PCI设备进行描述的数据结构 */
struct demo_card {
unsigned int magic;
/* 使用链表保存所有同类的PCI设备 */
struct demo_card *next;
/* ... */
}
/* 中断处理模块 */
static void demo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
/* ... */
}
/* 设备文件操作接口 */
static struct file_operations demo_fops = {
owner: THIS_MODULE, /* demo_fops所属的设备模块 */
read: demo_read, /* 读设备操作*/
write: demo_write, /* 写设备操作*/
ioctl: demo_ioctl, /* 控制设备操作*/
mmap: demo_mmap, /* 内存重映射操作*/
open: demo_open, /* 打开设备操作*/
release: demo_release /* 释放设备操作*/
/* ... */
};
/* 设备模块信息 */
static struct pci_driver demo_pci_driver = {
name: demo_MODULE_NAME, /* 设备模块名称 */
id_table: demo_pci_tbl, /* 能够驱动的设备列表 */
probe: demo_probe, /* 查找并初始化设备 */
remove: demo_remove /* 卸载设备模块 */
/* ... */
};
static int __init demo_init_module (void)
{
/* ... */
}
static void __exit demo_cleanup_module (void)
{
pci_unregister_driver(&demo_pci_driver);
}
/* 加载驱动程序模块入口 */
module_init(demo_init_module);
/* 卸载驱动程序模块入口 */
module_exit(demo_cleanup_module);
上面这段代码给出了一个典型的PCI设备驱动程序的框架,是一种相对固定的模式。需要注意的是,同加载和卸载模块相关的函数或数据结构都要在前面加上 __init、__exit等标志符,以使同普通函数区分开来。构造出这样一个框架之后,接下去的工作就是如何完成框架内的各个功能模块了。
3. 初始化设备模块
在Linux系统下,想要完成对一个PCI设备的初始化,需要完成以下工作:
* 检查PCI总线是否被Linux内核支持;
* 检查设备是否插在总线插槽上,如果在的话则保存它所占用的插槽的位置等信息。
* 读出配置头中的信息提供给驱动程序使用。
当Linux内核启动并完成对所有PCI设备进行扫描、登录和分配资源等初始化操作的同时,会建立起系统中所有PCI设备的拓扑结构,此后当PCI驱动程序需要对设备进行初始化时,一般都会调用如下的代码:
static int __init demo_init_module (void)
{
/* 检查系统是否支持PCI总线 */
if (!pci_present())
return -ENODEV;
/* 注册硬件驱动程序 */
if (!pci_register_driver(&demo_pci_driver)) {
pci_unregister_driver(&demo_pci_driver);
return -ENODEV;
}
return 0;
}
驱动程序首先调用函数pci_present( )检查PCI总线是否已经被Linux内核支持,如果系统支持PCI总线结构,这个函数的返回值为0,如果驱动程序在调用这个函数时得到了一个非0的返回值,那么驱动程序就必须得中止自己的任务了。在2.4以前的内核中,需要手工调用pci_find_device( )函数来查找PCI设备,但在2.4以后更好的办法是调用pci_register_driver( )函数来注册PCI设备的驱动程序,此时需要提供一个pci_driver结构,在该结构中给出的probe探测例程将负责完成对硬件的检测工作。
static int __init demo_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
{
struct demo_card *card;
/* 启动PCI设备 */
if (pci_enable_device(pci_dev))
return -EIO;
/* 设备DMA标识 */
if (pci_set_dma_mask(pci_dev, DEMO_DMA_MASK)) {
return -ENODEV;
}
/* 在内核空间中动态申请内存 */
if ((card = kmalloc(sizeof(struct demo_card), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "pci_demo: out of memory\n");
return -ENOMEM;
}
memset(card, 0, sizeof(*card));
/* 读取PCI配置信息 */
card->iobase = pci_resource_start (pci_dev, 1);
card->pci_dev = pci_dev;
card->pci_id = pci_id->device;
card->irq = pci_dev->irq;
card->next = devs;
card->magic = DEMO_CARD_MAGIC;
/* 设置成总线主DMA模式 */
pci_set_master(pci_dev);
/* 申请I/O资源 */
request_region(card->iobase, 64, card_names[pci_id->driver_data]);
return 0;
}
4. 打开设备模块
在这个模块里主要实现申请中断、检查读写模式以及申请对设备的控制权等。在申请控制权的时候,非阻塞方式遇忙返回,否则进程主动接受调度,进入睡眠状态,等待其它进程释放对设备的控制权。
static int demo_open(struct inode *inode, struct file *file)
{
/* 申请中断,注册中断处理程序 */
request_irq(card->irq, &demo_interrupt, SA_SHIRQ,
card_names[pci_id->driver_data], card)) {
/* 检查读写模式 */
if(file->f_mode & FMODE_READ) {
/* ... */
}
if(file->f_mode & FMODE_WRITE) {
}
/* 申请对设备的控制权 */
down(&card->open_sem);
while(card->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
/* NONBLOCK模式,返回-EBUSY */
up(&card->open_sem);
return -EBUSY;
} else {
/* 等待调度,获得控制权 */
card->open_mode |= f_mode & (FMODE_READ | FMODE_WRITE);
up(&card->open_sem);
/* 设备打开计数增1 */
MOD_INC_USE_COUNT;
}
}
}
5. 数据读写和控制信息模块
PCI设备驱动程序可以通过demo_fops 结构中的函数demo_ioctl( ),向应用程序提供对硬件进行控制的接口。例如,通过它可以从I/O寄存器里读取一个数据,并传送到用户空间里:
static int demo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd) {
case DEMO_RDATA:
/* 从I/O端口读取4字节的数据 */
val = inl(card->iobae + 0x10);
/* 将读取的数据传输到用户空间 */
return 0;
}
}
事实上,在demo_fops里还可以实现诸如demo_read( )、demo_mmap( )等操作,Linux内核源码中的driver目录里提供了许多设备驱动程序的源代码,找那里可以找到类似的例子。在对资源的访问方式上,除了有I/O指令以外,还有对外设I/O内存的访问。对这些内存的操作一方面可以通过把I/O内存重新映射后作为普通内存进行操作,另一方面也可以通过总线主DMA (Bus Master DMA)的方式让设备把数据通过DMA传送到系统内存中。
6. 中断处理模块
PC的中断资源比较有限,只有0~15的中断号,因此大部分外部设备都是以共享的形式申请中断号的。当中断发生的时候,中断处理程序首先负责对中断进行识别,然后再做进一步的处理。
static void demo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct demo_card *card = (struct demo_card *)dev_id;
u32 status;
spin_lock(&card->lock);
/* 识别中断 */
status = inl(card->iobase + GLOB_STA);
if(!(status & INT_MASK))
{
spin_unlock(&card->lock);
return; /* not for us */
}
/* 告诉设备已经收到中断 */
outl(status & INT_MASK, card->iobase + GLOB_STA);
spin_unlock(&card->lock);
/* 其它进一步的处理,如更新DMA缓冲区指针等 */
}
7. 释放设备模块
释放设备模块主要负责释放对设备的控制权,释放占用的内存和中断等,所做的事情正好与打开设备模块相反:
static int demo_release(struct inode *inode, struct file *file)
{
/* 释放对设备的控制权 */
card->open_mode &= (FMODE_READ | FMODE_WRITE);
/* 唤醒其它等待获取控制权的进程 */
wake_up(&card->open_wait);
up(&card->open_sem);
/* 释放中断 */
free_irq(card->irq, card);
/* 设备打开计数增1 */
MOD_DEC_USE_COUNT;
}
8. 卸载设备模块
调用函数pci_unregister_driver( )从Linux内核中注销设备驱动程序
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mingjie_520/archive/2009/03/27/4029695.aspx
posted @
2009-06-20 16:02 MEYE 阅读(696) |
评论 (0) |
编辑 收藏
Linux下PCI设备驱动程序开发基本框架收藏
PCI是一种广泛采用的总线标准,它提供了许多优于其它总线标准(如EISA)的新特性,目前已经成为计算 机系统中应用最为广泛,并且最为通用的总线标准。Linux的内核能较好地支持PCI总线,本文以Intel 386体系结构为主,探讨了在Linux下开发PCI设备驱动程序的基本框架。
一、PCI总线系统体系结构
PCI是外围设备互连(Peripheral Component Interconnect)的简称,作为一种通用的总线接口标准,它在目前的计算机系统中得到了非常广泛的应用。PCI提供了一组完整的总线接口规范,其 目的是描述如何将计算机系统中的外围设备以一种结构化和可控化的方式连接在一起,同时它还刻画了外围设备在连接时的电气特性和行为规约,并且详细定义了计 算机系统中的各个不同部件之间应该如何正确地进行交互。
无论是在基于Intel芯片的PC机中,或是在基于Alpha芯片的工作 站上,PCI毫无疑问都是目前使用最广泛的一种总线接口标准。同旧式的ISA总线不同,PCI将计算机系统中的总线子系统与存储子系统完全地分开,CPU 通过一块称为PCI桥(PCI-Bridge)的设备来完成同总线子系统的交互,如图1所示。
图1 PCI子系统的体系结构
由于使用了更高的时钟频率,因此PCI总线能够获得比ISA总线更好的整体性能。PCI总线的时钟频率一般在25MHz到33MHz范围内,有些甚至能 够达到66MHz或者133MHz,而在64位系统中则最高能达到266MHz。尽管目前PCI设备大多采用32位数据总线,但PCI规范中已经给出了 64位的扩展实现,从而使PCI总线能够更好地实现平台无关性,现在PCI总线已经能够用于IA-32、Alpha、PowerPC、SPARC64和 IA-64等体系结构中。
PCI总线具有三个非常显著的优点,使得它能够完成最终取代ISA总线这一历史使命:
在计算机和外设间传输数据时具有更好的性能;
能够尽量独立于具体的平台;
可以很方便地实现即插即用。
图2是一个典型的基于PCI总线的计算机系统逻辑示意图,系统的各个部分通过PCI总线和PCI-PCI桥连接在一起。从图中不难看出,CPU和RAM 需要通过PCI桥连接到PCI总线0(即主PCI总线),而具有PCI接口的显卡则可以直接连接到主PCI总线上。PCI-PCI桥是一个特殊的PCI设 备,它负责将PCI总线0和PCI总线1(即从PCI主线)连接在一起,通常PCI总线1称为PCI-PCI桥的下游(downstream),而PCI 总线0则称为PCI-PCI桥的上游(upstream)。图中连接到从PCI总线上的是SCSI卡和以太网卡。为了兼容旧的ISA总线标准,PCI总线 还可以通过PCI-ISA桥来连接ISA总线,从而能够支持以前的ISA设备。图中ISA总线上连接着一个多功能I/O控制器,用于控制键盘、鼠标和软 驱。
图2 PCI系统示意图
在此我只对PCI总线系统体系结构作了概括性介绍,如果读者想进一步了解,David A Rusling在The Linux Kernel(http://tldp.org/LDP/tlk/dd/pci.html)中对Linux的PCI子系统有比较详细的介绍。
二、Linux驱动程序框架
Linux将所有外部设备看成是一类特殊文件,称之为“设备文件”,如果说系统调用是Linux内核和应用程序之间的接口,那么设备驱动程序则可以看成是 Linux内核与外部设备之间的接口。设备驱动程序向应用程序屏蔽了硬件在实现上的细节,使得应用程序可以像操作普通文件一样来操作外部设备。
1. 字符设备和块设备
Linux抽象了对硬件的处理,所有的硬件设备都可以像普通文件一样来看待:它们可以使用和操作文件相同的、标准的系统调用接口来完成打开、关闭、读写和 I/O控制操作,而驱动程序的主要任务也就是要实现这些系统调用函数。Linux系统中的所有硬件设备都使用一个特殊的设备文件来表示,例如,系统中的第 一个IDE硬盘使用/dev/hda表示。每个设备文件对应有两个设备号:一个是主设备号,标识该设备的种类,也标识了该设备所使用的驱动程序;另一个是 次设备号,标识使用同一设备驱动程序的不同硬件设备。设备文件的主设备号必须与设备驱动程序在登录该设备时申请的主设备号一致,否则用户进程将无法访问到 设备驱动程序。
在Linux操作系统下有两类主要的设备文件:一类是字符设备,另一类则是块设备。字符设备是以字节为单位逐个进行I/O操作的设备,在对字符设备发出读 写请求时,实际的硬件I/O紧接着就发生了,一般来说字符设备中的缓存是可有可无的,而且也不支持随机访问。块设备则是利用一块系统内存作为缓冲区,当用 户进程对设备进行读写请求时,驱动程序先查看缓冲区中的内容,如果缓冲区中的数据能满足用户的要求就返回相应的数据,否则就调用相应的请求函数来进行实际 的I/O操作。块设备主要是针对磁盘等慢速设备设计的,其目的是避免耗费过多的CPU时间来等待操作的完成。一般说来,PCI卡通常都属于字符设备。
所有已经注册(即已经加载了驱动程序)的硬件设备的主设备号可以从/proc/devices文件中得到。使用mknod命令可以创建指定类型的设备文件,同时为其分配相应的主设备号和次设备号。例如,下面的命令:
[root@gary root]# mknod /dev/lp0 c 6 0
将建立一个主设备号为6,次设备号为0的字符设备文件/dev/lp0。当应用程序对某个设备文件进行系统调用时,Linux内核会根据该设备文件的设备 类型和主设备号调用相应的驱动程序,并从用户态进入到核心态,再由驱动程序判断该设备的次设备号,最终完成对相应硬件的操作。
2. 设备驱动程序接口
Linux中的I/O子系统向内核中的其他部分提供了一个统一的标准设备接口,这是通过include/linux/fs.h中的数据结构file_operations来完成的:
struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*write) (struct file *, const char *, size_t, loff_t *); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);};
当应用程序对设备文件进行诸如open、close、read、write等操作时,Linux内核将通过file_operations结构访问驱动程 序提供的函数。例如,当应用程序对设备文件执行读操作时,内核将调用file_operations结构中的read函数。
3. 设备驱动程序模块
Linux下的设备驱动程序可以按照两种方式进行编译,一种是直接静态编译成内核的一部分,另一种则是编译成可以动态加载的模块。如果编译进内核的话,会增加内核的大小,还要改动内核的源文件,而且不能动态地卸载,不利于调试,所有推荐使用模块方式。
从本质上来讲,模块也是内核的一部分,它不同于普通的应用程序,不能调用位于用户态下的C或者C++库函数,而只能调用Linux内核提供的函数,在/proc/ksyms中可以查看到内核提供的所有函数。
在以模块方式编写驱动程序时,要实现两个必不可少的函数init_module( )和cleanup_module( ),而且至少要包含和两 个头文件。在用gcc编译内核模块时,需要加上-DMODULE -D__KERNEL__ -DLINUX这几个参数,编译生成的模块(一般为.o文件)可以使用命令insmod载入Linux内核,从而成为内核的一个组成部分,此时内核会调用 模块中的函数init_module( )。当不需要该模块时,可以使用rmmod命令进行卸载,此进内核会调用模块中的函数cleanup_module( )。任何时候都可以使用命令来lsmod查看目前已经加载的模块以及正在使用该模块的用户数。
4. 设备驱动程序结构
了解设备驱动程序的基本结构(或者称为框架),对开发人员而言是非常重要的,Linux的设备驱动程序大致可以分为如下几个部分:驱动程序的注册与注销、设备的打开与释放、设备的读写操作、设备的控制操作、设备的中断和轮询处理。
驱动程序的注册与注销
向系统增加一个驱动程序意味着要赋予它一个主设备号,这可以通过在驱动程序的初始化过程中调用register_chrdev( )或者register_blkdev( )来完成。而在关闭字符设备或者块设备时,则需要通过调用unregister_chrdev( )或unregister_blkdev( )从内核中注销设备,同时释放占用的主设备号。
设备的打开与释放
打开设备是通过调用file_operations结构中的函数open( )来完成的,它是驱动程序用来为今后的操作完成初始化准备工作的。在大部分驱动程序中,open( )通常需要完成下列工作:
1.检查设备相关错误,如设备尚未准备好等。
2.如果是第一次打开,则初始化硬件设备。
3.识别次设备号,如果有必要则更新读写操作的当前位置指针f_ops。
4.分配和填写要放在file->private_data里的数据结构。
5.使用计数增1。
释放设备是通过调用file_operations结构中的函数release( )来完成的,这个设备方法有时也被称为close( ),它的作用正好与open( )相反,通常要完成下列工作:
1.使用计数减1。
2.释放在file->private_data中分配的内存。
3.如果使用计算为0,则关闭设备。
设备的读写操作
字符设备的读写操作相对比较简单,直接使用函数read( )和write( )就可以了。但如果是块设备的话,则需要调用函数block_read( )和block_write( )来进行数据读写,这两个函数将向设备请求表中增加读写请求,以便Linux内核可以对请求顺序进行优化。由于是对内存缓冲区而不是直接对设备进行操作 的,因此能很大程度上加快读写速度。如果内存缓冲区中没有所要读入的数据,或者需要执行写操作将数据写入设备,那么就要执行真正的数据传输,这是通过调用 数据结构blk_dev_struct中的函数request_fn( )来完成的。
设备的控制操作
除了读写操作外,应用程序有时还需要对设备进行控制,这可以通过设备驱动程序中的函数ioctl( )来完成。ioctl( )的用法与具体设备密切关联,因此需要根据设备的实际情况进行具体分析。
设备的中断和轮询处理
对于不支持中断的硬件设备,读写时需要轮流查询设备状态,以便决定是否继续进行数据传输。如果设备支持中断,则可以按中断方式进行操作。
三、PCI驱动程序实现
1. 关键数据结构
PCI设备上有三种地址空间:PCI的I/O空间、PCI的存储空间和PCI的配置空间。CPU可以访问PCI设备上的所有地址空间,其中I/O空间和存 储空间提供给设备驱动程序使用,而配置空间则由Linux内核中的PCI初始化代码使用。内核在启动时负责对所有PCI设备进行初始化,配置好所有的 PCI设备,包括中断号以及I/O基址,并在文件/proc/pci中列出所有找到的PCI设备,以及这些设备的参数和属性。
Linux驱动程序通常使用结构(struct)来表示一种设备,而结构体中的变量则代表某一具体设备,该变量存放了与该设备相关的所有信息。好的驱动程 序都应该能驱动多个同种设备,每个设备之间用次设备号进行区分,如果采用结构数据来代表所有能由该驱动程序驱动的设备,那么就可以简单地使用数组下标来表 示次设备号。
在PCI驱动程序中,下面几个关键数据结构起着非常核心的作用:
pci_driver
这个数据结构在文件include/linux/pci.h里,这是Linux内核版本2.4之后为新型的PCI设备驱动程序所添加的,其中最主要的是用于识别设备的id_table结构,以及用于检测设备的函数probe( )和卸载设备的函数remove( ):
struct pci_driver { struct list_head node; char *name; const struct pci_device_id *id_table; int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); void (*remove) (struct pci_dev *dev); int (*save_state) (struct pci_dev *dev, u32 state); int (*suspend)(struct pci_dev *dev, u32 state); int (*resume) (struct pci_dev *dev); int (*enable_wake) (struct pci_dev *dev, u32 state, int enable);};
pci_dev
这个数据结构也在文件include/linux/pci.h里,它详细描述了一个PCI设备几乎所有的硬件信息,包括厂商ID、设备ID、各种资源等:
struct pci_dev { struct list_head global_list; struct list_head bus_list; struct pci_bus *bus; struct pci_bus *subordinate; void *sysdata; struct proc_dir_entry *procent; unsigned int devfn; unsigned short vendor; unsigned short device; unsigned short subsystem_vendor; unsigned short subsystem_device; unsigned int class; u8 hdr_type; u8 rom_base_reg; struct pci_driver *driver; void *driver_data; u64 dma_mask; u32 current_state; unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE]; unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE]; unsigned int irq; struct resource resource[DEVICE_COUNT_RESOURCE]; struct resource dma_resource[DEVICE_COUNT_DMA]; struct resource irq_resource[DEVICE_COUNT_IRQ]; char name[80]; char slot_name[8]; int active; int ro; unsigned short regs; int (*prepare)(struct pci_dev *dev); int (*activate)(struct pci_dev *dev); int (*deactivate)(struct pci_dev *dev);};
2. 基本框架
在用模块方式实现PCI设备驱动程序时,通常至少要实现以下几个部分:初始化设备模块、设备打开模块、数据读写和控制模块、中断处理模块、设备释放模块、设备卸载模块。下面给出一个典型的PCI设备驱动程序的基本框架,从中不难体会到这几个关键模块是如何组织起来的。
/* 指明该驱动程序适用于哪一些PCI设备 */static struct pci_device_id demo_pci_tbl [] __initdata = { {PCI_VENDOR_ID_DEMO, PCI_DEVICE_ID_DEMO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEMO}, {0,}};/* 对特定PCI设备进行描述的数据结构 */struct demo_card { unsigned int magic; /* 使用链表保存所有同类的PCI设备 */ struct demo_card *next; /* ... */}/* 中断处理模块 */static void demo_interrupt(int irq, void *dev_id, struct pt_regs *regs){ /* ... */}/* 设备文件操作接口 */static struct file_operations demo_fops = { owner: THIS_MODULE, /* demo_fops所属的设备模块 */ read: demo_read, /* 读设备操作*/ write: demo_write, /* 写设备操作*/ ioctl: demo_ioctl, /* 控制设备操作*/ mmap: demo_mmap, /* 内存重映射操作*/ open: demo_open, /* 打开设备操作*/ release: demo_release /* 释放设备操作*/ /* ... */};/* 设备模块信息 */static struct pci_driver demo_pci_driver = { name: demo_MODULE_NAME, /* 设备模块名称 */ id_table: demo_pci_tbl, /* 能够驱动的设备列表 */ probe: demo_probe, /* 查找并初始化设备 */ remove: demo_remove /* 卸载设备模块 */ /* ... */};static int __init demo_init_module (void){ /* ... */}static void __exit demo_cleanup_module (void){ pci_unregister_driver(&demo_pci_driver);}/* 加载驱动程序模块入口 */module_init(demo_init_module);/* 卸载驱动程序模块入口 */module_exit(demo_cleanup_module);
上面这段代码给出了一个典型的PCI设备驱动程序的框架,是一种相对固定的模式。需要注意的是,同加载和卸载模块相关的函数或数据结构都要在前面加上 __init、__exit等标志符,以使同普通函数区分开来。构造出这样一个框架之后,接下去的工作就是如何完成框架内的各个功能模块了。
3. 初始化设备模块
在Linux系统下,想要完成对一个PCI设备的初始化,需要完成以下工作:
检查PCI总线是否被Linux内核支持;
检查设备是否插在总线插槽上,如果在的话则保存它所占用的插槽的位置等信息。
读出配置头中的信息提供给驱动程序使用。
当Linux内核启动并完成对所有PCI设备进行扫描、登录和分配资源等初始化操作的同时,会建立起系统中所有PCI设备的拓扑结构,此后当PCI驱动程序需要对设备进行初始化时,一般都会调用如下的代码:
static int __init demo_init_module (void){ /* 检查系统是否支持PCI总线 */ if (!pci_present()) return -ENODEV; /* 注册硬件驱动程序 */ if (!pci_register_driver(&demo_pci_driver)) { pci_unregister_driver(&demo_pci_driver); return -ENODEV; } /* ... */ return 0;}
驱动程序首先调用函数pci_present( )检查PCI总线是否已经被Linux内核支持,如果系统支持PCI总线结构,这个函数的返回值为0,如果驱动程序在调用这个函数时得到了一个非0的返回 值,那么驱动程序就必须得中止自己的任务了。在2.4以前的内核中,需要手工调用pci_find_device( )函数来查找PCI设备,但在2.4以后更好的办法是调用pci_register_driver( )函数来注册PCI设备的驱动程序,此时需要提供一个pci_driver结构,在该结构中给出的probe探测例程将负责完成对硬件的检测工作。
static int __init demo_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id){ struct demo_card *card; /* 启动PCI设备 */ if (pci_enable_device(pci_dev)) return -EIO; /* 设备DMA标识 */ if (pci_set_dma_mask(pci_dev, DEMO_DMA_MASK)) { return -ENODEV; } /* 在内核空间中动态申请内存 */ if ((card = kmalloc(sizeof(struct demo_card), GFP_KERNEL)) == NULL) { printk(KERN_ERR "pci_demo: out of memory\n"); return -ENOMEM; } memset(card, 0, sizeof(*card)); /* 读取PCI配置信息 */ card->iobase = pci_resource_start (pci_dev, 1); card->pci_dev = pci_dev; card->pci_id = pci_id->device; card->irq = pci_dev->irq; card->next = devs; card->magic = DEMO_CARD_MAGIC; /* 设置成总线主DMA模式 */ pci_set_master(pci_dev); /* 申请I/O资源 */ request_region(card->iobase, 64, card_names[pci_id->driver_data]); return 0;}
4. 打开设备模块
在这个模块里主要实现申请中断、检查读写模式以及申请对设备的控制权等。在申请控制权的时候,非阻塞方式遇忙返回,否则进程主动接受调度,进入睡眠状态,等待其它进程释放对设备的控制权。
static int demo_open(struct inode *inode, struct file *file){ /* 申请中断,注册中断处理程序 */ request_irq(card->irq, &demo_interrupt, SA_SHIRQ, card_names[pci_id->driver_data], card)) { /* 检查读写模式 */ if(file->f_mode & FMODE_READ) { /* ... */ } if(file->f_mode & FMODE_WRITE) { /* ... */ } /* 申请对设备的控制权 */ down(&card->open_sem); while(card->open_mode & file->f_mode) { if (file->f_flags & O_NONBLOCK) { /* NONBLOCK模式,返回-EBUSY */ up(&card->open_sem); return -EBUSY; } else { /* 等待调度,获得控制权 */ card->open_mode |= f_mode & (FMODE_READ | FMODE_WRITE); up(&card->open_sem); /* 设备打开计数增1 */ MOD_INC_USE_COUNT; /* ... */ } }}
5. 数据读写和控制信息模块
PCI设备驱动程序可以通过demo_fops 结构中的函数demo_ioctl( ),向应用程序提供对硬件进行控制的接口。例如,通过它可以从I/O寄存器里读取一个数据,并传送到用户空间里:
static int demo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ /* ... */ switch(cmd) { case DEMO_RDATA: /* 从I/O端口读取4字节的数据 */ val = inl(card->iobae + 0x10); /* 将读取的数据传输到用户空间 */ return 0; } /* ... */}
事实上,在demo_fops里还可以实现诸如demo_read( )、demo_mmap( )等操作,Linux内核源码中的driver目录里提供了许多设备驱动程序的源代码,找那里可以找到类似的例子。在对资源的访问方式上,除了有I/O指 令以外,还有对外设I/O内存的访问。对这些内存的操作一方面可以通过把I/O内存重新映射后作为普通内存进行操作,另一方面也可以通过总线主DMA (Bus Master DMA)的方式让设备把数据通过DMA传送到系统内存中。
6. 中断处理模块
PC的中断资源比较有限,只有0~15的中断号,因此大部分外部设备都是以共享的形式申请中断号的。当中断发生的时候,中断处理程序首先负责对中断进行识别,然后再做进一步的处理。
static void demo_interrupt(int irq, void *dev_id, struct pt_regs *regs){ struct demo_card *card = (struct demo_card *)dev_id; u32 status; spin_lock(&card->lock); /* 识别中断 */ status = inl(card->iobase + GLOB_STA); if(!(status & INT_MASK)) { spin_unlock(&card->lock); return; /* not for us */ } /* 告诉设备已经收到中断 */ outl(status & INT_MASK, card->iobase + GLOB_STA); spin_unlock(&card->lock); /* 其它进一步的处理,如更新DMA缓冲区指针等 */}
7. 释放设备模块
释放设备模块主要负责释放对设备的控制权,释放占用的内存和中断等,所做的事情正好与打开设备模块相反:
static int demo_release(struct inode *inode, struct file *file){ /* ... */ /* 释放对设备的控制权 */ card->open_mode &= (FMODE_READ | FMODE_WRITE); /* 唤醒其它等待获取控制权的进程 */ wake_up(&card->open_wait); up(&card->open_sem); /* 释放中断 */ free_irq(card->irq, card); /* 设备打开计数增1 */ MOD_DEC_USE_COUNT; /* ... */ }
8. 卸载设备模块
卸载设备模块与初始化设备模块是相对应的,实现起来相对比较简单,主要是调用函数pci_unregister_driver( )从Linux内核中注销设备驱动程序:
static void __exit demo_cleanup_module (void){ pci_unregister_driver(&demo_pci_driver);}
四、小结
PCI总线不仅是目前应用广泛的计算机总线标准,而且是一种兼容性最强、功能最全的计算机总线。而Linux作为一种新的操作系统,其发展前景是无法估量 的,同时也为PCI总线与各种新型设备互连成为可能。由于Linux源码开放,因此给连接到PCI总线上的任何设备编写驱动程序变得相对容易。本文介绍如 何编译Linux下的PCI驱动程序,针对的内核版本是2.4。
参考资料: David A Rusling在 The Linux Kernel中对Linux的PCI子系统进行了比较详细的介绍。
Linux PCI-HOWTO是了解Linux下PCI设备的最好读物。
毛德操,胡希明,Linux内核源代码情景分析,杭州:浙江大学出版社,2001
Alessandro Rubini,,Linux Device Drivers(2nd Edition) USA:O’Reilly,2001
Tomshanley,DonAderson,PCI系统结构(第四版),北京:电子工业出版社,2000
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mingjie_520/archive/2009/03/27/4029919.aspx
posted @
2009-06-20 16:02 MEYE 阅读(610) |
评论 (0) |
编辑 收藏
换内核
由于开发环境需要,更换了一个比较新的内核,更换过程参考了附文,但文章稍显繁琐,我给大致总结一下,具体过程见原文。
2、下载内核升级工具:
(1)安装module-init-tools工具
# tar jvxf module-init-tools-3.2.tar.bz2 (解压module-init-tools)
# cd module-init-tools-3.2 (由/usr/src目录进入module-init-tools目录下)
#./configure --prefix=/
# make moveold
# make all install
#./generate-modprobe.conf /etc/modprobe.conf (该步能否运行未知,多次运行均未果)
(2)安装另外三个升级工具
# rpm -ivh --nodeps mkinitrd-4.1.18-2.i386.rpm (注意,这里一定要加入--nodeps参数,下同)
# rpm -ivh --nodeps lvm2-2.00.25-1.01.i386.rpm
# rpm -ivh --nodeps device-mapper-1.00.19-2.i386.rpm
4、配置编译内核
解压内核源码包到linux-2.6.x
# cd linux-2.6.x
# make mrproper (该命令可确保源代码目录下没有不正确的.o文件)
# make menuconfig (配置内核各选项,配置详情参考原文)
# make dep (建立编译时所需的从属文件。注意:如果内核从未编译过,此步可跳过)
# make clean (清除内核编译的目标文件。注意:如果内核从未编译过,此步可跳过)
# make bzImage (注意大小写。这一步才是真正编译内核)
# make modules (编译可加载模块) (此步骤约半到1小时,需耐心等待)
# make modules_install (安装可加载模块)
安装成功后,系统会在/lib/modules目录下生成一个2.6.18子目录,里面存放着新内核的所有可加载模块。
# make install (安装新内核)
5、启动新内核
此时我的系统中/root目录下已经有了新内核及启动项,启动配置文件(我的貌似是/root/grub/menu.lst)也已自动更改好,直接重启并在启动页面选择新内核OK。
若启动项未自动更改再次参考原文。
附原文:
序 言
由于开发环境需要在linux-2.6内核上进行,于是准备对我的虚拟机上的Linux系统升级。没想到这一弄就花了两天时间(反复装系统,辛苦啊~~),总算把Linux系统从2.4.20-8内核成功升级到了2.6.18内核。
网上虽然有很多介绍Linux内核升级的文章,不过要么过时,下载链接失效;要么表达不清,不知所云;更可气的是很多文章在转载过程中命令行都有错误。刚开始我就是在这些“攻略”的指点下来升级的,以致于浪费了很多时间。
现在,费尽周折,升级成功,心情很爽,趁性也来写个“升级攻略”吧!于是特意又在虚拟机上重新安装一个Linux系统,再来一次完美的升级,边升级边记录这些步骤,写成一篇Linux内核升级记实录(可不是回忆录啊!),和大家一起分享~~!
一、准备工作
首先说明,下面带#号的行都是要输入的命令行,且本文提到的所有命令行都在终端里输入。
启动Linux系统,并用根用户登录,进入终端模式下。
1、查看Linux内核版本
# uname -a
如果屏幕显示的是2.6.x,说明你的已经是2.6的内核,也用不着看下文了,该干什么干什么去吧!~~~如果显示的是2.4.x,那恭喜你,闯关通过,赶快进行下一步。
二、配置工作
好啦,2.6内核和4个升级工具都下载完了(少一个也不行,如果没有下载齐全,请不要尝试下面的步骤,升级是不会成功的),下面回到Linux系统中开始配置工作吧。
4、将下载好的内核源码包和4个升级工具都拷贝到/usr/src文件夹下。怎么拷贝就不用我教了吧~~~~不会拷贝的去撞墙吧!~~呵呵!
5、拷贝完毕,开始解压新内核,具体操作请依次执行以下命令:
# cd /usr/src (进入到/usr/src目录下,如果已经在/usr/src目录下,可不执行该命令)
# rm –rf linux (删除linux文件夹。值得一提的是,如果内核先前从未编译过,则没有这个文件夹,此命令行可略过)
# tar jvxf linux-2.6.18.tar.bz2 (解压新内核)
# ln -s linux-2.6.18 linux (重新生成linux文件夹)
6、安装module-init-tools工具
在/usr/src目录下,依次执行下列命令:
# tar jvxf module-init-tools-3.2.tar.bz2 (解压module-init-tools)
# cd module-init-tools-3.2 (由/usr/src目录进入module-init-tools目录下)
#./configure --prefix=/
# make moveold
# make all install
#./generate-modprobe.conf /etc/modprobe.conf
7、安装另外三个升级工具
回到/usr/src目录下,依次执行下列3个命令来安装另外三个升级工具:
# rpm -ivh --nodeps mkinitrd-4.1.18-2.i386.rpm (注意,这里一定要加入--nodeps参数,下同)
# rpm -ivh --nodeps lvm2-2.00.25-1.01.i386.rpm
# rpm -ivh --nodeps device-mapper-1.00.19-2.i386.rpm
如果不更新以上几个升级包,在后面编译内核时会提示以下错误:
mkinitrd failed
make[1]: *** [install] Error 1
make: *** [install] Error 2
8、配置内核选项。有点繁琐,~~希望一次成功哦~~。
# cd linux-2.6.18 (进入到/usr/src/linux-2.6.18目录下)
# make mrproper (该命令可确保源代码目录下没有不正确的.o文件)
# make menuconfig (配置内核各选项)
此时会出现一个图形界面,列出了所有的内核配置选项,有的选项下还有子选项,你可以用方向键来选择,用Y键来确定。经过我多次试验,大多数选项默认就行,以下几个选项必须选择(请认真核对下面每一个选项,否则编译很有可能前功尽弃):
(1)Loadable Module support选项中,选上“Module unloading”和“Automatic kernel module loading”这两项;
(2)Device Drivers--->Block Devices中选上“Loopback device support”;
Device Drivers--->Multi-device support(RAID and LVM)处要选上“device mapper support”;
Device Drivers--->Graphics support,一定要选上“ Support for buffer devices”;
Device Drivers --->USB support --->选上“USB Mass Storage support”(如果是在实环境中,想要更多USB支持,就全选吧。我的是在虚拟机中,用不着了)
Device Drivers --->;Network device support --->Ethernet (10 or 100Mbit) ---><*> AMD PCnet32 PCI support
(3)File system--->(以下9个选项是关于ext2和ext3文件系统配置,全部选上)
Second extended fs support
Ext2 extended attributes
Ext2 POSIX Access Control Lists
Ext2 Security Labels
Ext3 journalling file system support
Ext3 extended attributes
Ext3 POSIX Access Control Lists
Ext3 Security Labels
JBB (ext3) debugging support
File system--->DOS/FAT/NT Filesystems --->选上“NTFS file system support”;
注意:
ext2和ext3文件系统配置很重要,也是必需的,如果对Ext3、Ext2文件的支持直接编译进内核,在你reboot时机器就会当掉,出现如下错误信息:
kernel panic : no init found ,try passing init = option to kernel.....
或者是:
VFS:Cannot open root device "hdxy" or unknow-block(0,0)
Please append a correct "root=" boot option
kernel panic:VFS:Unable to mount root fs on unknown-block(0,0)
或者是:
mount: error 19 mounting ext3
pivotroot: pivot_root(/sysroot,/sysroot/initrd) failed: 2
umount /initrd/proc fail: 2
Freeing unused kernel memory: 244k freed
Kernel panic – not syncing: No init found. Try passing init = option to kernel
(我的机器就是在重启之后出现第三种错误,进不去系统,郁闷死,只好重装了~~~如果依照本文做完所有步骤,当你重启Linux系统后,若不幸进不去2.6.18内核,你会发现你的出错信息就是上面三种了~~~哈!)
(4)如果你在vmware下编译内核,硬盘用的是scsi的,以下三个选项必选:
Device Drivers ---><*>SCSI device support (此项不选的话,下面两项就选择不上)
Device Drivers ---><*>SCSI device support ---><*>SCSI disk support
Device Drivers---><8>SCSI device support--->SCSI low-level drivers---><*>; BusLogic SCSI support
三、编译工作
OK,繁杂的配置工作完成了,至此,编译前的准备工作都做好了!
9、开始编译啦……
在/usr/src/linux-2.6.18目录下,执行以下命令即可编译。编译需要一段时间,给自己倒杯茶耐心等候吧!
# make dep (建立编译时所需的从属文件。注意:如果内核从未编译过,此步可跳过)
# make clean (清除内核编译的目标文件。注意:如果内核从未编译过,此步可跳过)
# make bzImage (注意大小写。这一步才是真正编译内核)
内核编译成功后,会在/usr/src/linux/arch/i386/boot目录中生成一个新内核的映像文件bzImage。如果用 make zImage编译,内核很大的话,系统会提示你使用make bzImage命令来编译,所以我直接用make bzImage来编译。
# make modules (编译可加载模块)
# make modules_install (安装可加载模块)
安装成功后,系统会在/lib/modules目录下生成一个2.6.18子目录,里面存放着新内核的所有可加载模块。
# make install (安装新内核)
注意:
make install的时候可能会出现如下错误信息:
No module BusLogic found for kernel 2.4.12
mkinitrd failed
此问题一般只出现在SCSI硬盘+VMWARE+REDHAT架构中,因为BusLogic被编译进了内核而不是一个module的形式(2.4内核的Buslogic模块即使静态编译进内核也不行)。解决方式是直接将BusLogic.o文件复制过去:
# cp /usr/src/linux-2.6.18/drivers/scsi/BusLogic.o /lib/modules/2.6.18/kernel/drivers/scsi
不过别忘记,复制过后再执行一下make install。这一步若卡住了,下面的都无法进行,如果看本文档还是没有解决问题,就来我的网上留言本求助吧,进
http://www.piaoyang.org ,点“留言本”即可,我会及时看到你的求助信息的。
四、启动新内核
10、将新内核和System.map文件拷贝到/boot目录下,依次执行以下命令:
# cp /usr/src/linux-2.6.18/arch/i386/boot/bzImage /boot/vmlinuz-2.6.18
# cp /usr/src/linux-2.6.18/System.map /boot/System.map-2.6.18
# cd /boot (进入boot目录)
# rm –rf System.map (删除原来的连接)
# ln –s System.map-2.6.18 System.map (重新建立连接)
11、修改Grub启动管理器
如果没有错误的话, 下面开始修改grub配置文件(不要告诉我你用的lilo)
在/boot目录下,执行以下命令:
# new-kernel-pkg --mkinitrd --depmod --install 2.6.18 (这时候你的/boot下会生成一个initrd-2.4.18.img,并且你的grub.conf文件也作了相应更改)
# df (查看根目录在那个分区,下一步要用到。注意,这里根分区不时boot的那个50M的分区,而一般是你最大的那个分区,也就是“/”,千万不要搞错哦。我的为 /dev/hda2)
# vi /grub/grub.conf
进入grub.conf文件,找到如下信息:
default=1
timeout=10
splashimage=(hd0,0)/grub/splash.xpm.gz
title Red Hat Linux (2.6.18)
root (hd0,0)
kernel /vmlinuz-2.6.18 ro root= LABEL=/
initrd /initrd-2.6.18.img
做两处修改:
(1) 将default=1改为default=0(不改的话也可以,只不过重启之后会默认进入2.4内核)
(2) 将kernel行的“LABEL=/”换成根目录所在的分区(上一步查看的就是)
此步很重要,修改错误将可能导致进不去系统,我把我修改后的grub.conf文件列出来,不明之处,可以对照修改:
default=0
timeout=10
splashimage=(hd0,0)/grub/splash.xpm.gz
title Red Hat Linux (2.6.18)
root (hd0,0)
kernel /vmlinuz-2.6.18 ro root=/dev/hda2
initrd /initrd-2.6.18.img
title Red Hat Linux (2.4.20-8)
root (hd0,0)
kernel /vmlinuz-2.4.20-8 ro root=LABEL=/
initrd /initrd-2.4.20-8.img
12,OK,大功告成!赶快重启,看看升级后的2.6内核吧~~~~
后记:
Linux内核 升级和编译,老掉牙的话题了,网上相关的文章不计其数。然后,这么多的文章,却没有一篇让我顺利的升级成功。经过两天的体验,我深切的感受到,对于像我这样的新手来说,第一次升级和编译Linux内核,真是一项艰巨的任务。好在没有失去耐心,经过多篇文章的比对和自己的琢磨,一次次的修正,终于正确升级、编译成功。总结这两天的感受,那就是“痛,并快乐着”!如果你照着这些步骤一路下来的话,仍然没有成功;那么我可以告诉你两点:一是,不要怀疑我的步骤有问题,因为不光是我,我的同事照我的这篇文档也一次成功;二是,你可以到我的留言本
http://www.piaoyang.org/guestbook 给我留言,我会尽力解答你的问题。以此拙作,希望能给大家带去些微的帮助。
posted @
2009-06-11 21:32 MEYE 阅读(445) |
评论 (0) |
编辑 收藏
摘要: linux设备模型深探(1) 2009-06-05 15:37
分类:LinuxDriver
字号: 大大 中中 小小
转自:http://blog.chinaunix.net/u1/51562/showart_1077877.html
------------------------------------------
本文系本站原创,...
阅读全文
posted @
2009-06-11 21:31 MEYE 阅读(911) |
评论 (0) |
编辑 收藏
linux设备模型深探(2) 2009-06-05 15:40
这段代码中比较繁锁的就是bus_type对应目录下的属性文件建立,为了直观的说明,将属性文件的建立统一放到一起分析
从上面的代码中可以看,创建属性文件对应的属性分别为:
bus_attr_uevent bus_attr_drivers_probe, bus_attr_drivers_autoprobe
分别定义如下:
static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
static BUS_ATTR(drivers_probe, S_IWUSR, NULL, store_drivers_probe);
static BUS_ATTR(drivers_autoprobe, S_IWUSR | S_IRUGO,
show_drivers_autoprobe, store_drivers_autoprobe);
BUS_ATTR定义如下:
#define BUS_ATTR(_name, _mode, _show, _store) \
struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
#define __ATTR(_name,_mode,_show,_store) { \
.attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
}
由此可见.上面这三个属性对应的名称为别为uevent, drivers_probe, drivers_autoprobe.也就是说,会在bus_types目录下生成三个文件,分别为uevent,probe,autoprobe.
根据之前的分析,我们知道在sysfs文件系统中,对普通属性文件的读写都会回溯到kobject->ktype->sysfs_ops中.在这里,注意到有:
priv->subsys.kobj.kset = bus_kset;
priv->subsys.kobj.ktype = &bus_ktype;
显然,读写操作就回溯到了bus_ktype中.定义如下:
static struct kobj_type bus_ktype = {
.sysfs_ops = &bus_sysfs_ops,
};
static struct sysfs_ops bus_sysfs_ops = {
.show = bus_attr_show,
.store = bus_attr_store,
};
Show和store函数对应的代码为:
static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
struct bus_attribute *bus_attr = to_bus_attr(attr);
struct bus_type_private *bus_priv = to_bus(kobj);
ssize_t ret = 0;
if (bus_attr->show)
ret = bus_attr->show(bus_priv->bus, buf);
return ret;
}
static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr,
const char *buf, size_t count)
{
struct bus_attribute *bus_attr = to_bus_attr(attr);
struct bus_type_private *bus_priv = to_bus(kobj);
ssize_t ret = 0;
if (bus_attr->store)
ret = bus_attr->store(bus_priv->bus, buf, count);
return ret;
}
从代码可以看出.读写操作又会回溯到bus_attribute中的show和store中.在自定义结构里嵌入struct attribute,.然后再操作回溯到自定义结构中,这是一种比较高明的架构设计手法.
闲言少叙.我们对应看一下上面三个文件对应的最终操作:
Uevent对应的读写操作为:NULL, bus_uevent_store.对于这个文件没有读操作,只有写操作.用cat 命令去查看这个文件的时候,可能会返回”设备不存在”的错误.bus_uevent_store()代码如下:
static ssize_t bus_uevent_store(struct bus_type *bus,
const char *buf, size_t count)
{
enum kobject_action action;
if (kobject_action_type(buf, count, &action) == 0)
kobject_uevent(&bus->p->subsys.kobj, action);
return count;
}
从这里可以看到,可以在用户空间控制事件的发生,如echo add > event就会产生一个add的事件,
Probe文件对应的读写操作为:NULL store_drivers_probe.
store_drivers_probe()这个函数的代码涉及到struct device.等分析完struct device可以自行回过来看下这个函数的实现.实际上,这个函数是将用户输和的设备名称对应的设备与驱动匹配一次.
Autoprobe文件对应的读写操作为show_drivers_autoprobe, store_drivers_autoprobe.对应读的代码为:
static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)
{
return sprintf(buf, "%d\n", bus->p->drivers_autoprobe);
}
它将总线对应的drivers_autoprobe的值输出到用户空间,这个值为1时,自动将驱动与设备进行匹配.否则,反之.
写操作的代码如下:
static ssize_t store_drivers_autoprobe(struct bus_type *bus,
const char *buf, size_t count)
{
if (buf[0] == '0')
bus->p->drivers_autoprobe = 0;
else
bus->p->drivers_autoprobe = 1;
return count;
}
写操作就会改变bus->p->drivers_autoprobe的值.
就这样,通过sysfs就可以控制总线是否要进行自动匹配了.
从这里也可以看出.内核开发者的思维是何等的灵活.
我们从sysfs中找个例子来印证一下:
Cd / sys/bus/usb
用ls命令查看:
devices drivers drivers_autoprobe drivers_probe uevent
与上面分析的相吻合
设备的注册接口为: device_register().
int device_register(struct device *dev)
{
device_initialize(dev);
return device_add(dev);
}
Device_initialize()中有几个很重要的操作,如下:
void device_initialize(struct device *dev)
{
dev->kobj.kset = devices_kset;
kobject_init(&dev->kobj, &device_ktype);
klist_init(&dev->klist_children, klist_children_get,
klist_children_put);
INIT_LIST_HEAD(&dev->dma_pools);
INIT_LIST_HEAD(&dev->node);
init_MUTEX(&dev->sem);
spin_lock_init(&dev->devres_lock);
INIT_LIST_HEAD(&dev->devres_head);
device_init_wakeup(dev, 0);
set_dev_node(dev, -1);
}
在这里,它为device的内嵌kobject指定了ktype和kset.device_kset的值如下:
devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
即对应sysfs中的/sys/devices
device_ktype 中对属性的读写操作同bus中的类似,被回溯到了struct device_attribute中的show 和store.
接着往下看device_add()的实现.这个函数比较长,分段分析如下:
int device_add(struct device *dev)
{
struct device *parent = NULL;
struct class_interface *class_intf;
int error;
dev = get_device(dev);
if (!dev || !strlen(dev->bus_id)) {
error = -EINVAL;
goto Done;
}
pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__);
parent = get_device(dev->parent);
setup_parent(dev, parent);
/* first, register with generic layer. */
error = kobject_add(&dev->kobj, dev->kobj.parent, "%s", dev->bus_id);
if (error)
goto Error;
如果注册device的时候,没有指定父结点,在kobject_add将会在/sys/device/下建立相同名称的目录
/* notify platform of device entry */
if (platform_notify)
platform_notify(dev);
/* notify clients of device entry (new way) */
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_ADD_DEVICE, dev);
忽略notify部份,这部份不会影响本函数的流程
error = device_create_file(dev, &uevent_attr);
if (error)
goto attrError;
if (MAJOR(dev->devt)) {
error = device_create_file(dev, &devt_attr);
if (error)
goto ueventattrError;
}
建立属性为uevent_attr的属性文件,如果device中指定了设备号,则建立属性为devt_attr的属性文件
error = device_add_class_symlinks(dev);
if (error)
goto SymlinkError;
error = device_add_attrs(dev);
if (error)
goto AttrsError;
error = dpm_sysfs_add(dev);
if (error)
goto PMError;
device_pm_add(dev);
在这里,不打算讨论class的部份,dpm pm是选择编译部份,不讨论. device_add_attrs中涉及到了group的部分,暂不讨论
error = bus_add_device(dev);
if (error)
goto BusError;
kobject_uevent(&dev->kobj, KOBJ_ADD);
bus_attach_device(dev);
if (parent)
klist_add_tail(&dev->knode_parent, &parent->klist_children);
if (dev->class) {
down(&dev->class->sem);
/* tie the class to the device */
list_add_tail(&dev->node, &dev->class->devices);
/* notify any interfaces that the device is here */
list_for_each_entry(class_intf, &dev->class->interfaces, node)
if (class_intf->add_dev)
class_intf->add_dev(dev, class_intf);
up(&dev->class->sem);
}
bus_add_device()会在对应总线代表目录的device目录下创建几个到device的链接.然后产生一个add事件,再调用bus_attach_device()去匹配已经注册到总线的驱动程序.全部做完之后,将设备挂到父结点的子链表.
Done:
put_device(dev);
return error;
BusError:
device_pm_remove(dev);
PMError:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_DEL_DEVICE, dev);
device_remove_attrs(dev);
AttrsError:
device_remove_class_symlinks(dev);
SymlinkError:
if (MAJOR(dev->devt))
device_remove_file(dev, &devt_attr);
ueventattrError:
device_remove_file(dev, &uevent_attr);
attrError:
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
Error:
cleanup_device_parent(dev);
if (parent)
put_device(parent);
goto Done;
}
出错处理部份.
bus_attach_device()是一个很重要的函数。它将设备自动与挂在总线上面的驱动进行匹配。代码如下:
void bus_attach_device(struct device *dev)
{
struct bus_type *bus = dev->bus;
int ret = 0;
if (bus) {
dev->is_registered = 1;
if (bus->p->drivers_autoprobe)
ret = device_attach(dev);
WARN_ON(ret < 0);
if (ret >= 0)
klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
else
dev->is_registered = 0;
}
}
从上面的代码我们可以看出。只有在bus->p->drivers_autoprobe为1的情况下,才会去自己匹配。这也就是bus目录下的drivers_probe 文件的作用.然后,将设备挂到总线的设备链表。
Device_attach()代码如下:
int device_attach(struct device *dev)
{
int ret = 0;
down(&dev->sem);
if (dev->driver) {
ret = device_bind_driver(dev);
if (ret == 0)
ret = 1;
else {
dev->driver = NULL;
ret = 0;
}
} else {
ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
}
up(&dev->sem);
return ret;
}
对于设备自己已经指定驱动的情况,只需要将其直接和驱动绑定即可。如果没有指定驱动。就匹配总线之上的驱动。这是在bus_for_each_drv(dev->bus, NULL, dev, __device_attach);完成的。代码如下:
int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
void *data, int (*fn)(struct device_driver *, void *))
{
struct klist_iter i;
struct device_driver *drv;
int error = 0;
if (!bus)
return -EINVAL;
klist_iter_init_node(&bus->p->klist_drivers, &i,
start ? &start->p->knode_bus : NULL);
while ((drv = next_driver(&i)) && !error)
error = fn(drv, data);
klist_iter_exit(&i);
return error;
}
很明显,这个函数就是遍历总线之上的驱动。每遍历一个驱动就调用一次回调函数进行判断。如果回调函数返回不为0。就说明匹配已经成功了。不需要再匹配剩余的。退出。在这里调用的回调函数是__device_attach().在这里。完全了设备与驱动匹配的最核心的动作。代码如下:
static int __device_attach(struct device_driver *drv, void *data)
{
struct device *dev = data;
return driver_probe_device(drv, dev);
}
转到driver_probe_device():
int driver_probe_device(struct device_driver *drv, struct device *dev)
{
int ret = 0;
if (!device_is_registered(dev))
return -ENODEV;
if (drv->bus->match && !drv->bus->match(dev, drv))
goto done;
pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
drv->bus->name, __FUNCTION__, dev->bus_id, drv->name);
ret = really_probe(dev, drv);
done:
return ret;
}
如果设备没有注册到总线之上。即dev->is_registered不为1. 就直接返回。
然后,再调用总线的match()函数进行匹配。如果match()函数返回0.说明匹配失败。那退出此函数。如果match函数返回1.说明初步的检查已经通过了。可以进入really_probe()再进行细致的检查。如果匹配成功,这个函数会返回1.此函数比较长而且比较重要,分段列出代码:
static int really_probe(struct device *dev, struct device_driver *drv)
{
int ret = 0;
atomic_inc(&probe_count);
pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
drv->bus->name, __FUNCTION__, drv->name, dev->bus_id);
WARN_ON(!list_empty(&dev->devres_head));
dev->driver = drv;
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__FUNCTION__, dev->bus_id);
goto probe_failed;
}
先假设驱动和设备是匹配的。为设备结构设置驱动成员。使其指向匹配的驱动。然后再调用driver_sysfs_add()建立几个符号链接。这几个链接分别为:
1:在驱动目录下建立一个到设备的同名链接
2:在设备目录下建立一个名为driver。到驱动的链接
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
ret = drv->probe(dev);
if (ret)
goto probe_failed;
}
然后,再调用总线的probe函数。如果总线的此函数不存在。就会调用驱动的probe函数。如果匹配成功,返回0.如果不成功,就会跳转到probe_failed
driver_bound(dev);
ret = 1;
pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
drv->bus->name, __FUNCTION__, dev->bus_id, drv->name);
goto done;
到这里。设备和驱动已经匹配成功,调用driver_bound()将其关联起来。在这个函数里:
会将设备加至驱动的设备链表。这在我们之前分析bus,device driver中分析到的。相关的代码如下示:
klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices);
至此,这个匹配过程已经圆满结束了。返回1
probe_failed:
devres_release_all(dev);
driver_sysfs_remove(dev);
dev->driver = NULL;
if (ret != -ENODEV && ret != -ENXIO) {
/* driver matched but the probe failed */
printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
drv->name, dev->bus_id, ret);
}
/*
* Ignore errors returned by ->probe so that the next driver can try
* its luck.
*/
ret = 0;
这里是匹配不成功的处理,在这里,删除之前建立的几个链接文件,然后将设备的driver域置空。
done:
atomic_dec(&probe_count);
wake_up(&probe_waitqueue);
return ret;
}
从上面的分析可以看到,对应创建的属性文件分别为:uevent_attr devt_attr。它们的定义如下:
static struct device_attribute uevent_attr =
__ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
static struct device_attribute devt_attr =
__ATTR(dev, S_IRUGO, show_dev, NULL);
uevent_attr对应的读写函数分别为:show_uevent store_uevent。先分析读操作。它的代码如下:
static ssize_t show_uevent(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct kobject *top_kobj;
struct kset *kset;
struct kobj_uevent_env *env = NULL;
int i;
size_t count = 0;
int retval;
/* search the kset, the device belongs to */
top_kobj = &dev->kobj;
while (!top_kobj->kset && top_kobj->parent)
top_kobj = top_kobj->parent;
if (!top_kobj->kset)
goto out;
kset = top_kobj->kset;
if (!kset->uevent_ops || !kset->uevent_ops->uevent)
goto out;
/* respect filter */
if (kset->uevent_ops && kset->uevent_ops->filter)
if (!kset->uevent_ops->filter(kset, &dev->kobj))
goto out;
env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
if (!env)
return -ENOMEM;
/* let the kset specific function add its keys */
retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
if (retval)
goto out;
/* copy keys to file */
for (i = 0; i < env->envp_idx; i++)
count += sprintf(&buf[count], "%s\n", env->envp[i]);
out:
kfree(env);
return count;
}
从代码可以看出。这里会显示出由设备对应的kset.也就是由devices_kset所产生的环境变量。例如,在shell中输入如下指令:
Cat /sys/devices/LNXSYSTM:00/ uevent
输出结果如下:
PHYSDEVBUS=acpi
MODALIAS=acpi:LNXSYSTM:
这就是由devices_kset所添加的环境变量
写操作对应的代码如下:
static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
enum kobject_action action;
if (kobject_action_type(buf, count, &action) == 0) {
kobject_uevent(&dev->kobj, action);
goto out;
}
dev_err(dev, "uevent: unsupported action-string; this will "
"be ignored in a future kernel version\n");
kobject_uevent(&dev->kobj, KOBJ_ADD);
out:
return count;
}
从上面的代码可以看出。这个文件的作用是输入一个字符字串。如果字符不合法,就会默认产生一个add事件。
devt_attr对应的读写函数为show_dev NULL.写函数为空,也就是说这个属性文件不允许写。只允许读。读操作的代码如下示:
static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
char *buf)
{
return print_dev_t(buf, dev->devt);
}
也就是说,会将设备号显示出来.
分析完了bus.device.再接着分析driver.这里我们要分析的最后一个元素了。耐着性子往下看,快要完了^_^
驱动注册的接口为:driver_register().代码如下:
int driver_register(struct device_driver *drv)
{
int ret;
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown))
printk(KERN_WARNING "Driver '%s' needs updating - please use "
"bus_type methods\n", drv->name);
ret = bus_add_driver(drv);
if (ret)
return ret;
ret = driver_add_groups(drv, drv->groups);
if (ret)
bus_remove_driver(drv);
return ret;
}
如果设备与总线定义了相同的成员的函数。内核是优先使用bus中定义的.这一点我们在分析device注册的时候已经分析过。所以。这里打印出警告信息,用来提醒代码编写者。在这里,忽略有关group的东西。剩余的便只剩下bus_add_driver().代码如下:
int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
int error = 0;
bus = bus_get(drv->bus);
if (!bus)
return -EINVAL;
pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
error = -ENOMEM;
goto out_put_bus;
}
klist_init(&priv->klist_devices, NULL, NULL);
priv->driver = drv;
drv->p = priv;
priv->kobj.kset = bus->p->drivers_kset;
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
"%s", drv->name);
初始化驱动的driver_private域。使其内嵌的kobject的kset指bus中的drivers_kset.这样,这个内嵌的kobject所生成的目录就会存在于bus对应目录的driver目录之下。这里还要注意的是,为内嵌kobject指定的ktype是driver_ktype.属性文件的读写操作都回回溯到struct driver_attribute中。这在之后再分析.
if (error)
goto out_unregister;
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
}
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
b
module_add_driver(drv->owner, drv);
如果总线允许自动进行匹配。就会调用driver_attach()进行这个自己匹配过程。这个函数跟我们在上面分析的device自动匹配过程是一样的。请自行分析.最后,将驱动挂到bus对应的驱动链表
error = driver_create_file(drv, &driver_attr_uevent);
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__FUNCTION__, drv->name);
}
生成一个属性为driver_attr_uevent的属性文件
error = driver_add_attrs(bus, drv);
if (error) {
/* How the hell do we get out of this pickle? Give up */
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
__FUNCTION__, drv->name);
}
为bus中的driver属性生成属性文件
error = add_bind_files(drv);
if (error) {
/* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__FUNCTION__, drv->name);
}
生成属性为driver_attr_unbind和driver_attr_bind的属性文件
kobject_uevent(&priv->kobj, KOBJ_ADD);
生成一个add事件
return error;
out_unregister:
kobject_put(&priv->kobj);
out_put_bus:
bus_put(bus);
return error;
}
总的来说,这个函数比较简单。其中涉及到的子函数大部份都在之前分析过。我们接下来分析一下。它所创建的几个属性文件的含义。
如上所述。在这里会创建三个属性文件,对应属性分别为:driver_attr_uevent,driver_attr_unbind,driver_attr_bind。这几个属性的定义如下:
static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store);
static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
DRIVER_ATTR宏的定义如下:
#define DRIVER_ATTR(_name, _mode, _show, _store) \
struct driver_attribute driver_attr_##_name = \
__ATTR(_name, _mode, _show, _store)
对于driver_attr_uevent.它的读写函数分别为:NULL。driver_uevent_store。也就是说这个文件只允许写,不允许读操作。写操作的代码如下示:
static ssize_t driver_uevent_store(struct device_driver *drv,
const char *buf, size_t count)
{
enum kobject_action action;
if (kobject_action_type(buf, count, &action) == 0)
kobject_uevent(&drv->p->kobj, action);
return count;
}
很明显,这是一个手动产生事件的过程。用户可间可以写事件到这个文件来产生事件。
对于driver_unbind.它的读写函数分别为:NULL driver_unbind。这个文件也是不允许读的。写操作代码如下:
static ssize_t driver_unbind(struct device_driver *drv,
const char *buf, size_t count)
{
struct bus_type *bus = bus_get(drv->bus);
struct device *dev;
int err = -ENODEV;
dev = bus_find_device_by_name(bus, NULL, buf);
if (dev && dev->driver == drv) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
device_release_driver(dev);
if (dev->parent)
up(&dev->parent->sem);
err = count;
}
put_device(dev);
bus_put(bus);
return err;
}
从上面的代码可以看出。写入文件的是一个设备名称。这个函数对应操作是将这个设备与驱动的绑定分离开来。
driver_attr_bind属性对应的读写函数分别为NULL。driver_attr_bind 即也是不允许写的。从字面意思和上面分析的driver_attr_unbind操作代码来看,这个属性对应的写函数应该是将写入的设备文件与此驱动绑定起来。我们来看下代码。以证实我们的猜测。代码如下:
static ssize_t driver_bind(struct device_driver *drv,
const char *buf, size_t count)
{
struct bus_type *bus = bus_get(drv->bus);
struct device *dev;
int err = -ENODEV;
dev = bus_find_device_by_name(bus, NULL, buf);
if (dev && dev->driver == NULL) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
err = driver_probe_device(drv, dev);
up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
if (err > 0) {
/* success */
err = count;
} else if (err == 0) {
/* driver didn't accept device */
err = -ENODEV;
}
}
put_device(dev);
bus_put(bus);
return err;
}
果然,和我们猜测的是一样的。
五:小结
在这一节里,分析了设备模型中的最底层的元素和他们之间的关系。也分析了它们建立的几个属性文件的含义。到这里,我们已经可以自己写驱动架构代码了.^_^
posted @
2009-06-11 21:31 MEYE 阅读(613) |
评论 (0) |
编辑 收藏
linux下的GPIO驱动 2009-06-05 08:29
编写驱动程序,首先要了解是什么类型的设备。linux下的设备分为三类,分别为:字符设备,块设备和网络设备。字符设备类型是根据是否以字符流为数据的交换方式,大部分设备都是字符设备,如键盘,串口等,块设备则是以块为单位进行管理的设备,如,磁盘。网络设备就是网卡等。
其次要了解应用程序和驱动程序的区别,两者的主要区别分为以下三点:
1入口函数的任务不相同,应用程序完成一个任务,驱动只完成初始化工作,比如中断
申请,寄存器设置,定时器设置。
2运行时的cpu模式不相同,驱动具有很高的权限,应用程序是在用户态下运行,而驱
动程序是在内核态下执行。
3 驱动程序不能调用C库函数,内核为驱动程序提供一些函数。如printk(KERN_NOTICE fmt, ##arg),第一个参数为打印级别,有如下的打印级别:
KERN_EMERG 用于紧急事件,一般是系统崩溃前的提示信息
KERN_ALERT 用于需要立即采取动作的场合
KERN_CRIT 临界状态,通常设计验证的硬件或软件操作失败
KERN_ERR 用于报告错误状态.设备驱动程序通常会用它报告来自硬件的问题
KERN_WARNING 就可能出现的问题提出警告.这些问题通常不会对系统造成严重破坏
KERN_NOTICE 有必要提示的正常情况.许多安全相关的情况用这个级别汇报
KERN_INFO 提示性信息.有很多驱动程序在启动时用这个级别打印相关信息
KERN_DEBUG 用于调试的信息
u_long copy_from_user(void *to, const void *from, u_long len),由用户态拷贝到内核态;
u_long copy_to_user(void * to, const void *from, u_long len),由内核态拷贝到用户态。
鉴于以上区别,驱动程序需要完成以下三点基本功能:
1:要对设备进行初始化和释放功能模块,就如上面的寄存器设置,中断的申请,向内核注
册驱动程序(register_chrdev()),卸载驱动程序(unregister_chrdev())。
2:能进行数据传输,在read(),write()函数里具体实现,数据传输工作。
3:能进行控制操作,给用户提供的ioctl()函数里可实现一些用户的选择性设置功能。
确定一个设备的执行函数集(结构体)
static struct file_operations myGPIO_fops = {
owner: THIS_MODULE,
write: myGPIO_write,
read: myGPIO_read,
ioctl: myGPIO_ioctl,
open: myGPIO_open,
release: myGPIO_release,
};
接下来是初始化工作,需要写在一个init()函数中,这个函数是独立的也是自动执行的,在这之中主要是对一些寄存器进行初始化操作。同样需要完成卸载驱动模块。
myGPIO_Major = register_chrdev(0, DRIVER_NAME, &myDriver_fops);
上面的程序完成设备号的注册,第一个参数为主设备号,一般为0,由系统来分配。
第二个参数为设备名,这需要在/dev/(/dev目录下设备名由命令 <mknod 设备名 C 主设备号 从设备号>来生成)目录下出现的设备名相符合。相反的在卸载中就取消注册
unregister_chrdev(myGPIO_Major, DRIVER_NAME);
最后将这两个模块加入到内核中,由程序段的最后两行完成。
static int __init myGPIO_init(void)
{
PRINTK("GPIO init\n");
myGPIO_Major = register_chrdev(0, DRIVER_NAME, &myGPIO_fops);
if(myGPIO_Major < 0)
{
PRINTK("register char device fail!\n");
return myGPIO_Major;
}
PRINTK("register myGPIO OK! Major = %d\n", myGPIO_Major);
#ifdef CONFIG_DEVFS_FS
devfs_myDriver_dir = devfs_mk_dir(NULL, "GPIO", NULL);
devfs_myDriver_raw = devfs_register(devfs_myDriver_dir, "raw0", DEVFS_FL_DEFAULT, myGPIO_Major, 0, S_IFCHR | S_IRUSR | S_IWUSR, &myGPIO_fops, NULL);
PRINTK("add dev file to devfs OK!\n");
#endif
return 0;
}
static void __exit myGPIO_exit(void)
{
/* Module exit code */
PRINTK("GPIO exit\n");
/* Driver unregister */
if(myGPIO_Major > 0)
{
#ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_myDriver_raw);
devfs_unregister(devfs_myDriver_dir);
#endif
unregister_chrdev(myGPIO_Major, DRIVER_NAME);
}
return;
}
MODULE_AUTHOR("LiuFan");
MODULE_LICENSE("Dual BSD/GPL");
module_init(myGPIO_init);
module_exit(myGPIO_exit);
设备执行函数功能的实现将在下面完成。如结构体的函数,但并不是全都需要实现。open()函数中是执行一些设备工作前的初始化工作。rlease()则是将设备的相关寄存器恢复到原来的值。read()函数是将设备中的数据拷贝到内核,write()函数是将内核数据拷贝到对应的设备中。MOD_INC_USE_COUNT和MOD_DEC_USE_COUNT两个宏是提供给系统对硬件资源进行控制访问的。在open()和rlease()两个函数中最基本的操作应是实现以上两个宏的操作。
static unsigned char myGPIO_Buffer[1024*1024];
/* Driver Operation Functions */
static int myGPIO_open(struct inode *inode, struct file *filp)
{
// int Minor = MINOR(inode->i_rdev);
// filp->private_data = 0;
MOD_INC_USE_COUNT;
PRINTK("myDriver open called!\n");
return 0;
}
static int myGPIO_release(struct inode *inode, struct file *filp)
{
// int Minor = MINOR(inode->i_rdev);
MOD_DEC_USE_COUNT;
PRINTK("myDriver release called!\n");
return 0;
}
static ssize_t myGPIO_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
char dat;
size_t read_size = count;
PRINTK("GPIO read called!\n");
PRINTK("\tcount=%d, pos=%d\n", count, (int)*f_pos);
/* if(*f_pos >= sizeof(myGPIO_Buffer))
{
PRINTK("[GPIO read]Buffer Overlap\n");
*f_pos = sizeof(myGPIO_Buffer);
return 0;
}
if((count + *f_pos) > sizeof(myGPIO_Buffer))
{
PRINTK("count + f_pos > sizeof buffer\n");
read_size = sizeof(myGPIO_Buffer) - *f_pos;
}*/
dat= GPFDAT;
copy_to_user(buf,&dat,1);
// *f_pos += read_size;
return read_size;
}
static ssize_t myGPIO_write(struct file *filp,const char *buf, size_t count, loff_t *f_pos)
{
char dat;
size_t fill_size = count;
PRINTK("myDriver write called!\n");
PRINTK("\tcount=%d, pos=%d\n", count, (int)*f_pos);
if(*f_pos >= sizeof(myGPIO_Buffer))
{
PRINTK("[myDriver write]Buffer Overlap\n");
*f_pos = sizeof(myGPIO_Buffer);
return 0;
}
if((count + *f_pos) > sizeof(myGPIO_Buffer))
{
PRINTK("count + f_pos > sizeof buffer\n");
fill_size = sizeof(myGPIO_Buffer) - *f_pos;
}
copy_from_user(&dat,buf,fill_size);
GPFDAT = dat;
// *f_pos += fill_size;
return fill_size;
}
控制ioctl() 函数则是提供给应用层的接口函数,功能并不是固定的,由开发者定义,一般都是对硬件的一些除过上述功能的其他操作。
static int myGPIO_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
int i;
unsigned int mask=0x01;
GPFUP = 0x00;
PRINTK("myGPIO ioctl called(%d)!\n", cmd);
switch(cmd)
{
case MOD_IN:
for(i=0;i<8;i++)
{
if((mask & arg)!=0x0)
{
GPFCON &=~(3<<i*2);
}
mask =mask << 1;
}
break;
case MOD_OUT:
PRINTK("IOCTRL 0 called(0x%lx)!\n", arg);
for(i=0;i<8;i++)
{
if((mask & arg)!=0x00)
{
GPFCON &= ~(3 <<( i*2));
GPFCON |=(0x01<<(i*2));
}
mask=mask<<1;
}
break;
case MOD_EXIT_INT:
PRINTK("IOCTRL 1 called(0x%lx)!\n", arg);
GPFDAT = 0xFFFFFF00;
break;
default:
break;
}
return 0;
}
posted @
2009-06-11 21:30 MEYE 阅读(2611) |
评论 (0) |
编辑 收藏
2009-05-25 | 嵌入式Linux下USB驱动程序的设计
一、引言
USB(Universal Serial Bus)即通用串行总线,是一种全新的双向同步传输的支持热插拔的数据传输总线,其目的是为了提供一种兼容不同速度的、可扩充的并且使用方便的外围设备接口,同时也是为了解决计算机接口的太多的弊端而设计的。一个USB系统主要有三部分组成:USB互连、USB主机、USB设备三部分组成的,其结构如图1 所示。在编写USB设备驱动程序设计时,可以分为三部分编写:主机端设备驱动程序、主机控制器驱动程序设计和设备端驱动程序三部分,在本文中重点介绍主机端驱动程序的设计。
二、USB设备驱动程序的设计
USB设备驱动程序的设计包括主机端设备驱动程序设计、主机控制器驱动程序设计和设备端驱动程序设计三部分组成。主机端设备驱动程序就是通常说的设备驱动程序,它是主机环境中为用户应用程序提供一个访问USB外设的接口。Linux为这部分驱动程序提供编程接口,驱动程序设计者只要按照需求编写驱动程序框架,通过调用操作系统提供的API接口函数可以完成对USB外设的特定访问。
主机控制驱动主要是对USB主机控制器的驱动,在大多数PC环境下,主机控制器都是由操作系统提供。嵌入式设备一般都没有USB主机控制器,只是工作在 Slave模式下。如果要使USB具有主机功能,那么设备中需要选用一个带主机控制器的USB接口控制芯片,同时自己还要有实现该主机控制器的驱动程序。目前Linux内核中只提供USB主机控制器的开放主机控制器和通用主机控制器接口两种规格,而这两种规格主要用在PC架构中。USB主机端驱动程序与主机控制器的结构如图2所示。其中USB核是Linux的一个子模块,集中定义了一组USB相关的数据结构、宏以及API函数。
USB设备驱动程序是常说的设备固件程序的一部分,提供设备信息与主机的通信接口。设备端USB驱动程序设计由以下几部分处理程序组成。初始化例程:完成描述符指针、端点、配置改变等操作。数据传输例程:完成控制传输、批量传输、中断传输及同步传输等传输方式下的数据收发工作。标准设备处理请求:处理标准设备请求。厂商请求处理:处理生产商指定请求。其他操作:处理主机发出的端口复位、配置改变等操作。
1.USB设备驱动程序框架
USB驱动程序首先要向Linux内核注册自己,并告诉系统它所支持的设备类型以及它所支持的操作。这些信息通过一个usb_driver结构来传递。usb_driver结构如下:
static struct usb_driver skel_driver = {
name: "skeleton";/*驱动程序的名称*/
probe: skel_probe; /*设备列举时被调用*/
disconnect: skel_disconnect; /*设备被卸载时被调用*/
fops: &skel_fops; /*指向一个file_operation结构,内核通过它来访问驱动程序的文件操作函数,与用户程序的read、write等操作进行交互*/
minor USB_SKEL_MINOR_BASE; /*指向设备的次设备号,用于系统识别主设备号相同的设备(即一个驱动程序可以同时支持多个USB设备*/
id_table: skel_table; /*保存设备的厂商ID和产品ID,作为该设备的唯一标识,驱动程序向系统注册后,当下次插入时,系统根据这个标识查找正确的驱动程序,实现设备的即插即用*/
};
static struct file_operation skel_fops={
{
owner:THIS_MODULE,
read:skel_read,
write:skel_write,
ioctl:skel_ioctl,
open:skel_open,
release:skel_release,
};
(1)注册和注销
USB驱动程序注册,就是把在初始化函数中填好的use_driver结构作为参数传递给
use_register()函数即可,函数的调用方法为:
result=usb_register(&skel_driver);
当要从系统卸载驱动程序时,也是将use_driver结构作为参数传递给usb_deregister 函数处理。 函数的调用格式为:
static void __exit usb_skel_exit(void)
{ /* deregister this driver with the USB subsystem */
usb_deregister(&skel_driver);
}
module_exit(usb_skel_exit);
当USB设备插入时,为了使linux-hotplug(Linux中PCI、USB等设备热插拔支持)系统自动装载驱动程序,需要创建一个MODULE_DEVICE_TABLE。核心代码如下(这个模块仅支持某一特定设备):
/* table of devices that work with this driver */
static struct usb_device_id skel_table [] = {
{ USB_DEVICE(USB_SKEL_VENDOR_ID,
USB_SKEL_PRODUCT_ID) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, skel_table);
USB_DEVICE宏利用厂商ID和产品ID提供了一个设备的唯一标识。当系统插入一个ID匹配的USB设备到USB总线时,驱动会在USB core中注册,驱动程序中probe 函数也就会被调用。usb_device 结构指针、接口号和接口ID都会被传递到函数中。
(2)probe()函数
probe()函数的编写格式为:static void * skel_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id);驱动程序需要确认插入的设备是否可以被接受,如果不接受,或者在初始化的过程中发生任何错误,probe()函数返回一个NULL值。否则返回一个含有设备驱动程序状态的指针,通过这个指针,就可以访问所有结构中的回调函数。
在驱动程序里,最后一点是要注册devfs(设备文件系统)。首先创建一个缓冲用来保存那些被发送给USB设备的数据和那些从设备上接受的数据,并为设备传输创建一个USB请求块(URB)以向设备写入数据,同时USB urb 被初始化,然后在devfs子系统中注册设备,允许devfs用户访问USB的设备。注册过程如下:
/* initialize the devfs node for this device and register it */
sprintf(name, "skel%d", skel->minor);
skel->devfs = devfs_register (usb_devfs_handle, name, DEVFS_FL_DEFAULT, USB_MAJOR, USB_SKEL_MINOR_BASE + skel->minor, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, &skel_fops, NULL);
如果devfs_register函数失败, devfs子系统会将此情况报告给用户。如果设备从USB总线拔掉,设备指针会调用disconnect 函数。驱动程序就需要清除那些被分配了的所有私有数据、关闭urbs,并且从devfs上注销调自己。调用函数的格式为:
/* remove our devfs node */
devfs_unregister(skel->devfs);
现在,skeleton驱动就已经和设备绑定上了,任何用户态程序要操作此设备都可以通过file_operations结构所定义的函数进行了。
(3)open()、write()和read()函数
首先,要打开此设备。在open()函数中MODULE_INC_USE_COUNT 宏是一个关键,它起到一个计数的作用,有一个用户态程序打开一个设备,计数器就加1。例如,以模块方式加入一个驱动,若计数器不为零,就说明仍然有用户程序在使用此驱动,这时候,就不能通过rmmod命令卸载驱动模块了。
/* increment our usage count for the module */
MOD_INC_USE_COUNT;
++skel->open_count;
/* save our object in the file's private structure */
file->private_data = skel;
当open完设备后,read()、write()函数就可以收、发数据了。
read()函数首先从open()函数中保存的fi。
Write()函数和read()函数是完成驱动对读写等操作的响应。在skel_write中,一个FILL_BULK_URB函数,就完成了urb 系统callbak和的skel_write_bulk_callback之间的联系。注意skel_write_bulkcallback是中断方式,所以要注意时间不能太久,本程序中它就只是报告一些urb的状态等。 read 函数与write 函数稍有不同在于:程序并没有用urb 将数据从设备传送到驱动程序,而是用usb_bulk_msg 函数代替,这个函数能够不需要创建urbs 和操作urb函数的情况下,来发送数据给设备,或者从设备来接收数据。调用usb_bulk_msg函数并传到一个存储空间,用来缓冲和放置驱动收到的数据,若没有收到数据表示失败并返回一个错误信息。
usb_bulk_msg函数:当对usb设备进行一次读或者写时,usb_bulk_msg 函数是非常有用的; 然而, 当需要连续地对设备进行读/写时,应建立一个自己的urbs,同时将urbs 提交给USB子系统。
skel_disconnect函数:当释放设备文件句柄时,这个函数会被调用。
MOD_DEC_USE_COUNT宏也会被调用到(和MOD_INC_USE_COUNT刚好对应,它减少一个计数器),首先确认当前是否有其他的程序正在访问这个设备,如果是最后一个用户在使用,可以关闭任何正在发生的写,操作如下:
/* decrement our usage count for the device */
--skel->open_count;
if (skel->open_count <= 0) {
/* shutdown any bulk writes that might be
going on */
usb_unlink_urb (skel->write_urb);
skel->open_count = 0;
}
/* decrement our usage count for the module */
MOD_DEC_USE_COUNT;
USB设备可以在任何时间点从系统中取走,即使程序目前正在访问它。USB驱动程序必须要能够很好地处理解决此问题,它需要能够切断任何当前的读写,同时通知用户空间程序:USB设备已经被取走。
2.设计实例
下面通过介绍键盘飞梭驱动程序的实例来让读者更好的理解USB驱动程序的工作原理,实现代码如下:
/*需要的头文件*/
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/kbd_ll.h>
/* 驱动程序版本信息*/
#define DRIVER_VERSION ""
#define DRIVER_AUTHOR " TGE HOTKEY "
#define DRIVER_DESC "USB HID Tge hotkey driver"
#define USB_HOTKEY_VENDOR_ID 0x07e4
#define USB_HOTKEY_PRODUCT_ID 0x9473
/*厂商和产品ID信息就是/proc/bus/usb/devices中看到的值,通过cat/proc/bus/usb/devices得到当前系统探测到的USB总线上的设备信息。它包括Vendor、ProdID、Product等*/
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
/*此结构来自内核中drivers/usb/usbkbd.c*/
struct usb_kbd {
struct input_dev dev;
struct usb_device *usbdev;
unsigned char new[8];
unsigned char old[8];
struct urb irq, led;
struct usb_ctrlrequest dr;
unsigned char leds, newleds;
char name[128];
int open;
};
static void usb_kbd_irq(struct urb *urb) /*urb为USB请求块*/
{
struct usb_kbd *kbd = urb->context;
int *new;
new = (int *) kbd->new;
if(kbd->new[0] == (char)0x01)
{
if(((kbd->new[1]>>4)&0x0f)!=0x7)
{
handle_scancode(0xe0,1);
handle_scancode(0x4b,1);
handle_scancode(0xe0,0);
handle_scancode(0x4b,0);
}
else
{ handle_scancode(0xe0,1);
handle_scancode(0x4d,1);
handle_scancode(0xe0,0);
handle_scancode(0x4d,0);
}
}
printk("new=%x %x %x %x %x %x %x %x", kbd->new[0],kbd->new[1],kbd->new[2],kbd->new[3],
kbd->new[4],kbd->new[5],kbd->new[6],kbd->new[7]);
}
static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
{
struct usb_interface *iface;
struct usb_interface_descriptor *interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_kbd *kbd;
int pipe, maxp;
iface = &dev->actconfig->interface[ifnum];
interface = &iface->altsetting[iface->act_altsetting];
if ((dev->descriptor.idVendor != USB_HOTKEY_VENDOR_ID) || (dev->descriptor.idProduct != USB_HOTKEY_PRODUCT_ID) || (ifnum != 1))
{
return NULL;
}
if (dev->actconfig->bNumInterfaces != 2)
{
return NULL;
}
if (interface->bNumEndpoints != 1) return NULL;
endpoint = interface->endpoint + 0;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
usb_set_protocol(dev, interface->bInterfaceNumber, 0);
usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
printk(KERN_INFO "GUO: Vid = %.4x, Pid = %.4x, Device = %.2x, ifnum = %.2x, bufCount = %.8x\\n", dev->descriptor.idVendor,dev->descriptor.idProduct,dev->descriptor.bcdDevice, ifnum, maxp);
if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL;
memset(kbd, 0, sizeof(struct usb_kbd));
kbd->usbdev = dev;
FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp, usb_kbd_irq,kbd, endpoint->bInterval); kbd->irq.dev = kbd->usbdev;
if (dev->descriptor.iManufacturer) usb_string(dev, dev->descriptor.iManufacturer, kbd->name, 63);
if (usb_submit_urb(&kbd->irq)) {
kfree(kbd); return NULL; }
printk(KERN_INFO "input%d: %s on usb%d:%d.%d\\n", kbd->dev.number, kbd->name, dev->bus->busnum, dev->devnum, ifnum);
return kbd; }
static void usb_kbd_disconnect(struct usb_device *dev, void *ptr)
{
struct usb_kbd *kbd = ptr;
usb_unlink_urb(&kbd->irq);
kfree(kbd);
}
static struct usb_device_id usb_kbd_id_table [] = {
{ USB_DEVICE(USB_HOTKEY_VENDOR_ID, USB_HOTKEY_PRODUCT_ID) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
static struct usb_driver usb_kbd_driver = {
name: "Hotkey",
probe: usb_kbd_probe,
disconnect: usb_kbd_disconnect,
id_table: usb_kbd_id_table,
NULL,
};
static int __init usb_kbd_init(void)
{
usb_register(&usb_kbd_driver);
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
}
static void __exit usb_kbd_exit(void)
{
usb_deregister(&usb_kbd_driver);
}
module_init(usb_kbd_init);
module_exit(usb_kbd_exit);
三、结语
USB规范是一门比较新的技术,接口使用方便,但是驱动程序的设计较复杂。上面介绍了USB设备驱动程序的设计,主要分析了主机端驱动程序的设计,并且给出了一个编写USB驱动程序的实例。
参考文献
1.刘峥嵘.嵌入式Linux应用开发详界解.机械工业出版社,2004
2.周立功.ARM嵌入式Linux系统构件与驱动开发范例.北京航天航空大学出版社,2006
3.刘淼.嵌入式系统接口设计与Linux驱动程序开发.北京航天航空大学出版社,2006
posted @
2009-06-11 21:29 MEYE 阅读(560) |
评论 (0) |
编辑 收藏
转载--Linux经典书籍博物馆展览 2009-05-18 11:24
posted @
2009-06-11 21:29 MEYE 阅读(507) |
评论 (0) |
编辑 收藏
Linux C Function参考手册
Linux C Function参考手册一本深入详细介绍Linux C 函数的书。。
有用的朋友可以看下.
附件: [Linux C Function参考手册]
LinuxC-Function.pdf (2008-7-2 09:04, 926.65 K)
http://bbs.lupaworld.com/attachment.php?aid=7508
http://v.youku.com/v_show/id_XMzM5MTI0NTY=.html
posted @
2008-07-06 14:58 MEYE 阅读(822) |
评论 (1) |
编辑 收藏
http://www.kenengba.com/post/402.html
20多个在线操作系统(webOS)一览
写于
2008-03-21 – 2:18 下午 | 作者:Jason Ng | 类别 »
互联网络 |
之前我介绍了很多在线软件,而说到在线软件,不能不提在线操作系统(WebOS),相比起单个的在线软件,在线操作系统功能更全面,所有功能都是基于浏览器(如果你所在的地方禁用的MSN,不妨尝试使用WebOS来登录)。有人相信webOS会成为未来的主流,因为和在线软件一样,你能在任何地方连接到自己的工作平台和文件存储。这里介绍20多个WebOS,其中有不少是提供中文界面的。
1、I-Cube
提供1G的在线存储和文件共享,多媒体支持和一些常用办公工具。同时拥有一个email客户端和编程开发工具。
2、EyeOS
EyeOS是一个开源软件,可以下载使用也可以在其服务器上在线使用。拥有丰富的网络程序以及办公套件。个性化强度高。
3、eXo Enterprise WebOS
使用了大量的Web2.0元素构造,使用了大量的AJAX和Jacascript,因此它使用起来是相当方便的,即使在没有互联网连接的情况下也可以使用。
4、Zimdesk
Zimdesk提供的应用程序可以用琳琅满目来形容,从办公应用到多媒体应用,从文件管理到网络电视,又或者从RSS订阅到聊天工具,功能可谓是很好很强大。
5、Glide OS
一个需要flash支持的在线操作系统,除了提供Web入口之外,还提供移动网络入口。提供的程序和Zimdesk大同小异,不过有点杂乱。
6、WidgetPlus
顾名思义,这是一个以Widget为基础构成的WebOS,由于Widget的开放性,这个OS提供功能必将会越来越强大。
7、Peepel
与其说在线操作系统,不如说Peepel是一个在线办公应用,和Zoho,Google Docs是大同小异的。相比之下,我更喜欢Zoho。
8、Xindesk
一个免费在WebOS,支持所有的文件在线存储,日程管理,联系人资料等等。有点像Vista?
9、YouOS
YouOS是一个非常优秀的WebOS,使用JavaScript来与服务器交换数据,在进行下一步操作之前,上一步的操作会被记录,方便返回。另外,YouOS在在线协同操作方面做得非常优秀。
10、Widgetop
注意,你不能使用IE来登入这个WebOS!Firefox,Safari等都没有问题。即使是iPhone的浏览器也可以。由于又是基于Widget的,其扩展性是相当强的。
11、CorneliOS
12、JavaFlashBridge
13、Appmarks
一个用于iPhone和iPod Touch的在线操作系统, 事实上从外观看来也很有“水果商”的感觉。
14、Craythur
Craythur在界面设计上花了不少功夫,直观看起来和windows非常相似。
15、Desktoptwo
Desktoptwo不但拥有华丽的界面,其可操作性也是非常强大的,和其它很多webOS不同,它的所有应用程序都是用php语言编写的,并且都支持拖曳操作。
16、Ghost
此Ghost并非彼Ghost,这个是G.ho.st,但和赛门铁克的Ghost有几分相似,因为它也是经常做“备份”的操作。G.ho.st提供的功能也是相当强大的,而且界面看起来比较舒服。
17、Orca
OK,你的确很喜欢Vista,那么orca将会非常适合你。从截图你可以看出它有多像Vista,目前Orca的所有项目已经迁移到StartFoce上去。
18、SSOE
19、Purefect
20、Goowy
以上20个WebOS介绍摘译自My10sen。
21、TomOS
不能不提的中文webOS服务,很多功能都是符合中国人的使用习惯的,因此使用起来会非常得心应手。
22、Jooce
一个基于flash的webOS,支持的语言达10多种,当然其中包括中文。使用起来非常舒服,其速度也是相当可以的。但我在使用时总出现图片出错的情况,莫非我的图片是不雅照?
posted @
2008-03-26 11:40 MEYE 阅读(1154) |
评论 (0) |
编辑 收藏
Android平台介绍 http://www.loveandroid.com/
Google android介绍http://www.loveandroid.com/viewthread.php?tid=72&extra=page%3D2
http://topic.csdn.net/u/20080314/08/8eb27070-cc44-48be-af11-dc6da4023441.html
Android是什么? Android是一个针对移动设备的程序集, 其中包括一个操作系统, 一个中间件和一些关键性应用. 本文首先概览了Android SDK提供的工具和APIs, 当您在使用Java语言来开发Android平台的应用时您会用到它们.
特性
1.程序程序框架可重用及可复写组件组成
2.针对移动设备优化过的JAVA Dalvik虚拟机,采用流行的JAVA进行应用开发
3.整合浏览器, 该浏览器基于开源的WebKit引擎开发
4.提供了优化过得图形系统, 该系统由一个自定义的2D图形库; 一个遵循OpenGL ES 1.0标准(硬件加速)的3D图形库组成
5.使用SQLite来实现结构化数据的存储
6.媒体方面对一些通用的audio, video, 和图片格式提供支持(MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF)
7.GSM技术(依赖硬件)
8.蓝牙, EDGE, 3G和WiFi(依赖硬件)
9.Camera, GPS, 指南针, 和加速计 (依赖硬件)
10.非常丰富的开发环境, 包括一个设备模拟器, 调适工具, 内存和效率调优工具和一个Eclipse的插件
Android的结构
下图展示了Android 操作系统的主要组件结构. 每一部分都在下面的段落有详细介绍
1.应用程序 Android会附带一些核心的应用程序, 包括一个email客户端, 短信程序, 日历, 地图, 浏览器, 通讯录等.
2.所有的应用程序都是由Java语言完成的.
3.应用程序框架 开发人员可以跟那些核心应用一样, 拥有访问框架APIs的全部权限. 应用的系结构设计简化了各组件之间的重用;任何应用都可以分发自己的组件, 任何应用也可以使用这些分发的组件(应用的使用方法需遵循框架的安全性约束)。这个机制对用户来说同样适用, 他们也可以替换组件.
隐藏在每个应用后面的是一套服务和系统, 其中包括:
1.一套表现丰富,扩展性很强的View, 通过这些View您可以创建包括list, grid, 文本框, 按钮, 甚至一个嵌入浏览器的应用
Content Providers, 通过它可以在某个应用内访问其他应用的数据(例如通讯录), 或者共享自己的数据
Resource Manager, 提供对静态资源的访问能力, 例如国际化文本和layout文件
Notification Manager, 通过该机制, 所有的应用都可以在状态栏显示自己的提醒信息
Activity Manager, 用于管理应用的生命周期, 并且提供了通用的向后导航功能
2.库 Android 包含一套C/C++库, 被用于Android 系统中的各种组件中. 这些功能通过Android 应用框架展现给开发人员. 下面列出一些核心库:
System C library - 实现了BSD-derived 的标准C系统库(libc), 用于嵌入式的基于Linux的设备
Media Libraries - 基于PacketVideo的 OpenCORE; 该库提供了对许多流行的音频和视频格式的播放回放和录制功能, 同样包括静态图片文件, 包括MPEG4, H.264, MP3, AAC, AMR, JPG, 和 PNG 等
Surface Manager - 用于管理不同应用对图形显示子系统和2D和3D图形层的访问
LibWebCore - 一个时尚的web浏览器引擎, 为Android浏览器和内嵌的web view提供实现
SGL - 隐藏的2D图形引擎
3D libraries - 基于OpenGL ES 1.0 APIs实现的库; 该库用于3D图形加速或提供高优化的3D软件光栅器
FreeType - 位图和向量模式的字体绘制
SQLite - 一个强大的, 轻量的关系型数据库引擎, 用于所有的应用
Android 运行时 Android包含一组核心库, 提供了Java语言核心库内的大部分功能.
3.每一个Android应用运行在自己的进程里, 用该应用自己的Dalvik 虚拟机实例. Dalvik 可以让一个设备高效的运行很多个VM. Dalvik 虚拟机执行Dalvik Executable (.dex)格式的文件, 该格式的文件经过优化 占用很小的内存. 该虚拟机是基于存储器的, 运行经过Java语言编译器的类, 这些类通过"dx"工具被转换成.dex格式.
4.Dalvik 虚拟机依赖Linux kernel 来实现一些潜在功能, 例如线程和底层内存管理.
5.Linux Kernel Android基于Linux version 2.6内核来提供系统的核心服务, 例如安全机制, 内存管理, 进程管理, 网络堆栈和驱动模块. 该内核还扮演着一个虚拟的中间层, 该层介于硬件和其余的软件堆栈.
posted @
2008-03-26 10:13 MEYE 阅读(1059) |
评论 (0) |
编辑 收藏
http://www.5xue.com/modules/wordpress/?p=213
一切成功都是“一三五八成功模式”,这是《一生的保证》这本书的核心脉络,也是我八年研究成功学得出的结论,那些成功的人没有谁离开了这模式。那么“八”是什么呢?
人
类的一切设想都必须基于材料来实现,成功也毫无例外需要材料。所谓实现就是转化,成功是什么东西转化来的呢?显然还是物质、能量、信息,因为这世界除此之
外再无别的东西。但是物质、能量、信息是从最基本的哲学层面来说的,它并不具备操作性。你这一辈子可操作的资源不过八种:财富资源、信息资源、能力资源、
品质资源、人际资源、健康资源、时间资源、空间资源。
一、积累财富。金钱不是万能的,没钱是万万不能的,一句话没钱决不会成功。从你降生一刻起,从你喝第一口奶始,
物质就开始左右着你的命运。你的成长、你的教育以及人生的一切收获都是财富投资的结果。在你不能独立之前,财富决定着你,在你独立于社会后,财富影响着
你,即使是成功的人也要为此耗掉半生精力。在这个多变的职业世界里,你不会永远在一个地方工作,在一个岗位上淋漓尽致地发挥自己,当你感到无法施展时,你
会辞职或创业,如果你事先储蓄了足够的钱,将给你的成功奠定坚实的基础。
二、吸收信息。是信息造就了我们人,当然也是信息造就了我们的成功。一切创造、认知、判断都来源于信息,成功就
是不断吸收知识信息变成积木,然后按照你的规则把它搭出来。但我们最最核心的信息是某一专业的系统信息,你必须学会本行业所需要的一切知识并有见解。每个
人在年轻时都可能有过彻夜不眠、刻苦攻读,这在20岁甚或30岁都没有问题,但到了35岁,就不应该再为学习基本技能而大伤脑筋了。35岁应该是专家了,
在学术上差不多是副教授,基本上完成信息的积累,35岁之后就应该勃发了,可惜的是,许多人到四十岁了在本行业还没入门,他们的知识太缺乏系统,缺乏深度
了。
三、训练能力。能力=知识+训练,这是我的一个简化公式,不是心理学上的专业名词解释。掌握知识与智力有关,不
同类型的智力遗传度在35%~96%之间,而且95%以上都是正常的,智商低于70的弱智儿童全人口只占3%,所以我们先天性地就获得巨大资源,但这还不
是一个人全部的心理资源,甚至也不是开发出来的资源。高智商的人解决问题容易一些,但不等于成功就容易一些,世上有多少事非智商180不能做呢?只要智力
正常,就足够成功了,关键有没有把知识发挥出来用到实处的能力。第四章节“十全四美”十四种能力总有某几种是你的优势,你要用得炉火纯青,所谓“样样通样
样松”“一招鲜吃遍天”。十八般武艺你总要精一样,到35岁还不知自己的长处和短处是相当麻烦的,但不管怎样基本能力如表达、沟通、收集信息等每天都要
练。各种能力都极大地依赖于后天锻练与发掘,这才是一个人真正的心理资源,它与外界一切资源一样是取之不尽的,一个人到底能干些什么,谁也不知道,即便是
爱因斯坦也只是用了他潜能的一小部分。
四、磨练品质。也是心理资源的一部分,它渗透到外面的部分就是人格魅力。一个人能不能把八大资源吸引到自己身
上,能否承托起八大资源的负载,又能否把资源用到极至,靠的就是他的品质。俗话说大事做人,做的就是品质。年轻时犯错误,可以说是不成熟,但人家不会说你
品质有问题,当被人说品质有问题时,一辈子都完了。“1358”里的五大品质已经说过了,此不多说,再强调一点到35岁还没有形成风格魅力、人格魅力,下
半子希望不大。
五、扩大人际。资源的配置是不平衡的,你所需要的许多资源都在别人手里,可在他手里并不当作资源,同样你身上闲
置的东西也可能是别人苦苦追寻的东西。社会分工越来越细,任何有价值的工作都不可能由一个人完成。如果到了35岁你仍未建立起牢固的人际关系网,那你就有
麻烦了。这个人际关系网包括你的朋友、亲人、同爱好、同事、行业的骄骄者、新闻媒介等,最低限度包括所有可以互相帮助的人。其中家庭是第一人际关系网,家
庭不保、情感生活不愉快的人很能有大发展。人际关系网不是一朝一夕就能建立起来的,它需要几年甚至十几年的培养,同时也需要终生的维护。臭清高是中国知识
分子的一大悲哀,至到现在还有许多人意识不到自己失败的原因。所有的资源都需要你拿出精力去获取去交换,也就是说资源背后是成本,人际成本是必须花的,甚
至还相当高昂,因为它比任何一种资源带来的回报都大。
六、保持健康。这是支撑我们一辈子的物质和能量资源。五十岁前用健康换金钱,五十岁后用金钱换健康,这是有道理
的。只有健康资源的连续可用,我们的成功才有保证。35岁身体开始走下坡路了,可以说下半辈子都是吃老本,如果没有老本吃,那就完了。考察成功人士,一个
显要特征就是精力充沛,他们把健康资源优势发挥到最大程度。可以说每个人都有深刻的体验,一生病我们所有的愿望都萎缩了,一旦精神好转,我们理想的云帆又
高扬起来。而还有一些人,终因健康资源的断缺而成为悲剧英雄。
七、珍惜时间。时间是老生常谈的两个字,因而也就成了视而不见的资源。一幢大楼,人们只知道它由砂、石、水泥、
钢筋砌成,却不知道还有六个月的时间也砌在里面了,如果只给你一天时间,这个世界将没有大楼。坏就坏在世上没有一天的时间,有的只是无穷无尽的时间,它不
需要再生,而是永生,所以我们不到生命的结束,意识不到它的荒废和飞逝。年轻时你还浪费得起,到35岁你还不能有效地利用时间,还在一切无聊与懒散中,还
在弥补35前的漏洞中,可真危险了。
八、扩展空间。人是动物,动物的优势就是能自由地利用空间。但并不是每个人都能意识到空间是他的资源。以商业为
例,竞争的较量来较量去最后都到空间上来了,国际资本的全球渗透到了空前地步,如果不开放空间,哪有什么跨国公司,哪有什么连锁企业?毫无空间概念、更无
空间资源概念的人,他们在心理上已经注定是没有多少成长要求的人,他们无所谓成长,当然也就无所谓成功。不知您们相不相信,我身边一些35岁的人还没出过
省,他们都是大学毕业哦。
八种资源大致可分对应的四组,它们在同一轴上是同向增减的互动关系,成功资源图也就是成功熵势图,以总面积表示。一切资源都可以相互转化,从图示上
也是如此,增加任何一个轴,增加的都是总面积,都反应在任何一个轴上,反之亦然。但任何资源都不可以相互替代,西谚云:The trouble
with being poor is taking up all your
time。善哉!金钱可以买时间,但金钱绝不能替代时间,人际可以弥补才能,但决不可以替代才能。资源不是平均分布,要想总面积最大,那就是全面发展的圆
周,可以像车轮一样飞奔,而奇形怪状则很难滚动起来。很多人寄望于一种资源,那就是能力资源里的智力因素,抱有希望或每每埋怨的也都是它,以为只要有了它
就万事大吉了,即使这一种资源也可能只用了五分之一,而其它的七又五分之四资源都被白白浪费了,所以你一生中实际资源利用率是四十分之一,2.5%,这就
是你的成功概率。而成功人士,都是珍惜资源,并且把资源使用到极至的人。摘自黄怀宁《一生的保证》。
posted @
2008-02-14 17:25 MEYE 阅读(576) |
评论 (0) |
编辑 收藏
[转:]http://blog.chinaunix.net/u/15586/showart.php?id=473344
推荐几款PYTHON编辑器:
推荐几款不错的python编辑器吧。这里推荐的几个并不是像vim,emacs一类的老牌编辑器,而是主要
针对python的编辑器。在我看来,我所需要的代码编辑器的功能,包括代码折叠,语法高亮,行号显示,代码提示,当然能够你IDE一样加入调试和执行功
能就再好不过了。今晚我介绍几款,这些功能上面参差不齐,希望对有需要的朋友有所帮助。
1.PythonWinEditor
如果你安装activePython或pywin32模块的话,这个编辑器一般默认情况下都会安装的。pythonwineditor其实非常不错,上述所说的四项功能一应俱全,而且会有调试功能。完全免费,算是这里面不错的选择了。
2.Editra
Editra在你安装最新版的wxPython的时候会有选项提示你是否安装,当然你也可以直接从他的站点下载独立安装。这个软件出来时间并不长,但是却很有趣。我说的功能也都有,代码提示功能更是让人喜爱,软件是用python和wxPython完成的,很不错。
3.KomodoIDE/Editor
ActiveState
现在专门针对开源脚本语言开发一些不错的应用。KomodoIDE是KomodoEditor的增强版本,当然是收费的,而
KomodoEditor却是免费的。虽然这款软件觉得占用内存比较大,但是软件的代码提示功能让你喜欢。感觉比上述两款的提示功能要强得多。
Editor没有调试和运行功能,而IDE则相对应的有这些功能。不过对于一般用户来讲,Editor也已经够用了。当然如果你想花点银子的话搞IDE的
话,也是物有所值的。
国内的python大牛limodo出的一个Ulipad,我就不多想介绍了。软件代码自动提示功能并不十分实善,而且感
觉一个编辑器挺占用内存的,这一点并不好,而且色彩上面用太亮眼的绿色在里面,有点难看了。就不太向大家推荐了。开源的世界是一个多彩的世界,你总能从里
面发现一些有趣的东西。我喜欢这些有趣的东西,python把我带来一个新境界,他让我看到更多更有趣的东西。你可以用python完成更多你想要做的
事,而且这一切基本上没有什么不可能的。随着你对这门语言的深入,你会爱上他,在我看来,现在许多应用层上的程序,python都能快速有效的完成,而且
你会觉得他很安全,辅助你思维更加清晰。python和许多语言的理念往往不同,通过C/C++语言,你会觉得你所要的许多功能你所想到的第一件事是怎么
实现这一功能,你想要做一件事,往往需要自己写许多代码就会帮你实现;而python则不同,你想到的一件事是有什么模块可以帮我实现。前两天看见一个T
恤写着“生命短暂,我用python“。是呀,用python不需要费太多的脑子,因为已经帮你想好和做好了你想要实现的功能。你只需要轻松调用就可以
了。用python你不必花费太多的心思在怎么实现上面,而是花更多的心思在问题的解决思路上面。虽然我在07年的11/12月份才开始接触这门语言,但
是,却深深的喜欢上了她。python的世界是自由的,但代码是工整的;python是包容的,可以容纳下你想要的任何功能,我爱开源,我爱
python.
用python进行GUI开发的选择:
用python进行GUI开发的选择
Python最大的特点就在于她的快速开发功能。作为一种胶水型语言,python几乎可以渗透在我们编程过程中的各个领域。这里我简单介绍一下用python进行gui开发的一些选择。
1.Tkinter
Tkinter
似乎是与tcl语言同时发展起来的一种界面库。tkinter是python的配备的标准gui库,也是opensource的产物。Tkinter可用
于windows/linux/unix/macintosh操作系统,而且显示风格是本地化的。Tkinter用起来非常简单,python自带的
IDLE就是采用它写的。除此外,tkinter的扩展集pmw和Tix功能上都要相对它强大,但tkinter却是最基本的。我认为,在用python
做gui开发,tkinter是最基本的知识,所以这个环节是必须要学习的。你或许在以后的开发中并不常用tkinter,但是一些小型的应用上面,他还
是很有用的,而且开发速度也很快。
2.WxPython
WxWidgets应该算是近几年了比较流行的GUI跨平台开发技术了。
wxWidgets有不同的版本应用,有c++的,也有basic的,现在在python上面也有较好的移植。wxpython的功能上面要强于
tkinter,她提供了超过200个类,面向对象的编程风格,设计的框架类似于MFC。对于大型GUI应用上面,wxPython还是具有很强的优势
的。boa constructor可以帮助我们快速可视地构建wxwidgets界面。
3.PyQT
Qt同样是一种开源的GUI库,Qt的类库大约在300多个,函数大约在5700多个。Qt同样适合于大型应用,由它自带的qt designer可以让我们轻松来构建界面元素。
4.pyGtk
Gtk是linux下Gnome的核心开发库了。功能上面非常齐全。值得说明的是,在windows平台下gtk的显示风格并不是特别本地化。不过他带的glade的界面设计器还是可以帮你省不少事的。
5.Jython
尝试过用python访问java类库吗,那么就用jython吧。jython其实可以认为是另外一个python开发环境,基于java的,但是大多
数的CPython调用jython下还是可以的。你可以在jython环境下像使用java一样来通过python的语法来调用java语言,真的很
酷。
6.MFC
Windows Pywin32允许你像VC一样的形式来使用PYTHON开发win32应用。代码风格可以类似win32 sdk,也可以类似MFC,由你选择。如果你仍不放弃vc一样的代码过程在python下,那么这就是一个不错的选择。
7.PythonCard
PythonCard其实是对wxPython的再封装。不过封装的更加简单,使用起来觉得比wxPython更直观,也更简单化了。
8.Dabo
仍是一个基于wxpython的再封装库,没用过,不太了解。它提供数据库访问,商业逻辑以及用户界面。
9.AnyGui
通过底层的api来访问其它工具集,像tkinter,wxpython和qt.具体也没怎么用过。
10.WPY
MFC风格的Gui开发库,代码风格也类似于MFC,仅管如此,你依旧可以使用这个库来开发GUI应用,而不用担心平台移植的问题。她同样是一个跨平台的库。
11.IronPython
如果你要想开发.net下面的应用的话,那么IronPython就是你的选择,与jython有点类似,他同样支持标准的python模块,但同样增加
了对.net库的支持。你也可以理解为他是另一个python开发环境。你可以非常方便地使用python语法进行.net应用的开发,这一点听起来真的
挺有意思。
总之,介绍了这么多,我个人意见是,如果你是java用户,那么你就用jython吧,除了可以享受python的模块功能及语法
外,你可以找到许多java的影子;如果你是.net用户,那么就用iron python吧。如果你对Visual
C++很熟悉,那么你可以使用MFC,WPY或是wxPython,当然我更建议wxPython了。当然,我认为对于tkinter是每一个原来搞C的
人都应该了解和学习的GUI库,因为她很轻便,小型应用就可以使用她来搞定,而对于较大型应用可以采用pyGtk,pyQt,WxPython或
PythonCard来搞定,这样的话,既可以注重知识的衔接性,也可以快速进行软体的开发了。
基于Python的socket编程[原]
服务端:
#socket server端
#获取socket构造及常量
from socket import *
#''代表服务器为localhost
myHost = ''
#在一个非保留端口号上进行监听
myPort = 50007
#设置一个TCP socket对象
sockobj = socket(AF_INET, SOCK_STREAM)
#绑定它至端口号
sockobj.bind((myHost, myPort))
#监听,允许5个连结
sockobj.listen(5)
#直到进程结束时才结束循环
while True:
#等待下一个客户端连结
connection, address = sockobj.accept( )
#连结是一个新的socket
print 'Server connected by', address
while True:
#读取客户端套接字的下一行
data = connection.recv(1024)
#如果没有数量的话,那么跳出循环
if not data: break
#发送一个回复至客户端
connection.send('Echo=>' + data)
#当socket关闭时eof
connection.close( )
|
客户端:
import sys
from socket import *
serverHost = 'localhost'
serverPort = 50007
#发送至服务端的默认文本
message = ['Hello network world']
#如果参数大于1的话,连结的服务端为第一个参数
if len(sys.argv) > 1:
serverHost = sys.argv[1]
#如果参数大于2的话,连结的文字为第二个参数
if len(sys.argv) > 2:
message = sys.argv[2:]
#建立一个tcp/ip套接字对象
sockobj = socket(AF_INET, SOCK_STREAM)
#连结至服务器及端口
sockobj.connect((serverHost, serverPort))
for line in message:
#经过套按字发送line至服务端
sockobj.send(line)
#从服务端接收到的数据,上限为1k
data = sockobj.recv(1024)
#确认他是引用的,是'x'
print 'Client received:', repr(data)
#关闭套接字
sockobj.close( )
posted @
2008-02-04 11:42 MEYE 阅读(958) |
评论 (0) |
编辑 收藏
Linux 平台上的C语言调试工具!
Debugging Tools for C on
Linux Platform
http://www.linuxgazette.com/node/view/8755
Submitted by Nikhil Bhargava on Tue, 02/17/2004 - 14:37. Articles | General Interest
This article talks about debugging tools for applications in C on Linux
platforms. Most of the tools are freely available on all major
platforms with very wide user support. The tools help in static
analysis of code as well as assist in dynamic evaluation of code.
Please
note that tools listed here are suggestions of the author. This list is
not a standard one. Changes have to be done in it depending upon the
nature, scope and details of the application to be developed.
Debugging Tools
1. Dmalloc
http://dmalloc.com/
The debug memory allocation or Dmalloc library is a freeware debugging
tool which has been specially designed as a drop in replacement for the
system's malloc, realloc, calloc, free and other memory management
routines while providing powerful debugging facilities configurable at
runtime. It makes changes during compile time and donot add runtime
changes in binary. These facilities include such things as memory-leak
tracking, fence-post write detection, file/line number reporting, and
general logging of statistics. The library is reasonably portable
having been run successfully on at least the following operating
systems: AIX, BSD/OS, DG/UX, Free/Net/OpenBSD, GNU/Hurd, HPUX, Irix,
Linux, MS-DOG, NeXT, OSF, SCO, Solaris, SunOS, Ultrix, Unixware,
Windoze, and even Unicos on a Cray T3E. It has full support for
programs the debugging of POSIX threads.
The package includes the library, configuration scripts, debug utility application, test program, and documentation.
2. Valgrind
http://valgrind.kde.org/
Valgrind is a GPL distributed system for debugging and profiling
x86-Linux programs. I can also be helpful for programs for platforms
other than x86 since behavior of x86 binary is similar to other
binaries. The accompanying tools with Valgrind automatically detect
many memory management and threading bugs, avoiding hours of
frustrating bug-hunting, making programs more stable. It supports a
through detailed profiling to help speed up the programs.
The Valgrind distribution includes four tools: two memory error detectors, a thread
error detector, and a cache profiler.
3. Electricfence
http://rpmfind.net/linux/RPM/conecti...-2cl.i386.html
Electric Fence is a freeware library that can be used for C programming
and debugging. It can be linked at compile time and it will warn about
possible problems such as freeing memory that doesn't exist, etc. It is
basically a memory profiling tool. However currently it is available
only on HP-Unix platform (I am not very sure though).
4. GDB
http://sources.redhat.com/gdb
This is the Gnome Debugger which comes as a freeware support package
with freeware Linux distribution like Red Hat, Slacware, and Debian
etc. It has full support of many languages like C, C++, and Perl etc.
It helps to debug the binaries of these languages in modes like single
step, multiple step or complete run. It also has provisions of setting
break points and trace value.
It is helpful for stub testing, functional flow checking and bound checking.
Further this is readily available with all flavours of Linux andUnix platforms and is amply supported in user community.
5. Insight
http://sources.redhat.com/insight
Insight is a graphical user interface to GDB, the GNU Debugger written
in Tcl/Tk by at Red Hat, Inc. and Cygnus Solutions Insight provides all
features provided by GDB along with Graphical debugging interface
replacing traditional command based interface.
6. Memprof
http://www.gnome.org/projects/memprof
MemProf is a free ware memory Profiling and memory leak detection tool
which comes as an addendum to common Linux distributions. It can
generate a profile how much memory was allocated by each function in
the program. It can scan memory and find blocks that have been
allocated but are no longer referenced anywhere (dead code).
MemProf works by pre-loading a library to override the C library's
memory allocation functions and does not require recompiling the
program. One advantage MemProf has over some other similar tools that
are available is that it has a nice GUI front-end and is relatively
easy to use.
I am Nikhil Bhargava from Delhi, India. I am a Computer Engineer
currently working in C-DOT, India for past one year. Comments and
Suggestions are always welcome.
【硬件编程咨询】C语言资料大全
◆经典C源程序100例:http://post.baidu.com/f?kz=8618367
◆时钟的驻留程序:http://post.baidu.com/f?kz=10822377
◆数据结构暨若干经典问题和算法:http://post.baidu.com/f?kz=10922856
◆LIUXUY 磁盘系统源程序:http://post.baidu.com/f?kz=12973347
◆RLE压缩:http://post.baidu.com/f?kz=12592570
◆快速排序:http://post.baidu.com/f?kz=12262349
◆全排列的递归算法:http://post.baidu.com/f?kz=12248706
◆KMP字符串搜索算法:http://post.baidu.com/f?kz=12143581
◆C高效编程四招:http://post.baidu.com/f?kz=13192245
◆无栈非递归二叉树遍历:http://post.baidu.com/f?kz=12394188
◆跟我学NETBSD内核源码:http://post.baidu.com/f?kz=12201581
◆Linux源码:http://post.baidu.com/f?kz=12692827
◆C语言中不定参数的实现http://post.baidu.com/f?kz=19232306
◆一个有关 FreeBSD 的网站:http://post.baidu.com/f?kz=14828500
◆c51系列仿真器:http://post.baidu.com/f?kz=14332652
◆brainf*ck 语言的解释器http://post.baidu.com/f?kz=15998145
◆怎样用c写游戏:http://post.baidu.com/f?kz=5417859
◆本吧游戏编程相关:http://post.baidu.com/f?kz=11867577
◆简单的病毒程序:http://post.baidu.com/f?kz=5558054
◆迷宫游戏:http://post.baidu.com/f?kz=5781985
◆QQ好友管理程序:http://post.baidu.com/f?kz=5071518
◆销售监控程序:http://post.baidu.com/f?kz=6352894
◆简单的仓储管理系统:http://post.baidu.com/f?kz=7316990
◆简单的电话储存系统:http://post.baidu.com/f?kz=7257980
◆模拟电子时钟的程序:http://post.baidu.com/f?kz=7519467
◆计算任意一天是星期几:http://post.baidu.com/f?kz=8329211
◆打印任意月份日历:http://post.baidu.com/f?kz=8880741
◆分类记事本:http://post.baidu.com/f?kz=8154266
◆TC2编程图片处理利器:http://post.baidu.com/f?kz=11163580
◆printf写的游戏:http://post.baidu.com/f?kz=11162185
◆人机对战扑克游戏:http://post.baidu.com/f?kz=11366672
◆俄罗斯方块:http://post.baidu.com/f?kz=12145169
◆俄罗斯方块:http://post.baidu.com/f?kz=16028030
◆文本加密例程:http://post.baidu.com/f?kz=11968123
◆给一行文字设置密码加解密:http://post.baidu.com/f?kz=20205053
◆破解BIOS密码:http://post.baidu.com/f?kz=12230804
◆贪吃蛇1代:http://post.baidu.com/f?kz=30512251
◆完整的贪吃蛇游戏:http://post.baidu.com/f?kz=31119717
◆贪吃蛇:http://post.baidu.com/f?kz=19624003
◆学生成绩系统(C++版) http://post.baidu.com/f?kz=6640660
◆图书馆管理系统http://post.baidu.com/f?kz=22241061
◆图书管理系统http://post.baidu.com/f?kz=17682927
◆万年历http://post.baidu.com/f?kz=17197492
◆判断闰年http://post.baidu.com/f?kz=16137615
◆万年历http://post.baidu.com/f?kz=20493202
◆变化的同心圆http://post.baidu.com/f?kz=18056765
◆通讯录 http://post.baidu.com/f?kz=22775724
◆C语言通讯录(数组):http://post.baidu.com/f?kz=37202204
◆飞机票订购系统http://post.baidu.com/f?kz=21296518
◆又一个计算器:http://post.baidu.com/f?kz=24283347
◆一个级数:http://post.baidu.com/f?kz=16708781
◆四则运算计算器http://post.baidu.com/f?kz=22279483
◆二叉树排序树上实现学生信息管理http://post.baidu.com/f?kz=21436251
◆判断回文字符串:http://post.baidu.com/f?kz=21815959
◆教小学生算术:http://post.baidu.com/f?kz=22322599
◆六籽弹小游戏http://post.baidu.com/f?kz=17637684
◆黑白棋:http://post.baidu.com/f?kz=19624178
◆十个学生的成绩统计:http://post.baidu.com/f?kz=14787745
◆某一天是这一年的第几天:http://post.baidu.com/f?kz=13772082
◆局域网聊天的程序:http://post.baidu.com/f?kz=14413292
◆C编写简单的窗口界面:http://post.baidu.com/f?kz=3388604
◆哈希表实例:http://post.baidu.com/f?kz=13350908
◆随机生成的迷宫游戏:http://post.baidu.com/f?kz=11120413
◆炸弹超人游戏c语言简版:http://post.baidu.com/f?kz=37461531
◆用栈实现的迷宫寻径演示:http://post.baidu.com/f?kz=38578844
◆计算电脑开机时间:http://post.baidu.com/f?kz=38506368
◆C++编一个成绩管理课件:http://post.baidu.com/f?kz=3889433
◆一圈人报数问题问题:http://post.baidu.com/f?kz=3833415
◆又一报数出圈http://post.baidu.com/f?kz=17789700
◆约瑟夫环循环链表 http://post.baidu.com/f?kz=13750140
◆用c编一个分数计算器程序 :http://post.baidu.com/f?kz=3831746
◆命令行计算器:http://post.baidu.com/f?kz=8465088
◆乘法表:http://post.baidu.com/f?kz=11267637
◆学生管理系统:http://post.baidu.com/f?kz=5806073
◆学生成绩管理系统:http://post.baidu.com/f?kz=37076140
◆学生成绩管理系统:http://post.baidu.com/f?kz=5972675
◆学生成绩管理程序(链表):http://post.baidu.com/f?kz=6598859
◆统计学生成绩(8pm版)http://post.baidu.com/f?kz=14787745
◆打印九九表:http://post.baidu.com/f?kz=6059385
◆水仙花数问题:http://post.baidu.com/f?kz=11510377
◆打印2004年日历:http://post.baidu.com/f?kz=6469868
◆八皇后问题:http://post.baidu.com/f?kz=4456709
◆八皇后问题(do熊版):http://post.baidu.com/f?kz=8513222
◆汉诺塔问题:http://post.baidu.com/f?kz=7402377
◆统计不同字符个数:http://post.baidu.com/f?kz=7394163
◆统计单词数行数:http://post.baidu.com/f?kz=8211273
◆查找替换字符串并统计次数:http://post.baidu.com/f?kz=7335032
◆杨辉三角:http://post.baidu.com/f?kz=9299150
◆屏幕中间输出杨辉三角http://post.baidu.com/f?kz=12054232
◆矩阵转置:http://post.baidu.com/f?kz=9882271
◆输出用*组成的三角形:http://post.baidu.com/f?kz=8465901
◆输出一个菱形:http://post.baidu.com/f?kz=11879706
◆输出菱形http://post.baidu.com/f?kz=16465168
◆手把手教你写猜数游戏:http://post.baidu.com/f?kz=11205156
◆abort函数简介:http://post.baidu.com/f?kz=8610596
◆getchar与putchar:http://post.baidu.com/f?kz=7820387
◆scanf 讨论:http://post.baidu.com/f?kz=5305522
◆C语言输入输出讨论:http://post.baidu.com/f?kz=7586045
◆时间函数clock():http://post.baidu.com/f?kz=7867779
◆在规定时段自动关机:http://post.baidu.com/f?kz=7132544
◆getch防止程序运行一闪而过:http://post.baidu.com/f?kz=7360819
◆MALLOC FREE问题:http://post.baidu.com/f?kz=4826280
◆一个连接两个字符串的函数:http://post.baidu.com/f?kz=7958354
◆同一行回显输入字符:http://post.baidu.com/f?kz=5272169
◆整点报时问题:http://post.baidu.com/f?kz=7307517
◆c语言中随机数字应用: http://post.baidu.com/f?kz=3065339
◆怎样获取文件大小:http://post.baidu.com/f?kz=4189689
◆程序得到自已的当前名称:http://post.baidu.com/f?kz=5993842
◆怎么使用清屏:http://post.baidu.com/f?kz=6087210
◆sound()函数为何没有声音:http://post.baidu.com/f?kz=30844221
◆自写trim函数:http://post.baidu.com/f?kz=14226973
◆bioskey(1)的问题:http://post.baidu.com/f?kz=14651579
http://post.baidu.com/f?kz=14536875
◆bioskey这个函数怎么用:http://post.baidu.com/f?kz=15272841
◆CHAR*转为LONG:http://post.baidu.com/f?kz=15054773
◆LONG毫秒转为CHAR*分秒的函数:http://post.baidu.com/f?kz=15140414
◆狐狸找兔子:http://post.baidu.com/f?kz=8729392
◆猴子吃桃:http://post.baidu.com/f?kz=8448705
◆猜数游戏: http://post.baidu.com/f?kz=4215306
◆二分法解方程:http://post.baidu.com/f?kz=7663955
◆同余在数值计算中的应用:http://post.baidu.com/f?kz=6924343
◆多项式相乘:http://post.baidu.com/f?kz=7441950
◆韩信点兵:http://post.baidu.com/f?kz=8203887
◆用C编写的四叶玫瑰曲线:http://post.baidu.com/f?kz=7853365
四叶玫瑰曲线的旋转动画:http://post.baidu.com/f?kz=18656216
◆求n个数的最大公约数:http://post.baidu.com/f?kz=6848849
◆寻找完数:http://post.baidu.com/f?kz=11892209
◆蛇形矩阵算法:http://post.baidu.com/f?kz=12433353
◆圆周率计算:http://post.baidu.com/f?kz=12394522
◆小球称重:http://post.baidu.com/f?kz=12648561
◆整数分解:http://post.baidu.com/f?kz=12582169
◆整数的立方=两整数的平方差:http://post.baidu.com/f?kz=15121585
◆阶乘级数:http://post.baidu.com/f?kz=14601711
◆三点坐标求三角形面积:http://post.baidu.com/f?kz=14679236
◆多项式相乘http://post.baidu.com/f?kz=17157736
◆求pi的怪异程式:http://post.baidu.com/f?kz=14832207
◆歌德巴赫猜想:http://post.baidu.com/f?kz=20011131
◆求最大公约数和最小公倍数http://post.baidu.com/f?kz=15965236
◆3个正整数的最小公倍数http://post.baidu.com/f?kz=17747110
◆求阶乘:http://post.baidu.com/f?kz=19314067
◆输出三数最大值:http://post.baidu.com/f?kz=19023855
◆10000以内的阶乘(do熊版)http://post.baidu.com/f?kz=16446002
◆算法:整数划分问题http://post.baidu.com/f?kz=12582169
◆辗转法求2个数最大公约数http://post.baidu.com/f?kz=16965299
◆算24:http://post.baidu.com/f?kz=17336190
◆100元买100只鸡:http://post.baidu.com/f?kz=14920285
◆COS X曲线http://post.baidu.com/f?kz=16633244
◆矩阵的加减乘运算演示:http://post.baidu.com/f?kz=37953154
◆狐狸找兔子:http://post.baidu.com/f?kz=8729392
◆猴子吃桃:http://post.baidu.com/f?kz=8448705
◆猜数游戏: http://post.baidu.com/f?kz=4215306
◆二分法解方程:http://post.baidu.com/f?kz=7663955
◆同余在数值计算中的应用:http://post.baidu.com/f?kz=6924343
◆多项式相乘:http://post.baidu.com/f?kz=7441950
◆韩信点兵:http://post.baidu.com/f?kz=8203887
◆用C编写的四叶玫瑰曲线:http://post.baidu.com/f?kz=7853365
四叶玫瑰曲线的旋转动画:http://post.baidu.com/f?kz=18656216
◆求n个数的最大公约数:http://post.baidu.com/f?kz=6848849
◆寻找完数:http://post.baidu.com/f?kz=11892209
◆蛇形矩阵算法:http://post.baidu.com/f?kz=12433353
◆圆周率计算:http://post.baidu.com/f?kz=12394522
◆小球称重:http://post.baidu.com/f?kz=12648561
◆整数分解:http://post.baidu.com/f?kz=12582169
◆整数的立方=两整数的平方差:http://post.baidu.com/f?kz=15121585
◆阶乘级数:http://post.baidu.com/f?kz=14601711
◆三点坐标求三角形面积:http://post.baidu.com/f?kz=14679236
◆多项式相乘http://post.baidu.com/f?kz=17157736
◆求pi的怪异程式:http://post.baidu.com/f?kz=14832207
◆歌德巴赫猜想:http://post.baidu.com/f?kz=20011131
◆求最大公约数和最小公倍数http://post.baidu.com/f?kz=15965236
◆3个正整数的最小公倍数http://post.baidu.com/f?kz=17747110
◆求阶乘:http://post.baidu.com/f?kz=19314067
◆输出三数最大值:http://post.baidu.com/f?kz=19023855
◆10000以内的阶乘(do熊版)http://post.baidu.com/f?kz=16446002
◆算法:整数划分问题http://post.baidu.com/f?kz=12582169
◆辗转法求2个数最大公约数http://post.baidu.com/f?kz=16965299
◆算24:http://post.baidu.com/f?kz=17336190
◆100元买100只鸡:http://post.baidu.com/f?kz=14920285
◆COS X曲线http://post.baidu.com/f?kz=16633244
◆矩阵的加减乘运算演示:http://post.baidu.com/f?kz=37953154
◆@ 的读音:http://post.baidu.com/f?kz=12952426
◆“&”怎么读http://post.baidu.com/f?kz=17725981
◆gcc跨平台问题:http://post.baidu.com/f?kz=5371847
◆LL型运算(64位): http://post.baidu.com/f?kz=5248192
◆正方形动画下落(不用清屏):http://post.baidu.com/f?kz=5467099
◆大数运算的免费库libgmp:http://www.swox.com/gmp/
◆大数运算10000以内阶乘:http://post.baidu.com/f?kz=2780897
◆素数搜索算法程序:http://post.baidu.com/f?kz=6221885
◆bmp文件读写: http://post.baidu.com/f?kz=5236264
◆用C显示PCX文件:http://post.baidu.com/f?kz=6059067
◆汇编语言嵌入C 程序段:http://post.baidu.com/f?kz=4038342
◆宏替换问题: http://post.baidu.com/f?kz=5327438
◆宏定义带括号的问题:http://post.baidu.com/f?kz=10001502
◆大下标数组操作:http://post.baidu.com/f?kz=4201196
◆关于数组越界:http://post.baidu.com/f?kz=13204257
◆整数数组初始化赋值:http://post.baidu.com/f?kz=8513573
◆字符数组与字符串:http://post.baidu.com/f?kz=7608560
◆字符串数组下标问题:http://post.baidu.com/f?kz=11253296
◆数组的编译和执行的效率:http://post.baidu.com/f?kz=6243463
◆C写的隐式输入密码:http://post.baidu.com/f?kz=5438409
◆又一个隐式密码输入:http://post.baidu.com/f?kz=11321460
◆C 的文本文件行操作:http://post.baidu.com/f?kz=4303211
◆链表的数据插入:http://post.baidu.com/f?kz=5851022
◆链表的合并:http://post.baidu.com/f?kz=5790984
◆双向链表的插入和删除:http://post.baidu.com/f?kz=6352819
◆谭C例题链表插入删除操作:http://post.baidu.com/f?kz=2286853
◆进制转换的几个函数:http://post.baidu.com/f?kz=5799330
◆十进制转二进制的一种方法:http://post.baidu.com/f?kz=4201639
◆鼠标事件处理:http://post.baidu.com/f?kz=5469795
◆两个鼠标函数库:http://post.baidu.com/f?kz=6952040
◆鼠标器的程序信息:http://post.baidu.com/f?kz=2728110
◆关于鼠标程序:http://post.baidu.com/f?kz=12299687
◆中断号调用:http://post.baidu.com/f?kz=5469596
◆几个中断的资料:http://post.baidu.com/f?kz=7462907
◆C语言接口与实现:http://post.baidu.com/f?kz=5979383
◆C语言的串口通信:http://post.baidu.com/f?kz=8467750
◆怎样理解递归对栈的应用:http://post.baidu.com/f?kz=9882580
◆递归求组合定值:http://post.baidu.com/f?kz=5824841
◆递归求元素和:http://post.baidu.com/f?kz=6380549
◆全排列:http://post.baidu.com/f?kz=7336872
◆擂台赛--求1000000素数:http://post.baidu.com/f?kz=6221885
◆擂台赛--大数运算:http://post.baidu.com/f?kz=6279195
◆字符串编辑时光标的控制:http://post.baidu.com/f?kz=6230397
◆在指定位置输出字符:http://post.baidu.com/f?kz=12059970
◆光盘启动菜单的问题:http://post.baidu.com/f?kz=6093143
◆NOIP复赛文件名大小写问题:http://post.baidu.com/f?kz=6270393
◆程序的带参运行 http://post.baidu.com/f?kz=3545215
◆关于main 的参数:http://post.baidu.com/f?kz=7535662
◆main 函数返回值问题:http://post.baidu.com/f?kz=11161360
◆一个主函数参数问题:http://post.baidu.com/f?kz=9495695
◆函数参数中引用别名问题:http://post.baidu.com/f?kz=9299395
◆函数调用返回多个值:http://post.baidu.com/f?kz=5536004
◆函数中参数调用的问题:http://post.baidu.com/f?kz=6035295
◆函数参数按址传送的问题:http://post.baidu.com/f?kz=5558840
◆assiss谈宏定义及条件编译:http://post.baidu.com/f?kz=6193259
◆输出格式*号控制符:http://post.baidu.com/f?kz=7149608
◆输出格式的空格问题:http://post.baidu.com/f?kz=5147346
◆输出格式中#代表什么:http://post.baidu.com/f?kz=11993035
◆程序代码的上传与下载:http://post.baidu.com/f?kz=6566895
◆++i和i++的问题:http://post.baidu.com/f?kz=6712609
◆ASCII字符输出问题:http://post.baidu.com/f?kz=6771317
◆Fdisk的源程序:http://post.baidu.com/f?kz=6790551
◆正则替换:http://post.baidu.com/f?kz=6775253
◆自我保护----“程序自杀”:http://post.baidu.com/f?kz=6682850
◆编辑框问题:http://post.baidu.com/f?kz=6953560
◆西文环境下显示汉字:http://post.baidu.com/f?kz=2144548
◆读取汉字库中的汉字:http://post.baidu.com/f?kz=7359496
◆三种排序:http://post.baidu.com/f?kz=6769579
◆far 远程指针简述:http://post.baidu.com/f?kz=7742757
◆指针悬空的危险错误:http://post.baidu.com/f?kz=7130531
◆指针作参数的问题:http://post.baidu.com/f?kz=6922977
◆判断字符串是否回文: http://post.baidu.com/f?kz=7624806
◆编程中遇到的小困扰:http://post.baidu.com/f?kz=8002835
◆UNIX下面怎么编译C程序:http://post.baidu.com/f?kz=8046512
◆C如何调用其他程序:http://post.baidu.com/f?kz=8355281
◆C游戏中控制键盘:http://post.baidu.com/f?kz=4902906
◆C语言控制应用:http://post.baidu.com/f?kz=8399030
◆C项目工程(unix下)注意事项:http://post.baidu.com/f?kz=9087043
◆make file(unix下)易错地方:http://post.baidu.com/f?kz=9362741
◆补码问题:http://post.baidu.com/f?kz=11189164
◆DOS仿多线程问题:http://post.baidu.com/f?kz=11553963
◆栈的push和pop操作:http://post.baidu.com/f?kz=10820691
◆头文件如何理解:http://post.baidu.com/f?kz=7566720
◆编程解IQ测试:http://post.baidu.com/f?kz=11359491
◆逻辑破案的编程处理:http://post.baidu.com/f?kz=11283225
◆VC++中浮点数与字符串转化:http://post.baidu.com/f?kz=12061615
◆为何VC++6.0无法运行某些C程序:http://post.baidu.com/f?kz=11123696
◆逆序输出:http://post.baidu.com/f?kz=11484218
◆scanf:floating points format not linked:http://post.baidu.com/f?kz=12999839
◆c输出到打印机:http://post.baidu.com/f?kz=12482547
◆源代码-自我产生的程序:http://post.baidu.com/f?kz=14261864
◆PC 底层系统编程:http://post.baidu.com/f?kz=14071636
◆C中怎么制作函数库:http://post.baidu.com/f?kz=14190938
◆有关 FreeBSD 的网站:http://post.baidu.com/f?kz=14828500
◆一个画图程序:http://post.baidu.com/f?kz=15165712
◆算法--贪心法:http://post.baidu.com/f?kz=15321632
◆合并排序:http://post.baidu.com/f?kz=15330626
◆射击游戏:http://post.baidu.com/f?kz=15417872
◆怎样编一个螺旋数组:http://post.baidu.com/f?kz=15384659
C中怎么制作函数库:http://post.baidu.com/f?kz=14190938
10发90环有多少种可能:http://post.baidu.com/f?kz=15878635
Dev-C++4.9.9.2下载&使用教程:http://post.baidu.com/f?kz=40893628
FinC国人开发的嵌入式编程语言:http://post.baidu.com/f?kz=41127825
C语言的通讯录:http://post.baidu.com/f?kz=41627304
炸弹超人c语言简版:http://post.baidu.com/f?kz=37461531
求因子:http://post.baidu.com/f?kz=41674487
C语言中常见错误:http://post.baidu.com/f?kz=40525835
WPS Office 2005个人版免费下载:http://post.baidu.com/f?kz=41108925
TC2使用图解:http://post.baidu.com/f?kz=40504833
posted @
2007-12-06 21:36 MEYE 阅读(2955) |
评论 (2) |
编辑 收藏
[url:]http://www.yuanma.org/data/2006/1228/article_2024.htm
SkyEye是一个可以运行嵌入式操作系统的硬件仿真工具,这样就可以在没有硬件条件下来进行嵌入式系统的开发。
以下操作均在Fedora Core 1.0里通过。
Skyeye项目资源列表
http://gro.clinux.org/projects/skyeye/
文档摘要:
1、什么是SkyEye?
2、SkyEye可以做什么事情?
3、安装SkyEye
4、安装arm-elf交叉编译器
5、测试你的arm-elf-gcc编译器
6、执行你的hello程序
7、编译并运行uClinux-dist-20030909.tar.gz
8、加入网络功能
9、安装完成SkyEye后,下一步将做什么?
1、什么是SkyEye?
SkyEye
是开源软件的一个项目,SkyEye的目标是在Linux和Windows操作系统里提供一个完全的仿真环境。SkyEye仿真环境相当于一个嵌入式计算
机系统,你可以在SkyEye里运行一些嵌入式Linux操作系统,如ARMLinux,uClinux,uc/OS-II(ucos-ii)等,并能分
析和调试它们的源代码。
如果你想知道关于SkyEye和嵌入式系统更详细的信息,请访问下面的站点:
www.SkyEye.org
http://www.skyeye.org/index_cn.html
通过SkyEye能仿真下面的硬件:
CPU核心:ARM7TDMI, ARM720T, ARM9, StrongARM, XScale
CPU:
Atmel AT91/X40, Cirrus CIRRUS LOGIC EP7312, Intel SA1100/SA1110, Intel
XScale PXA 250/255, CS89712, samsung 4510B, samsung 44B0(还不全)
内存: RAM, ROM, Flash
周边设备: Timer, UART, ne2k网络芯片, LCD, 触摸屏等
目前能在SkyEye上运行下面的操作系统和系统软件:
uC/OSII-2.5.x(支持网络)
uClinux(基于Linux2.4.x内核, 支持网络)
ARM Linux 2.4.x/2.6.x
lwIP on uC/OSII
基于uC/OSII, uClinux, ARM Linux的应用程序
2.SkyEye可以做什么事情?
1. 通过SkyEye可以帮助促进嵌入式系统的学习,在不需要额外硬件的情况下学习和分析uclinux操作系统和其它嵌入式操作系统,如ucosII等。
2. SkyEye可用于嵌入式系统的教学。
3. 希望通过skyeye促进操作系统的研究,如ucosII,uclinux+RTAI,uclinux2.5.x等。
4. 可以基于SkyEye进行仿真特定硬件模块的研究。
5. SkyEye可以作为嵌入式集成开发环境开发嵌入式系统(当然需要对SkyEye做大量的工作)。
注:引自陈渝《SkyEye Project FAQ》
3、安装SkyEye
到
http://gro.clinux.org/projects/skyeye/下载skyeye-0.7.0.tar.bz2包:
tar jxvf skyeye-v0.7.0.tar.bz2
进入解压后的skyeye目录,如果SkyEye的版本低于0.6.0,则运行下面的命令:
./configure --target=arm-elf --prefix=/usr/local --without-gtk-prefix --without-gtk-exec-prefix --disable-gtktest
如果SkyEye的版本高于0.6.0,则运行下面的命令:
./configure --target=arm-elf --prefix=/usr/local
接下来执行:
make
make install
安装完成后执行skyeye
注意:
a.如果你使用的是Mandrake Linux发行版,那么你在编译SkyEye时遇到错误,并且错误与readline, ncurse, termcap等有关,你可以试试下面的方法:
ln -s /usr/include/ncurses/termcap.h /usr/local/include/termcap.h
接着再make和make install看能否成功!
b.如果你的Linux发行版是Debian Linux,那么不要使用gcc 2.95或是gcc 3.0,请使用gcc 3.2+
c.gcc的版本要在2.96或以上
d.如果SkyEye的版本大于0.6.0,那么使用LCD仿真需要在Linux系统里安装GTK软件。
4、安装arm-elf交叉编译器
下载arm-elf-tools-20030314.sh
ftp://166.111.68.183/pub/embed/uclinux/soft/tools/arm
或到
ftp://166.111.8.229/OS/Embeded
执行:
chmod a+x arm-elf-tools-20030314.sh
然后:
./arm-elf-tools-20030314.sh
ls /usr/local/bin/
你应能看到以arm-elf开头的可执行文件,其中arm-elf-gcc就是用来编译你目标平台的编译器的,当然还有一些小工具,后面将一一讲来。
5、测试你的arm-elf-gcc编译器
先写一个小程序hello.c
PHP代码:
#include <stdio.h>
int main(void)
{
int i;
for(i = 0; i < 6; i++){
printf("i = %d ",i);
printf("Hello, embedded linux!\n");
}
return 0;
}
|
然后执行:
arm-elf-gcc -Wl,-elf2flt -o hello hello.c
-elf2flt参数是将elf文件格式转为flat文件格式,这个工具是在你安装交叉编译器产生的。
或者你可以写个Makefile文件,执行:
make
这里是我的Makefile文件,仅供参考:
PHP代码:
# begin
CC = arm-elf-gcc
CFLAGS = -D__PIC__ -fpic -msingle-pic-base -O2 -pipe -Wall -g
LDFLAGS = -Wl,-elf2flt
LIBS =
OBJS = hello.o
all: hello
hello: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o hello $(OBJS) $(LIBS)
clean:
rm -rf *.o *.elf *.gdb hello
# end
|
如果编译通过,就会产生hello可执行文件。用下面的命令:
file hello
你会发现,它是BFLT(binary FLAT),你目标平台所支持的文件格式。
6、执行你的hello程序
这里,我们将借助genromfs这个小工具来完成测试,这个工具就是你在安装交叉编译器时产生的,你可以直接使用它。
到
http://gro.clinux.org/projects/skye...0.4.tar.bz2包:
tar jxvf skyeye-binary-testutils-1.0.4.tar.bz2
cd testsuits/at91/uclinux2(当然你还可以用别的)
mkdir romfs(建一个目录,后面用)
mount -o loop boot.rom /mnt/xxx
cp -r /mnt/xxx/* romfs
另外,把你编译好的可执行程序拷贝到/romfs/bin目录里,这里就是hello了!
genromfs -f boot.rom -d romfs/
注:可以用genromf -h来获得帮助!
OK!执行下面的命令:
skyeye linux
(skyeye)target sim
(skyeye)load
(skyeye)run
kernel start.....
很熟悉了吧。。。
cd /bin
hello
可以看到结果了吗?
其实到了这一步,你就可以开发自己的程序了!
7、编译并运行uClinux-dist-20030909.tar.gz
到
ftp://166.111.68.183/pub/embed/uclinux/soft/
或到
ftp://166.111.8.229/OS/Embeded/uclinux/pub/uClinux/dist下载
uClinux-dist-20030909.tar.gz
假设把它下载到/usr/src/目录下,然后依次执行下面的命令:
tar zxvf uClinux-dist-20030909.tar.gz
cd uClinux-dist/
在图形方式下可用命令make xconfig
或
在命令行方式下用命令make menuconfig
vendor/product中选择GDB/ARMulator
kernel版本选择2.4
然后save and exit
运行下面这两条命:
make dep
make
此时在/usr/src/uClinux-dist/linux-2.4.x目录下会生成可执行文件linux
在/usr/src/uClinux-dist/images/会生成romfs.img等文件
在uClinux-dist目录下建立仿真AT91的skyeye配置文件skyeye.conf,内容如下:
cpu: arm7tdmi
mach: at91
mem_bank: map=M, type=RW, addr=0x00000000, size=0x00004000
mem_bank: map=M, type=RW, addr=0x01000000, size=0x00400000
mem_bank: map=M, type=R, addr=0x01400000, size=0x00400000, file=images/romfs.img
mem_bank: map=M, type=RW, addr=0x02000000, size=0x00400000
mem_bank: map=M, type=RW, addr=0x02400000, size=0x00008000
mem_bank: map=M, type=RW, addr=0x04000000, size=0x00400000
mem_bank: map=I, type=RW, addr=0xf0000000, size=0x10000000
这个时候就可以用skyeye来调试运行kernel了,在/usr/src/uClinux-dist执行如下命令:
skyeye linux-2.4.x/linux
(skyeye)target sim
(skyeye)load
(skyeye)run
kernel start.....
注意:
要在skyeye.conf所在目录下执行skyeye linux-2.4.x/linux
8、加入网络功能
a.用root用户进行操作。
b.你要看你的/lib/modules/'uname -r'/kernel/drivers/net/目录里有没有tun.o
如果没有的话你就需要编译你的linux内核来获得tun.o了。
c.(1)运行tun设备模块:
#insmod /lib/modules/'uname -r'/kernel/drivers/net/tun.o
如果你没有该设备,那你就要用下面的命令来创建它:
#mkdir /dev/net
#mknod /dev/net/tun c 10 200
(2)运行vnet(虚拟集线器)设备模块(这一步不是必需的):
获取vnet的源码,然后创建设备:
#mknod /dev/net/vnet c 10 201
#chmod 666 /dev/net/vnet
创建vnet.o
#make vnet.o
插入模块vnet.o
#insmod vnet.o
进入test目录,用test来测度vnet.o
#cd test
#make
#./testvnet1
d.配置skyeye.conf文件
cpu: arm7tdmi
mach: at91
mem_bank: map=M, type=RW, addr=0x00000000, size=0x00004000
mem_bank: map=M, type=RW, addr=0x01000000, size=0x00400000
mem_bank: map=M, type=R, addr=0x01400000, size=0x00400000, file=images/romfs.img
mem_bank: map=M, type=RW, addr=0x02000000, size=0x00400000
mem_bank: map=M, type=RW, addr=0x02400000, size=0x00008000
mem_bank: map=M, type=RW, addr=0x04000000, size=0x00400000
mem_bank: map=I, type=RW, addr=0xf0000000, size=0x10000000
# format: state=on/off mac=xx:xx:xx:xx:xx:xx ethmod=tuntap/vnet hostip=dd.dd.dd.dd
net: state=on, mac=0:4:3:2:1:f, ethmod=tun, hostip=10.0.0.1
下面将对上面的一些参数作下说明:
state=on/off意思是仿真的NIC(网络接口板)是有线的还是无线的;
mac=仿真适配器的MAC地址;
ethmod=tuntap/vnet在主机环境里使用的虚拟设备;
hostip=意思是主机环境与keyeye交互用的IP
格式: state=on/off mac=xx:xx:xx:xx:xx:xx ethmod=tuntap/vnet hostip=dd.dd.dd.dd
For example:
#set nic info state=on/off mac=xx:xx:xx:xx:xx:xx ethmod=tuntap/vnet hostip=dd.dd.dd.dd
net: state=on, mac=0:4:3:2:1:f, ethmod=tun, hostip=10.0.0.1
或
net: state=on, mac=0:4:3:2:1:f, ethmod=vnet, hostip=10.0.0.1
注意:
如果你想在同一时刻运行两个或更多的skyeye,那么请为每一个skyeye使用不同的skyeye.conf
e.运行skyeye linux-2.4.x/linux
9、安装完成SkyEye后,下一步将做什么?
1、
对于嵌入式操作系统的初学者和入门者和入门的学生而言,他们可以先看一些有关操作系统和嵌入式操作系统方面的教材和书籍,如与uC/OS、Minix、
uClinux、Linux相关的书籍等。然后可以在Skyeye上开发一些简单的应用程序例子(如进程间通信、进程优先级、死锁情况、网络应用等),对
某些操作系统功能(如进程调度、内存管理、网络子系统、文件子系统等)进行简单的修改和扩展,并通过Skyeye进行运行和调试,看看会发生什么情况。
2、
对于有一定经验的软件工程师而言,在SkyEye上完成一定的应用系统原型开发是值得一做的事情。比如移植或开发一个文件子系统或网络子系统到一个特定的
操作系统中,相信比在一个真实的开发板上开发要容易一些。在Skyeye上进行一些操作系统的移植和开发(如移植RTLinux、RTAI等其它操作系统
到Skyeye上)也是很有挑战性的工作。
3、对于硬件工程师而言,对Skyeye进行扩充,设计新的硬件仿真(如USB、IDE硬盘等)使得Skyeye的硬件仿真功能更加强大,支持更多功能的软件,是很有意义的事情。
参考:
SkyEye项目站点里的一篇中文文档;
陈渝《SkyEye Project FAQ》;
skyeye-0.7.0中的README文档。
后记:
为了让大家能快速上手,进行实际的开发工作,我赶凑了一篇文档,很粗糙。但我坚信随着更多的有经验的人的加入;随着我们自己水平的提高,一定会出现更多、更好的文章来。就让我们快点行动起来吧!
最后,我再次建议大家看一下《嵌入式Linux技术与应用》这本书。
可以到
http://www.skyeye.org/document.htm或是
ftp://166.111.68.183/pub/embed/skyeye/document/或是
http://www.huihoo.org/mirrors/skyeye/
下载文档,可以获得更多有关skyeye和嵌入式Linux开发的知识和经验。
posted @
2007-12-06 20:09 MEYE 阅读(637) |
评论 (0) |
编辑 收藏