| Profilo di jiyu人生路漫漫,快乐先行FotoBlogElenchi | Guida |
|
28 maggio 迁移博客,欢迎大家访问 http://jiyu.wordpress.com.cn/博客迁移,欢迎大家访问 http://jiyu.wordpress.com.cn/ 新的blog关注python, Google App Engine, 奇思异想, webapplication, mobileapplication, javascript等 14 maggio 嵌入式程序员应知道的基本问题-C语言(zz)来源:21ICbbs 作者:lhf C语言测试:想成为嵌入式程序员应知道的0x10个基本问题 其中少量灰色的文字是我添加的,表达一些我的看法,很不成熟,希望朋友们指正。 C语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法。这些年,我既参加也组织了许多这种测试,在这过程中我意识到这些测试能为带面试者和被面试者提供许多有用信息,此外,撇开面试的压力不谈,这种测试也是相当有趣的。
1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
这个测试是为下面的目的而设的: least = MIN(*p++, b);
while(1) do{ ... } while (1) 一些程序员更喜欢如下方案: for(;;)
这个实现方式让我为难,因为这个语法没有确切表达到底怎么回事。如果一个应试者给出这个作为方案,我将用这个作为一个机会去探究他们这样做的基本原理。如果他们的基本答案是:“我被教着这样做,但从没有想到过为什么。”这会给我留下一个坏印象。 Loop:
数据声明(Data declarations) 5. 用变量a给出下面的定义 答案是: typedef int (*PFUNCTION)(int) PFUNCTION pfun; typedef int (*PFUNCTION)(int) PFUNCTION pfun[10];
7.关键字const有什么含意? const int a; /******/
8. 关键字volatile有什么含意?并给出三个不同的例子。 下面是答案:
long square(volatile int *ptr) 位操作(Bit manipulation) 9. 嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变。
void set_bit3(void) { 一些人喜欢为设置和清除值而定义一个掩码同时定义一些说明常数,这也是可以接受的。我希望看到几个要点:说明常数、|=和&=~操作。
10. 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。 int *ptr; A more obscure approach is: *(int * const)(0x67a9) = 0xaa55; 即使你的品味更接近第二种方案,但我建议你在面试时使用第一种方案。 中断(Interrupts) 11. 中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是,产生了一个新的关键字__interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。 __interrupt double compute_area (double radius) 这个函数有太多的错误了,以至让人不知从何说起了:
12 . 下面的代码输出是什么,为什么? void foo(void) 13. 评价下面的代码片断: unsigned int zero = 0; 对于一个int型不是16位的处理器为说,上面的代码是不正确的。应编写如下: unsigned int compzero = ~0; 这一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的经验里,好的嵌入式程序员非常准确地明白硬件的细节和它的局限,然而PC机程序往往把硬件作为一个无法避免的烦恼。 动态内存分配(Dynamic memory allocation) char *ptr; 所以在这个时候,一定要使用pc-lint来检察代码规范性,起码pc-lint能检查出if-else语句格式不对,要求开发人员对格式进行修改,那样的话,看起来就方便多了。 这是一个有趣的问题。最近在我的一个同事不经意把0值传给了函数malloc,得到了一个合法的指针之后,我才想到这个问题。这就是上面的代码,该代码的输出是“Got a valid pointer”。我用这个来开始讨论这样的一问题,看看被面试者是否想到库例程这样做是正确。得到正确的答案固然重要,但解决问题的方法和你做决定的基本原理更重要些。
#define dPS struct s * 以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么? dPS p1,p2; 第一个扩展为 struct s * p1, p2; . 晦涩的语法 16 . C语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么? int a = 5, b = 7, c; 这个问题将做为这个测验的一个愉快的结尾。不管你相不相信,上面的例子是完全合乎语法的。问题是编译器如何处理它?水平不高的编译作者实际上会争论这个问题,根据最处理原则,编译器应当能处理尽可能所有合法的用法。因此,上面的代码被处理成: c = a++ + b; 因此, 这段代码持行后a = 6, b = 7, c = 12。 让你明白什么是ERP(zz)ERP(Enterprise Resource Planning)企业资源计划系统,是指建立在信息技术基础上,以系统化的管理思想,为企业决策层及员工提供决策运行手段的管理平台。 一天中午,丈夫在外给家里打电话:"亲爱的老婆,晚上我想带几个同事回家吃饭可以吗?"(订货意向) 妻子:"当然可以,来几个人,几点来,想吃什么菜?" 丈夫:"6个人,我们7点左右回来,准备些酒、烤鸭、番茄炒蛋、凉菜、蛋花汤......。你看可以吗?"(商务沟通) 妻子:"没问题,我会准备好的。"(订单确认) 妻子记录下需要做的菜单(MPS计划),具体要准备的东西:鸭、酒、番茄、鸡蛋、调料......(BOM物料清单),发现需要:1只鸭蛋,5瓶酒,4个鸡蛋......(BOM展开),炒蛋需要6个鸡蛋,蛋花汤需要4个鸡蛋(共用物料)。 打开冰箱一看(库房),只剩下2个鸡蛋(缺料)。 来到自由市场,妻子:"请问鸡蛋怎么卖?"(采购询价) 小贩:"1个1元,半打5元,1打9.5元。" 妻子:"我只需要8个,但这次买1打。"(经济批量采购) 妻子:"这有一个坏的,换一个。"(验收、退料、换料) 回到家中,准备洗采、切菜、炒菜......(工艺线路),厨房中有燃气灶、微波炉、电饭煲......(工作中心)。妻子发现拨鸭毛最费时间(瓶颈工序,关键工艺路线),用微波炉自己做烤鸭可能来不及(产能不足),于是阅览室在楼下的餐厅里买现成的(产品委外)。 下午4点,电话铃又响:"妈妈,晚上几个同学想来家里吃饭,你帮忙准备一下。"(紧急订单) "好的,你们想吃什么,爸爸晚上也有客人,你愿意和他们一起吃吗?" "菜你看着办吧,但一定要有番茄炒鸡蛋,我们不和大人一起吃,6:30左右回来。"(不能并单处理) "好的,肯定让你们满意。"(订单确定) 鸡蛋又不购了,打电话叫小贬送来。(紧急采购) 6:30,一切准备就绪,可烤鸭还没送来,急忙打电话询问:"我是李太,怎么订的烤鸭还不送来?"(采购委外单跟催) "不好意思,送货的人已经走了,可能是堵车吧,马上就会到的。" 门铃响了。"李太太,这是您要的烤鸭。请在单上签一个字。"(验收、入库、转应付账款) 6:45,女儿的电话:"妈妈,我想现在带几个朋友回家吃饭可以吗?"(呵呵,又是紧急订购意向,要求现货) "不行呀,女儿,今天妈已经需要准备两桌饭了,时间实在是来不及,真的非常抱歉,下次早点说,一定给你们准备好。"(哈哈,这就是ERP的使用局限,要有稳定的外部环境,要有一个起码的提前期) 送走了所有客人,疲惫的妻子坐在沙发上对丈夫说:"亲 爱的,现在咱们家请客的频率非常高,应该要买些厨房用品了(设备采购),最好能再雇个小保姆(连人力资源系统也有接口了)。 丈夫:"家里你做主,需要什么你就去办吧。"(通过审核) 妻子:"还有,最近家里花销太大,用你的私房钱来补贴一下,好吗?"(最后就是应收货款的催要) 现在还有人不理解ERP吗?记住,每一个合格的家庭都是生产厂长的有力竞争者! 07 maggio 关于汇编语言内存寻址方式浅析(转)指令操作数的寻址方式
一、与数据有关,寻找参加操作的数据(8种---->7种基本方式+字符串寻址) ★涉及的一些概念 DISP/16位:AX(累加器),BX(基侄寄存器),CX(计数器),DX(数据与地址寄存器),SP(堆栈指针),BP(基址指针),SI(源变址器),DI(目的变址器) DISP/8位:AH(高8位),AL(低8位),BH,BL,CH,CL.DH,DL IP指令指针,存放代码段中的偏移地址;EA偏移地址,段内相对地址,有效地址 CS代码段,SS堆栈段,DS数据段,ES附加段 堆栈:方便事项程序要求保留和恢复有关信息的特殊存储部件,是一种数据结构。 pws(状态):CF(进位),PF(奇偶),SF(符号),OF(溢出),ZF(零),DF(方向),IF(中断),TF(跟踪) PA:20位物理地址 ;MOV传送 1、立即寻址 用来表示常数 MOV AX,1946H;1946H(立即数)-->AX 2、寄存器寻址 MOV AX,CX ;cx-->ax 3、直接寻址 MOV BX,[1000H] ;[1000H]→EA,操作数默认DS MOV AX,ES:VAR ;越段前缀 4、寄存器间接寻址 EA=BX∨SI∨DI∨BP;∨表示或者 a、PA=DS×16+{BX∨SI∨DI} b、PA=SS×16+BP c、PA=越段寄存器×16+{BX∨SI∨DI∨BP} 5、寄存器相对寻址 直接变址寻址 ┍BX┑ EA=├SI┥+{DISP} ├DI┥ ┕BP┚ mov ax,count[si] ;ea=count+si,(ea)→ax,约定为DS mov al,es:string[bp] ;越段前缀 6、基址变址寻址 使用数组和表格 EA={BX∨BP}+{SI∨DI} pA=DS×16+BX+{SI∨DI} pA=SS×16+BP+{SI∨DI} mov cx,es:[bx][di] mov ax,[bx][si] ;ea=bx+si,ea→ax 7、相对基址变址寻址 EA={BX∨BP}+{SI∨DI}+{DISP} mov ax,array[bx][si] ;ea=array+bx+si,ea→ax 8、字符串寻址 movsb ;([si])=>([di]),si+1=>si,di+1=>di ;源=>目,可理解为mov [di],[si] 我对寻址的一些分析看看对大家对他的理解有没有帮助。 物理地址(PA)=段地址+偏移地址(EA) =段寄存器的内容×16+偏移地址 =约定默认段地址×16+偏移地址 =越段地址×16+偏移地址 1、立即寻址 A→B,A就是PA(物理地址)可以直接给B 2、寄存器寻址 A→B,A(寄存器)的值是PA可以给B 3、直接寻址 A→B,A是EA,EA=确定的寄存器的值,由EA得到PA,然后给B 4、寄存器间接寻址 A→B,A是EA,EA=变动的寄存器的值,由EA得到PA,然后给B 5、寄存器相对寻址 A→B,A是EA,EA=变动的寄存器的值+DISP的值,由EA得到PA,然后给B 6、基址变址寻址 A→B,A是EA,EA=变动的寄存器的值+另一变动的寄存器的值,由EA得到PA ,然后给B 7、相对基址变址寻址 A→B,A是EA,EA=变动的寄存器的值+另一变动的寄存器的值+DISP的值, 由EA得到PA,然后给B 8、字符串寻址 A→B,A源PA,然后给B(目的pA) 理解寻址方式的关键是EA的值是什么和怎样由EA得到PA,方式4,5,6,7容易混淆,我这样解释可能不科学,但能达到明白它的意思就行。4和3的区别是EA=变动的寄存器的值,5在4的基础上加了DISP的值,6相当于2个5相加(EA=变动的寄存器的值+另一变动的寄存器的),7相当于5+6,哈哈,都什么和什么呀。 06 maggio 让Editplus支持汇编语言语法高亮显示-- 2006.5.6 By A.TNG
最近在看汇编,发现好多知识都还给老师了,得恶补回来。写了几行代码,发现SourceInsight感觉好不爽,还是用回最喜欢的Editplus。不过突然发现ep不支持汇编语言的语法高亮显示,很是郁闷,心想,如此强大的ep怎能如此弱,找了找ep的各个设置,发现在:工具-〉参数设置-〉文件-〉设置和语法 中有个可以设置语法高亮显示的选项,里头已经有了:cpp css html java js jsp ...。马上在网搜索了一个ASM的语法高亮设置,贴出来,分享一下,同时也感谢原作者的工作。
所需要做的是,打开ep,至对应的设置面板,选择添加,在描述中输入:ASM,在文件扩展名中输入:asm,然后在语法文件一栏选择对应的stx文件就好了。(asm的stx文件,就是把下面的东东保存为you_decide_the_name.stx)
#TITLE=ASM
; ASM syntax file written by kylin. ; This file is required for EditPlus to run correctly. #DELIMITER=,(){}[]-+*/=~!&|<>?:.
#QUOTATION1=' #QUOTATION2=" #CONTINUE_QUOTE=n #LINECOMMENT=; #ESCAPE=\ #CASE=y #PREFIX3=$ #PREFIX4=@ #PREFIX5=% #NUMBER_PATTERN=asm #SPECIAL_STX=asm #KEYWORD=Reserved words
db dw dd dq mov movsx movzx xchg push pusha pushad pop popa popad in out xlat lea lds les lfs lgs lss lahf sahf pushf pushfd popf popfd add sub adc sbb inc dec mul div imul idiv cbw cwd cwde cdq cmp neg daa das aaa aas aam aad and or xor not test shl sal rol ror rcl rcr shld shrd movs movsb movsw movsd cmps cmpsb cmpsw cmpsd scas scasb scasw scasd lods lodsb lodsw lodsd stos stosb stosw stosd ins insb insw insd outs outsb outsw outsd jmp jc jnc jz je jnz jne js jns jo jno jp jpe jnp jpo ja jneb jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jcxz jecxz loop loopz loope loopnz loopne ret retn retf int into iret iretd set clc stc cmc cld std cli sti hlt wait esc lock nop bt btc btr bts bsf bsr bound enter leave lar lsl lgdt lidt sgdt sidt ltr str lmsw smsw lldt sldt arpl clts verr verw DW DD DQ MOV MOVSX MOVZX XCHG PUSH PUSHA PUSHAD POP POPA POPAD IN OUT XLAT LEA LDS LES LFS LGS LSS LAHF SAHF PUSHF PUSHFD POPF POPFD ADD SUB ADC SBB INC DEC MUL DIV IMUL IDIV CBW CWD CWDE CDQ CMP NEG DAA DAS AAA AAS AAM AAD AND OR XOR NOT TEST SHL SAL ROL ROR RCL RCR SHLD SHRD MOVS MOVSB MOVSW MOVSD CMPS CMPSB CMPSW CMPSD SCAS SCASB SCASW SCASD LODS LODSB LODSW LODSD STOS STOSB STOSW STOSD INS INSB INSW INSD OUTS OUTSB OUTSW OUTSD JMP JC JNC JZ JE JNZ JNE JS JNS JO JNO JP JPE JNP JPO JA JNEB JAE JNB JB JNAE JBE JNA JG JNLE JGE JNL JL JNGE JLE JNG JCXZ JECXZ LOOP LOOPZ LOOPE LOOPNZ LOOPNE RET RETN RETF INT INTO IRET IRETD SET CLC STC CMC CLD STD CLI STI HLT WAIT ESC LOCK NOP BT BTC BTR BTS BSF BSR BOUND ENTER LEAVE LAR LSL LGDT LIDT SGDT SIDT LTR STR LMSW SMSW LLDT SLDT ARPL CLTS VERR VERW #KEYWORD=Register flat stdcall casemap none dup proto call local invoke eax ax ah al ebx bh bl bx ecx cx ch cl edx dx dh dl esi si edi di ebp bp esp sp carry overflow parity sign zero true false FLAT STDCALL CASEMAP NONE DUP PROTO CALL LOCAL INVOKE EAX AX AH AL EBX BH BL BX ECX CX CH CL EDX DX DH DL ESI SI EDI DI EBP BP ESP SP CARRY OVERFLOW PARITY SIGN ZERO TRUE FALSE #KEYWORD=Statements
386 model option data const stack code proc endp struc ends end include includelib if else elseif endif while endw repeat break continue until null 386 MODEL OPTION DATA CONST STACK CODE PROC ENDP STRUC ENDS END INCLUDE INCLUDELIB IF ELSE ELSEIF ENDIF WHILE ENDW REPEAT BREAK CONTINUE UNTIL NULL #KEYWORD=Description
ds cs es ss fs gs addr offset byte word dword ptr DS CS ES SS FS GS ADDR OFFSET BYTE WORD DWORD PTR #KEYWORD=Symbols
= : @ ( ) , . ; / + - * % # 01 maggio 今天才知道,一个磁盘的扇区大小为512B软盘、硬盘都是这样,那么来说,处理起来是一样的。 不过又看到一则新闻,稍微老一些,2006-3-26。 德国IT新闻网站Golem.de报道,“国际磁盘驱动器、器材及原料协会”(IDEMA)已经同意将硬盘扇区大小由目前的512Byte增加到4096Byte,这将导致硬盘存储密度和容量的进一步提升。 该报道称更大的扇区可以实现更健全的错误修正机制。采用4KB扇区的硬盘将在今年晚些时候上市,但目前我们还没有哪些厂商将推出这种硬盘及其容量大小的消息。 世界变化就是快啊。 29 aprile Petri网简介(转载) Petri网是对离散并行系统的数学表示。Petri网是1960年代由卡尔·A·佩特里发明的,适合于描述异步的、并发的计算机系统模型。Petri网既有严格的数学表述方式,也有直观的图形表达方式,既有丰富的系统描述手段和系统行为分析技术,又为计算机科学提供坚实的概念基础。
如果一个变迁的每个输入库所(input place)都拥有令牌,该变迁即为被允许(enable)。一个变迁被允许时,变迁将发生(fire),输入库所(input place)的令牌被消耗,同时为输出库所(output place)产生令牌。
一个经典的Petri网由四元组(库所,变迁,输入函数,输出函数)组成。任何图都可以映射到这样一个四元组上,反之亦然。 一个流程的状态是由在场所中的令牌建模的,状态的变迁是由变迁建模的。令牌表示事物(人,货物,机器),信息,条件,或对象的状态; 库所代表库所,通道或地理位置;变迁代表事件,转化或传输。 一个流程有当前状态,可达状态,不可达状态。
为了解决经典Petri网中的问题,研究出了高级Petri网,在以下方面进行了扩展:
Petri网的应用非常广泛,以下是Petri网比较常用的几种应用:
彩信之我见-- 2006.4.28 By A.TNG
爱立信、诺基亚、摩托罗拉、西门子、阿尔卡特、朗讯、北电、华为和中兴,哪家不是世界巨头,哪家不令各大学高材生趋之若鹜。她们都是属于电信行业。因此,就算是进了排名最后的中兴,“挨起踢”来,都让人觉得舒服,或者说,人家放个屁都是香的。 完了,跑题了。最后跑一句:珍爱生命,远离中·华·。 2、关于彩信。 还有一点,就是觉得彩信组的人都是大牛,人也特别好,感觉好亲切:) 3、说说彩信 然后是网络支持不够,凭借现在2G的网络或者是CDMA的网络,对于发送小的彩信,还是不错的,来个小图片,来段短声音,都还凑活。但是据彩信组的大牛们说,在现在GPRS的网络上,超过80K的彩信,就极有可能发送不成功;移动的兄弟们说,我们的GSM网络就支持100K的数据,超过这个量,说断就断,不会事先跟你打招呼的。其实啊,各大厂商也就是把宝压在了3G的网络上头,在那个上头发彩信,感觉爽极了。 说实话,彩信还有有她的缺陷,在能发送的情况下,彩信中心是不会保存发送的彩信的,因为她不是一个邮件服务器,不过她也有很有趣的地方,彩信可以通过网关,并且重新编码,发到用户的邮箱里头。 彩信发到邮箱,需要各个方面的支持,网关需要支持,能对彩信进行解码和MIME封装,需要支持SMTP把彩信发到邮件服务器上,用户的客户端(Outlook和Foxmail)把彩信型邮件接收下来,也需要显示上的支持,不过我试过Outlook Express 6.00.2800.1807和Foxmail 5.0.800.0都不支持对SMIL的解析,所以也完全没有达到显示彩信的效果。唉,其实也很惭愧,我觉得既然OE和Foxmail都不支持,我们做的东西也不需要支持那么好,照着葫芦画瓢就好了。 4、个人感觉 个人感觉,邮件这个东西,发展到现在,很多方面都很完善了,ESMTP、POP3、IMAP4和MIME这些协议都有比较稳定的代码支撑着,可是邮件和手机结合的同时,要充分考虑手机的特点,手机在控制性和显示方面都有天生的缺陷,因此在显示邮件时,如何充分的利用MIME协议的特点,并且最大限度的满足用户的需求,才是难点。其实显示邮件方面Lotus Notes感觉是做得最好的,而OE和Foxmail要差一些。 28 aprile 十八点(转载)一、读大学,究竟读什么? 大学生和非大学生最主要的区别绝对不在于是否掌握了一门专业技能……一个经过独立思考而坚持错误观点的人比一个不假思索而接受正确观点的人更值得肯定……草木可以在校园年复一年地生长,而我们却注定要很快被另外一群人替代……尽管每次网到鱼的不过是一个网眼,但要想捕到鱼,就必须要编织一张网…… 二、人生规划:三岔路口的抉择 不走弯路就是捷径……仕途,商界,学术。在这人生的三岔路口,你将何去何从……与其跟一百个人去竞争五个职位,不如跟一个人去竞争一个职位……学术精神天然的应当与尘嚣和喧哗保持足够的距离……商场不忌讳任何神话。你也完全可能成为下一个传奇…… 三、专业无冷热,学校无高低 没有哪个用人单位会认为你代表了你的学校或者你的专业……既然是概率,就存在不止一种可能性……如果是选择学术,冷门专业比热门专业更容易获得成就……跨专业几乎早已成为一种流行一种时尚……大学之间的实力之争到了考研考场和人才市场原来是那样的微不足道…… 四、不可一业不专,不可只专一业 千招会,不如一招熟……十个百分之十并不是百分之百,而是零……在这个现实的社会,真正实现个人价值才是最体面最有面子最有尊严的事情……要想知道需要学什么,最好的方式就是留意招聘信息……很多专业因为不具备专长的有效性,所以成为了屠龙之术……为什么不将“买一送一”的促销思维运用到求职应聘的过程中来呢…… 五、不逃课的学生不是好学生 什么课都不逃,跟什么课都逃掉没什么两样……读大学,关键是学会思考问题的方法……逃课没有错,但是不要逃错课……英语角绝对不是学英语的地方……为了英语丢了专业,那就舍本逐末了……招聘单位是用人才的地方,而不是培养人才的地方……既要逃课,又要让老师给高分…… 六、勤工俭学的辩证法 对于贫困生来说,首先要做的不是挣钱,而是省钱……大部分女生将电脑当成了影碟机,大部分男生将电脑当成了游戏机……在这个处女膜都可以随意伪造的年代,还有什么值得轻易相信……态度决定一切……当学习下降到次要的地位,大学生就只能说是兼职的学生了…… 七、做事不如做人,人脉决定成败 学问好不如做事好,做事好不如做人好……会说话,就能减少奋斗三十年……一个人有多少钱并不是指他拥有多少钱的所有权,而是指他拥有多少钱的使用权……一个人赚的钱,12.5%是靠自身的知识,87.5%则来自人脉关系……三十岁以前靠专业赚钱,三十岁以后拿人脉赚钱……你和世界上的任何一个人之间只隔着四个人…… 八、互联网:倚天剑与达摩克利斯之剑 花两个小时就写出一篇天衣无缝的优秀毕业论文……在互联网领域创业的技术门槛并不高,关键的是市场眼光和营销能力……轻舞飞扬已经红颜薄命了,而痞子蔡却继续跟别的女孩发生着一次又一次的亲密接触……很多大学生的网友遍布祖国大江南北,可他们却从未主动向周围的人说一声:你好,我们可以聊聊吗…… 九、恋爱:花开堪折方须折 爱情是不期而至的,可以期待,但不可以制造……越是寂寞,越要警惕爱情……既然单身是可耻的,那西门庆是不是应该被评为宋朝十大杰出青年……花开堪折方须折,莫让鲜花败残枝……一个有一万块钱的人为你花掉一百元,你只占了他的百分之一;而一个只有十块钱的人为你花掉十块,你就成了他的全部…… 十、性:上帝死了,众神在堕落 爱要说,爱要做……我只有在肉体一下一下的撞击中才感到快乐。经过之后,将是更大的寂寞更大的空虚……为何要让别人的虚荣成为对自己的伤害……当她机械地躺在床上张开双腿,她的父母正在憧憬着女儿的未来……一朝春尽红颜老,花落人亡两不知…… 十一、考研:痛苦的安乐死 没有比浪费青春更失败的事情了……研究生扩招的速度是30%,也就意味着硕士学历贬值的速度是30%……同样是付出三年的努力,你可以让E1的值增加1,也可以让E2的值增加2甚至增加3……读完硕士或博士并不等于工作能力更强……面对13.54万的成本,你还会毫不犹豫地投资读研究生吗……努力就会有结果,但不一定是好结果…… 十二、留学:“海龟”变“海带” 月薪2500元的工作,居然引得三个“海归”硕士争相竞聘……对于某些专业而言,去美国留学和去埃塞俄比亚留学没什么两样……既然全世界的公司都想到中国的市场上来瓜分蛋糕,为什么中国人还要一门心思到国外去留学然后给外国人打工…… 十三、非统招:养卑照样处优 她在中国信息产业界创下了几项纪录。她被称为中国的“打工皇后”。而她不过是一名自考大专生……要想把曾经输掉的东西赢回来,就必须把自己比别人少付出的努力补上来……非统招生不但要有一定的实力,而且必须掌握一定的技巧,做到扬长避短出奇制胜……路在脚下。好走,走好…… 十四、毕业:十面埋伏的陷阱 母校不把自己当母亲,你又何必把自己当儿女……听辅导班不过是花钱买踏实……人才市场就是一个地雷阵……通过多种方式求职固然没有错,但是千万不要饥不择食……只要用人单位一说要你交钱,你掉头就走便是了……这年头立字尚且不足以为据,更何况一个口头约定…… 十五、求职:做人不要太厚道 求职简历必须突出自己的核心竞争力……求职的时候大可不必像严守一那样“有一说一”……一个人说假话并不难,难的是把假话说到底,并且不露一丝破绽……在填写自己的特长时,一定要尽可能详细……一份求职简历只要用一张A4纸做个表格就足够了……面试其实是有规律的,每次面试的时候只要背标准答案就行了…… 十六、骑一头能找千里马的驴 美国铁路两条铁轨之间的标准距离是4英尺8.5英寸,为什么呢?因为两匹马臀部之间的宽度是4英尺8.5英寸……垃圾是放错位置的人才……世界上最大的悲剧莫过于有太多的年轻人从来没有发现自己真正想做什么……中小型企业或许能够让你得到更充分的锻炼……从基层做起并不意味着可以从基层的每一个职位做起……要“钱途”,更要前途…… 十七、写字楼政治:白领必修课 大公司是做人,小公司是做事……职员能否得到提升,很大程度不在于是否努力,而在于老板对你的赏识程度……公司的事情和秘密永远比你想象的还要复杂和深奥……在适当的时候装糊涂不但是必要的,而且是睿智的……就把你的同事当成一群你可以叫得出名字的陌生人好了…… 十八、创业:29岁以前做富翁 瘦死的骆驼比马大……撑死胆大的,饿死胆小的……不再是“大鱼吃小鱼”,而是“快鱼吃慢鱼”……对于趋势的把握是一个创业者最重要的能力……高科技行业留给毕业生的空间已经很小……欲速则不达。在创业以前通过给别人打工而积累经验是非常必要的……市场永远比产品更重要……钱不够花,怎么办?第一,看菜吃饭;第二,借鸡生蛋…… 27 marzo 2006-3-25 太湖鼋头渚 真是天公作美,知道我们要去仙界和诸仙交流,所以太阳特别的好。过了会仙桥,各位都成了神仙了,一路游山玩水,好不快活。
不过就是时间太短了,还有就是其他人手艺不太好,把我照得比较搓,见谅,见谅。
27 febbraio 风雨夜上海----2006.2.26
偷偷的写这个日志,身边都是领导,最大的领导就在我旁边。所以尽量废话少说。
昨天晚上去游了夜上海,在老大的带领下。不过很多的不凑巧,比较忙,导致精神不振;风大,导致形象不佳;人多,上海太大了,简直就不能算是一个城市了。不过总归来说,玩得还是很高兴得,到处都看了,终于知道,什么是国际型大都市了。大家凑活着看吧。 09 febbraio 人生规划:20岁到60岁我该干什么(zz) 一个人的职业生涯,贯穿一生,是一个漫长的过程。科学地将其划分为不同的阶段,明确每个阶段的特征和任务,做好规划,对更好地从事自己的职业,实现确立的人生目标,非常重要。
职业生涯阶段如何划分,各国专家学者有不同的划分理论和方法,主要可分为按年龄层次划分、按专业层次划分和按管理层次划分三种类型。
我国从事职业生涯规划研究的人事人才科学研究所副研究员罗双平认为:以年龄为依据,每十年作为一个阶段比较合适,即二十岁至三十岁为一个阶段,三十岁至四十岁为一个阶段,依次类推。我们每个人都要经历这几个阶段,那么你现在该做些什么呢?罗双平谈了他的看法,供读者朋友参考。 二十岁至三十岁:走好第一步
这一阶段的主要特征,是从学校走上工作岗位,是人生事业发展的起点。如何起步,直接关系到今后的成败。
这一阶段的主要任务之一,就是选择职业。在充分做好自我分析和内外环境分析的基础上,选择适合自己的职业,设定人生目标,制定人生计划。再一个任务,就是要树立自己良好的形象。年轻人步入职业世界,表现如何,对未来的发展影响极大。有些年轻人,特别是刚毕业的大学生,总认为自己有知识,有文化,到单位工作后不屑于做零星小事,不能给同事们留下良好的印象,这对一个年轻人的发展而言,可以说是一个危机。还有一个重要任务,就是要坚持学习。根据日本科学家研究发现,人一生工作所需的知识,90%是工作后学习的。这个数据足以说明参加工作后学习的重要性。
三十岁至四十岁:不可忽视修订目标
这个时期是一个人风华正茂之时,是充分展现自己才能、获得晋升、事业得到迅速发展之时。此时的任务,除发奋努力,展示才能,拓展事业以外,对很多人来说,还有一个调整职业、修订目标的任务。人到30多岁,应当对自己、对环境有了更清楚的了解。看一看自己选择的职业、所选择的生涯路线、所确定的人生目标是否符合现实,如有出入,应尽快调整。
四十岁至五十岁:及时充电
这一阶段,是人生的收获季节,也是事业上获得成功的人大显身手的时期。对于到了这个年龄仍一无所得、事业无成的人应深刻反省一下原因何在?重点在自身上找原因,对环境因素也要做客观分析,切勿将一切原因都归咎于外界因素,他人之过。只有正确认识自己,找出客观原因,才能解决人生发展的困阻,把握今后的努力方向。
此阶段的另一个任务是继续充电。很多人在此阶段都会遇到知识更新问题,特别是近年来科学技术高速发展,知识更新的周期日趋缩短,如不及时充电,将难以满足工作需要,甚至影响事业的发展。
五十岁至六十岁:做好晚年生涯规划
此阶段是人生的转折期,无论是在事业上继续发展,还是准备退休,都面临转折问题。由于医学的进步,生活水平的提高,很多人此时乃至以后的十几年,都能身体健康,照样工作,所以做好晚年生涯规划十分重要。日本的职工一般是45岁时,开始做晚年生涯规划;美国是50岁时做晚年生涯规划。我国的职工按退休年龄提前5年做晚年生涯规划即可。
主要内容应包括以下几个方面:一是确定退化后的二三十年内,你准备干点什么事情,然后根据目标,制定行动方案;二是学习退休后的工作技能,最好是在退休前三年开始着手学习;三是了解退休后再就业的有关政策;四是寻找工作机会。目前我国已有离退休人员的人才职业介绍所,可提前与这些部门联系,取得他们的帮助。 人生规划,一个研究生的回顾(zz) 我今年39岁了, 25岁研究生毕业,工作14年,回头看看,应该说走了不少的弯路,有一些经验和教训。现在开一个小公司,赚的钱刚够养家糊口的。看看这些刚毕业的学生,对前景也很迷茫,想抛砖引玉,谈谈自己的看法,局限于理工科的学生,我对文科的不懂,身边的朋友也没有这一类型的。 91年研究生毕业,那时出路就是1种:留在北京的国营单位,搞一个北京户口,这是最好的选择。到后来的2~3年内,户口落定了,又分成4条出路: 1、 上国内的大企业,如:华为 2、 自己做公司,做产品开发; 3、 上外企,比如:爱立信、诺基亚 4、 自己做公司,做买卖; 5、 移民加拿大 我想,首先要看自己适合做什么?做技术还是做买卖。 做技术,需要你对技术感兴趣。我掰着数了一遍,我们研究生班的30来号人,实际上 ,适合做技术的,大概只有3、4个人,这几个人,1个现在还在华为,3个移民加拿大了,现在这4个人混的还可以,在华为的同学也移民加拿大了,他在华为呆了6年,在华为奖金工资加起来大概30万吧,还有华为的股票,再过几年,华为的股票一上市,也能值个100~200万。要是一毕业就去华为,那现在就绝对不是这个数字了。 要是做技术,最好的就是上大公司,国内的大型企业,象华为中兴肯定是首选,能学到很多东西。华为虽然累,但是,年轻人不能怕累,要是到老了,还需要去打拼,那才是真的累啊。 在外企,我想他们主要就是技术支持和销售,但是技术是学不到的,当然不能一概而论,我指的是象爱立信和诺基亚,真正的研发不会在中国做的,学到的也不如在华为多,其它的中兴我不是很了解,我想应该也不错啊。 一个人都有一技之长,有傍身之技,那是最好的,走到哪里,都能有一口饭吃,还吃的不错,这是传统的观点。 任何技术都是要在某个行业去应用,这个行业市场越大当然越好;要在一个领域之内,做深做精,成为绝对的专家,这是走技术道路的人的选择。不要跳来跳去,在中国,再小的行业你要做精深了,都可以产生很大的利润。 研究生刚毕业的时候,做产品开发的有不少人,都是自己拍拍脑子,觉得这个产品有市场,就自己出来做。现在看来,我的这些同学,做产品开发的成功的没有一例,为什么?资源不足。 1. 资金,刚毕业的学生啊,就是没钱;没钱,也意味着你开发的东西都是小产品;而且只能哥几个自己上,研发、生产、销售都是一个人或者几个人自己来,没有积累,什么都是重新来过。 2. 人脉,任何一个行业,要想进去,需要有很深的人脉,否则,谁会用你的东西啊?谁敢用你的东西啊? 我看到的,我这个班上开发产品的,自己还在坚持的,只剩下一个人了,说实在的,到现在,没有自己的汽车,也没有自己的房子,混的挺惨的。现在出国的不说了,在外企、在华为,至少都是几十万的年薪了,还有各种福利,就是产品开发成功了,又能如何?也就是这样了,但是以前那些年,都没有金钱的积累,等于白干。 我身边的一个自动化系的研究生班的同学,能靠自己开发产品活得还可以的,也只有2个人。说明这条路不是那么好走的啊。 其次就是上外企。我的2个同学,一个上了爱立信,一个先到爱立信后到诺基亚,都混的不错。到诺基亚的后来利用在诺基亚结识的人脉(就是哪些电信的头头脑脑),自己开了公司,也赚了不少的钱。 外企最大的好处就是除了能学到比较规范的管理外,还能给你的职业生涯镀金。到了一个外企外,再到同行业的外企我想就很容易了。而且外企的收入高啊。 自己做公司,做买卖,一开始有3~4个人走这条路,但是真正发财的只有一个人,其 他人后来上外企了。做买卖,还是要有一定的天赋,还有机遇。要有对金钱的赤裸裸的欲望,要有商业上的头脑。后来我们同学在一起谈,说,我们即使给自己这个机遇,也未必能做的好。何况当时那个同学看好的产品(做一个台湾产品的代理),我们大家都没有看好,说明,真理还是掌握在少数人手里。 到后来,同学们纷纷移民移民加拿大。 移民加拿大对搞技术的人来说,还是一个不错的选择,但是要尽早,练了几年的技术,就赶紧出去,大概是在1996年走了不到10个,现在都还可以,买了房子和车了。要是晚了,语言再学也难了,而且在国内都混的还可以了,也就没有必要出去了。 我自己呢,先是在国营的研究所混了4年,后来到一家公司干了6年,2002年出来自己做公司,现在也就是混了一个温饱吧,算是有房有车,有点积蓄,但是不多,还有一个可爱的女儿。回首这10来年,有一些经验和教训。 1. 要有一个职业生涯的规划。首先需要定位自己做什么合适,是做买卖还是做技术,一条路走到黑;当然,做了技术,后来改行也行; 2. 做技术,就是要做精做深,成为这个行业的这个技术的专家;最好就是去国内的大公司,才能全面学到东西,能够给你培训的机会;如果大公司进不去,先到小公司练技术,找机会再到大公司去镀金,学高深的技术。千万不要自己做产品,要做也是对这个行业熟悉了,再去做。 3. 积极争取机会。积极争取学习和进步的机会。比如,做技术,就需要多锻炼,多学习,来提高自己的水平。一门技术,只要有机会去学习,都能学的会;要是没有机会,天才也没有办法学到这个技术。柳传志就说,杨元庆就是"哭着喊着要进步",实际上,就是争取自己的机会;当然,这种强烈的进步欲望,也是领导看重的地方。每一步都走在前面,积累10年,你就有了比其他人更多的机会了。 4. 积累个人的信誉。从你的职业生涯的第一天,就要按照诚信的原则办事。要做到,当人们提起你的名字的时候,说,这哥们还不错,做事还行。 5. 注意利用资源。如果你有有钱的亲戚、成功的长辈或者朋友,可以充分利用这些机会,得到更加顺利的发展前景。 6. 注意财富的不断积累。人生要想得到自由,财富是很关键的。否则,永远仰人鼻息,永远看人脸色。人都是势利眼。今后的家庭、职业生涯,金钱的积累很重要,没有钱,永远不能开张自己的事业,得到更多的机会;财富要做到逐年积累,你才能家庭生活幸福。没有钱是不可能有幸福的家庭的。 7. 注意人脉的积累。最终,事业要靠在社会上的人脉的资源。要注意认识在你这个行业的人,结交他们,最终他们会成为你事业上的助力。 8. 寻求贵人相助。要找大老板来帮助你,得到大老板的赏识。想想看,大蛋糕,切一点就够了,小蛋糕,都给你也吃不饱啊。 9. 多听听成功的前辈和成功的朋友的意见。注意少听家里长辈的意见,尤其是都已经退休的长辈,他们对社会的认识还停留在很久以前,而这个社会已经发生很大的变化呢。最重要的是,长辈有时候会强求你做一些事情,但是,最终的结果他们是不负责的。只有你才能对自己负责。 欢迎朋友们都能提出自己的看法。 如何正确的进行人生规划(zz) 20岁以前,大部份的人是相同的,升学读书升学读书...,建立自己基础。在父母亲友,社会价值观影响及误打误撞的情况下完成基本教育。 选择读书,应该一鼓作气,在您尚未进入产业时,能读多高就多高,毕竟何时进入产业,您都是社会新鲜人。 但是一旦您已经有工作经验而又有心进修,当然管道很多,相对的挣扎也多。 因为您不知现在的年纪、条件、资历……再去做进修这样的投资是否值得? 如果,您认定一辈子要当上班族,学历对您而言相信是很重要的,否则,时间宝贵,不容许您再走错路。 20 ~ 25岁,您要懂得掌握与规划自己的未来,决定了就是一条无悔的不归路。 刚得到法律付予您的种种权力,相对的您要尽您的义务及学习面对责任的承担。 这时候的您,是喜悦、矛盾与痛苦交战,喜悦来自于开始被赋予一些自主权,矛盾来自于与父母割不断的脐带关系,痛苦的是开始要尝试错误。 您要开始为自己的未来规划,如升学、就业、感情……拿回自己对人生的主控权,而非一直受人左右影响的去摇摆自己的未来。 【学会人际关系,多认识积极的朋友,十年后这些朋友都将是产业的中坚】 25 ~ 30岁,您像一块海绵,努力吸收也甘心被压榨,为的只是自我的成长。 这时候的您,应是工作取向,薪水待遇。升迁调职您应该是斤斤计较。因为唯有努力付出,相对的您才敢积极争取,社会新鲜人的动力应该让您冲出自己的一片天,也因为没有经验,所以不懂挫折。 因为资源不多,所以一切尽人事,听天命。现在的您:领取别人的薪水,学习别人的经验,付出自己的青春,建构自己的未来。 【学会累积经验,接触机会,良师益友的提携更是提升您成长的大利器】 30 ~ 35岁,您要学习判断机会、掌握机会,不能再有尝试错误的心态。 这时候的您,应是事业取向和家庭取向,工作应该从体力转换为脑力。 您应该看到的是远景,而非现况,面对的是宽广人生,而非局限于自我。 结婚是许多人面临人生第一次的重大抉择,面对婚姻,很多人以为结婚就是一个责任的结束,殊不知正是学习的开始。 就像一些刚上市上柜公司,以为目标达成了,忘了自己的企业责任,忽略本业。反而是一个恶梦的开始。 人的本业不就是经营自己的家庭,赚钱的目的不就希望给家人更好的生活,但这可不能成为忽略家人的借口,一个经营不好家庭的人,纵使赚到全世界,他得到的只是表面的掌声,在他人生的这个圆,永远有一个缺口。 家应该是您最大的精神支柱。动力来源和坚强后盾! 【时间管理,转化心境;转化用头脑去工作,不要用身体去工作】 35 ~ 40岁,您要享受给人希望,功德无量的格局。 这时候的您,应是企业取向,工作只是一种休闲,更可转化为对他人的责任。如果您专注于研究,您应该不只穷毕生之力。 24小时不眠不休的去做苦力您应该有成立研究机构,带领一群人做更多研发的雄心壮志。 如果您是企业主管,您应该不只停留在汲汲营营,斤斤计较,您应该有能力担负主导周遭的员工、家人,带领他们享受更好的生活。 格局的大小,会影响您成就的多少,做一个有影响力的人,而非被影响的人。 【不论目前您多风光。多有成就,在您心中是否画得出十年后的你?】 静心思考!我们现在所有努力的目的不就是为了父母、另一半、小孩……? 工作,不应该等于是人生,更不应该是需要经营一辈子的事。 试问健康、财富、自我成长、人际关系和时间自由,什么是您努力工作的动力? 我相信没有人愿意放弃任何一点。 这些正是促使我们年轻人前进的动力。 十年后,您是提早完成它?还是提早放弃它? 【宁可因梦想而忙碌,不要因忙碌而失去梦想】 我看周遭有太多优秀甚于我数倍的朋友,可惜的是终日汲汲营营,投入更多的时间、精神、资源,却没有享受到应得的代价,原因无他,努力错方向,找错机会,拒绝机会而己。 Jordan 打了一辈子的篮球,是很难在棒球场上找到自己的舞台。不要让忙碌蒙蔽了您的双眼再回头:廉颇老矣,尚能饭否? 【你的时间在那里,成就就在那里】 当您一个人成功,您只享受到一个人的快乐! 懂得分享与付出,真正的快乐来自于:周遭的亲友因您的成长而提升,不论是精神或物质。 真正的成功来自于:周遭的亲友因您付出获得改善,给人希望功德无量。 我们不是在做慈善事业,尚没有能力普渡众生,但是,我们可以发挥一己之力,对亲友,对那些有缘相遇的陌生朋友。 伸出您的手,在他们需要的时候! 太多人在等生命中的贵人,聪明如您,何不先从帮助他人开始? “有人4、50岁了,还喜欢说出自某某名校,我觉得奇怪,他们把学校的那几年当成生命的巅峰,其实他出了校门便已开始走下坡路了。 ” 25 gennaio 年前最后一笔
年前最后一笔了,明天还有半天的班,估计是没有时间写了,放了假,27号中午的飞机回家。我的2005,再见,我的2006,你好。 最近变化好大,有点压得透过气来。世间的事情就是无法预料,YanPeng因为导师的原因,回了学校再也不来了,小马哥被调离了项目组。这个消息太突然,而且我当时正在看《金刚》的结局,一下子震得我低落极了。 事情已经是定局,我这种小角色肯定是无法扭转的,只能默默地承受,他俩的工作落到了我的手上,我要从零开始,N多莫名其妙的软件,狂负责的编译调试环境,我都得花时间去熟悉,上海那边一个劲的提故障,可是我连测试手机都没有摸热,脑子都快炸了。 通讯来了一个老员工帮我忙,很感谢他,我着急上火的时候,他一个劲安慰我,唉,没有过不去的坎。心急的时候,就无法正常思考,其实很多时候静心想想,也就好了。 来实习这么长时间了,第一次感觉到了压力,可能刚开始的时候,对小马哥依赖太多了,人还是要学着独立的。 祝所有的人,春节快乐。 BTW: 2006是我的本命年。 24 gennaio BREW平台Callback(回调)机制的最终分析----2006.1.22
摘要:回调机制是BREW平台中最关键的机制之一,很多接口类都是通过回调机制呈现在开发人员的面前,《对AEECallback结构体及其基础函数的分析》中队brew/src/thrdutil中的一些源代码进行分析,初略的理解了AEECallback结构体及其相关函数的实现,对开发能有一定的帮助,本文则更加深入的分析了该机制的特点,以及高通工作人员给出的一些答案。
注:非常感谢手机之家_开发联盟的superant, 东方欲晓, record等人,是他们激烈的讨论才引出了最后的答案。本文很多内容都摘自他们的帖子。
BREW平台的回调机制,通常是异步的,举例来说,在网络通信的时候,如果是发送数据,普通的方式是发送一快数据,判断是否发送成功,如果发送不成功,则空闲一段时间,在调用发送数据的函数,如此往复,但是如果在BREW平台上,调用发送函数发送数据,如果发送成功,函数会返回发送成功的字节数,如果返回的是-2,表示当前发送不成功,接下来,需要通过_Writeable注册一个回调函数,BREW会根据网络状况调用你注册的回调函数,继续发送需要发送的数据,直到所有数据发送成功。同样的道理,在接收数据的时候,如果数据量比较大,不是一次能够接收完,通常来说就是通过_Readable函数来注册接收回调函数,当有数据到的时候就会调用你注册的回调函数接收数据,直到所有数据接收成功。
BREW平台回调机制的实现有几个关键的部分下面一一介绍。
Callback机制中的核心数据结构:
struct _AEECallback
{
AEECallback *pNext;
void *pmc;
PFNCBCANCEL pfnCancel;
void *pCancelData;
PFNNOTIFY pfnNotify;
void *pNotifyData;
void *pReserved;
};
该结构体的每一个成员在《对AEECallback结构体及其基础函数的分析》中有介绍,在此略过。
从结构的命名中可以猜测,其实AEECallback结构体是以链表形式存在,其中的pNext成员就是起到遍历链表的作用,该链表由系统维护。
CALLBACK_Init和CALLBACK_Cancel是两个关键函数。CALLBACK_Init负责对AEECallback结构体进行初始化,该函数的参数列表第二个参数是PFNNOTIFY类型,就是需要回调的函数的函数指针类型,第三个参数是传递给该回调函数的参数指针,类型是void型指针。CALLBACK_Cancel函数是取消回调函数,也就是调用AEECallback结构体中的pfnCancel指针指向的函数来取消回调。
ISHELL_Resume()函数允许向 AEE 外壳注册回调。 它可以向 AEE 外壳的待处理操作列表中添加回调。 AEE 外壳将在下一次调用事件循环时调用此回调函数,以使应用程序或对象协同处理多任务。如果已注册回调,则会先将其注销,然后再重新注册。
举例来说,我们在APPLET里中定义m_pCB为AEECallback类型,调用CALLBACK_Init(&pme->m_pCB,FUNC1,pme),意在初始化m_pCB,将函数FUNC1注册到这个结构体中,这时候,m_pCB中的pfnNotify就指向了FUNC1,任何时候,不管是开发人员自己写代码调用ISHELL_Resume()函数,还是通过调用其它函数(BREW平台的APIs),在这些函数中有隐含的调用ISHELL_Resume(),该函数都会在BREW系统的回调链表中添加一个节点,该节点就是m_pCB,那么在适当的时候,BREW就会调用你的FUNC1函数。其实在很多BREW APIs中都会有调用ISHELL_Resume(),例如ISHELL_SetTimerEx()函数,不过这个只是猜测,因为根本无法看到该这些函数的原代码。
归纳起来,如过要使用BREW平台的回调机制,则只要初始化适当的AEECallback结构体,再在需要回调的时候调用ISHELL_Resume来启动回调函数 。
下面来叙述一下BREW平台的消息机制和回调机制的大概流程:
我们假设BREW运行于Ui Task,特定于BREW的Sig为AEE_APP_SIG。
For(;;)
{
waitfor sig // 无限循环,捕捉到相应的Sig后,作相应的处理
}
if (receive aee app sig)
{
AEE_Dispatch // 如果收到AEE_APP_SIG 说明BREW需要执行,调用AEE_Dispatch进行消息循环分发。
}
其中AEE_Dispathc是最关键的函数,他会检查BREW事件队列中的所有事件一一分发(调用APP->HandleEvent函数),同时也会检查Callback队列中注册的Callback,一一回调。所有都处理完后,表示本次BREW循环结束,将运行环境切换回UI Task中的其他非BREW程序,或者切换至其他Task。当下次BREW再需要执行时,BREW将再次设置AEE_APP_SIG,从而导致当系统任务调度到UI Task时,AEE_Dispatch再次被调用,以此往复。
关于在ISHELL_Resume注册完回调函数之后,具体会在什么时候调用回调函数,这个并没有深究的价值,在Callback对列中,BREW根据自身的算法选择回调,当一个时间片不够回调所有的Callback的话,则会把未完成的Callback放到下一个或者下几个时间片执行。所以,对于正常的概念来说,只需要知道,当执行了ISHELL_Resume之后,很短的时间内BREW会调用完成Callback的调用。 22 gennaio 对AEECallback结构体及其基础函数的分析----2006.1.22 typedef struct _AEECallback AEECallback; AEECallback_Setup函数: static void AEECallback_Setup(AEECallback *pcb, PFNCBCANCEL pfnCancel, AEECallback_Fire函数: static void AEECallback_Fire(void *pvCxt) pcb->pfnCancel = 0; AEECallback_CancelNotify函数: static void AEECallback_CancelNotify(AEECallback *pcb) pcb->pfnCancel = 0; AEECallback_SchedNotifyWait函数: void AEECallback_SchedNotifyWait(AEECallback *pcb, void *pSchedNotifyObj, 20 gennaio 关于BREW多线程雏形的想法总感觉不舒服,这个多线程,什么东西都需要自己控制。 case EVT_APP_START: 16 gennaio 关于AEEClsCreateInstance中nSize的奇怪问题AEEClsCreateInstance函数的功能是用来创建接口类,具体可以见Blog中《开发BREW扩展类》一文。在该函数的实现代码中,有一个奇怪的nSize,他是需要创建的接口类申请空间的大小,但是代码中对于该nSize的赋值十分有意思,对于以下的分析比较合理,贴出来分享一下。 转自:http://expert.imobile.com.cn/bbs 作者:东方欲晓 if(nSize < sizeof(ExtensionCls)) nSize += sizeof(ExtensionCls); ExtensionCls是用户定义的class结构,所以创建的内存nsize至少应该等于这个, nSize += sizeof(ExtensionCls); 进行真正的内存分配,此时除了给class分配内存外,还要为vtbl分配内存,所以分配的大小为nSize + 这样分配完后,在内存中,class之后就紧接着是一块vtbl区域,接着代码中会为这块vtbl区域初始化,即将其函数指针指向确切的函数地址,最后再将class中的pvt指针指向该vtbl,从而完成了整个class的初始化。 14 gennaio 开发BREW扩展类看到一篇文章,觉得比较有指导意义,译过来,希望给大家有些帮助,能力有限,有错误的地方还望大家指出来。共同学习,共同进步。 原文地址: 1 简介: 2 静态 VS 动态 3 特性 4 MIF文件 5 声明扩展类的结构体 第一行声明了一个IDemoExtension的结构体,该结构体是一个apple结构体,将会返回给正在初始化的应用,其中的宏AEEINTERFACE声明了一个扩展类的虚函数表,从上面的声明看出,虚函数表中有5个函数。BREW的每一个接口类都定义了一个类似于上面定义中的宏INHERIT_XXX,用它来把已继承的函数添加到已存在的函数表中,至少,BREW强烈推荐如上例所示,从IQueryInterface派生而来。宏INHERIT_IQueryInterface添加三个函数到函数表中:AddRef, Release, QueryInterface。我们的例子中添加了DisplayTime和DisplayData两个函数。 以上代码的第一行把虚函数表插入了扩展类的结构体定义之中,虚函数表必须总是被定义成为结构体的第一个成员,m_nRefs变量也必须在结构体定义中声明,一个扩展类在应用中将会数次被引用,这个变量用来保存在应用中被引用的总次数,AddRef和Release函数是用来对该变量进行增减操作的,一旦m_nRefs变为0,该扩展类就会释放所有占用的资源。结构体中接下来的三个成员是扩展类的可选成员,可以在扩展类中添加任何所需要的成员变量。 int MyExtension_New(int16 nSize, IShell *pIShell, IModule* pIModule, AddRef, Release和QueryInterface是从IQI接口继承过来的,AddRef负责增加引用计数的数值。 static uint32 MyExtension_AddRef(IDemoExtension* pMe) { Release函数负责减少引用计数的数值,当引用计数的值变为0的时候,该实例就会从内存中被释放掉。 static uint32 MyExtension_Release(IDemoExtension* pMe) { // Ref count is zero. Release memory associated with this object. // Release interfaces 我们最后一个需要定义的函数就是QueryInterface,这个函数返回一个与扩展类相关联的接口,IWeb接口就是一个例子,当一个应用使用该接口完成一个网页请求的时候,底层的一个TCP套接字被创建,为了能够直接控制这个套接字,应用可以通过调用IWeb_QueryInterface函数,传递参数AEECLSID_SOCKET(AEECLSID_SOCKPORT在BREW3.x中),来获得这个接口,该函数将返回一个指针,下面是QueryInterface的一个具体实现。 static int MyExtension_QueryInterface(IDemoExtension* me, 7 静态扩展类 上面介绍的这个例子也可以用来创建静态扩展类,然而静态扩展类可以作为全局变量,有了这个特性,下面的代码可以为静态扩展类构造虚函数表。 static const AEEVTBL(IDemoExtension) gvtIDemoExtension = { 以上的代码被放置在函数之外,通常是在一个头文件中,初始化扩展类可以简单的用一行代码搞定。 pMe->pvt = &gvtIDemoExtension; 上面的代码初始化了整个虚函数表,不必对于虚函数表中每个函数都初始化一次,然而上面的代码仅对静态扩展类是有效的,一个动态扩展类的地址是在运行时确定的(于之不同的是,静态扩展类的地址是在编译时确定的),因此,虚函数表必须在运行时声明。 8 关于宏 9 使用扩展类 if(ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_MYEXTENSION, IDEMOEXTENSION_DisplayTime(pMe->pIDemoExtension); 10 通过MIME类型使用扩展类 上面提及的例子展示了一个扩展类注册为MYTIME句柄,MIME类型的注册允许在运行时解决class ID的问题,应用可以通过ISHELL_GetHandler函数找到一个MIME类型的class ID,整个函数会遍历所有的MIF文件,寻找以MIME类型方式注册的class ID。 // An Application will call this function when it intends to // Ishell Createinstance DisplayFile是一个被所有扩展类实现的扩充IReader的接口,虚函数表在创建扩展类的时候被初始化,这样就使IREADER_DisplayFile可以索引正确的函数来显示文件。 11 更多信息
|
|
|