当前位置:文档之家› uCOS-II中文版电子书+第11章

uCOS-II中文版电子书+第11章

uCOS-II中文版电子书+第11章
uCOS-II中文版电子书+第11章

第11章

参考手册

本章提供了μC/OS-Ⅱ的用户指南。每一个用户可以调用的内核函数都按字母顺序加以说明,包括:

z函数的功能描述

z函数原型

z函数名称及源代码

z函数使用到的常量

z函数参数

z函数返回值

z特殊说明和注意点

264-μC/OS-II:实时操作系统内核

参考手册-265

OSInit( )

Void OSInit(void);

所属文件调用者开关量

OS_CORE.C 启动代码无

OSinit()初始化μC/OS-Ⅱ,对这个函数的调用必须在调用OSStart()函数之前,而OSStart ()函数真正开始运行多任务。

参数

返回值

注意/警告

必须先于OSStart()函数的调用

范例:

void main (void)

{

.

.

OSInit(); /* 初始化 uC/OS-II */

.

.

OSStart(); /*启动多任务内核 */

}

266-μC/OS-II:实时操作系统内核

OSIntEnter( )

Void OSIntEnter(void);

所属文件调用者开关量

OS_CORE.C 中断无

OSIntEnter()通知μC/OS-Ⅱ一个中断处理函数正在执行,这有助于μC/OS-Ⅱ掌握中断嵌套的情况。OSIntEnter()函数通常和OSIntExit()函数联合使用。

参数

返回值

注意/警告

在任务级不能调用该函数。

如果系统使用的处理器能够执行自动的独立执行读取-修改-写入的操作,那么就可以直接递增中断嵌套层数(OSIntNesting),这样可以避免调用函数所带来的额外的开销。

范例一:

(Intel 80x86的实模式, 在大模式下编译,,real mode,large model)

ISRx PROC FAR

PUSHA ; 保存中断现场

PUSH ES

PUSH DS

;

MOV AX, DGROUP ; 读入数据段

MOV DS, AX

;

CALL FAR PTR _OSIntEnter ; 通知内核进入中断

.

.

POP DS ; 恢复中断现场

参考手册-267

POP ES

POPA

IRET ; 中断返回

ISRx ENDP

范例二:

(Intel 80x86的实模式, 在大模式下编译,, real mode , large model)

ISRx PROC FAR

PUSHA ; 保存中断现场

PUSH ES

PUSH DS

;

MOV AX, DGROUP ; 读入数据段

MOV DS, AX

;

INC BYTE PTR _OSIntNesting ; 通知内核进入中断

.

.

.

POP DS ; 恢复中断现场

POP ES

POPA

IRET ; 中断返回

ISRx ENDP

268-μC/OS-II:实时操作系统内核

OSIntExit( )

Void OSIntExit(void);

所属文件调用者开关量

OS_CORE.C 中断无

OSIntExit()通知μC/OS-Ⅱ一个中断服务已执行完毕,这有助于μC/OS-Ⅱ掌握中断嵌套的情况。通常OSIntExit()和OSIntEnter()联合使用。当最后一层嵌套的中断执行完毕后,如果有更高优先级的任务准备就绪,μC/OS-Ⅱ会调用任务调度函数,在这种情况下,中断返回到更高优先级的任务而不是被中断了的任务。

参数

返回值

注意/警告

在任务级不能调用该函数。并且即使没有调用OSIntEnter()而是使用直接递增OSIntNesting 的方法,也必须调用OSIntExit()函数。

参考手册-269

范例:

(Intel 80x86 的实模式, 在大模式下编译,real mode , large model)

ISRx PROC FAR

PUSHA ; 保存中断现场

PUSH ES

PUSH DS

.

.

CALL FAR PTR _OSIntExit ; 通知内核进入中断

POP DS ; 恢复中断现场

POP ES

POPA

IRET ; 中断返回

ISRx ENDP

270-μC/OS-II:实时操作系统内核

OSMboxAccept( )

Void *OSMboxAccept(OS_EVENT *pevent);

所属文件调用者开关量

OS_MBOX.C 任务或中断OS_MBOX_EN OSMboxAccept()函数查看指定的消息邮箱是否有需要的消息。不同于OSMboxPend()函数,如果没有需要的消息,OSMboxAccept()函数并不挂起任务。如果消息已经到达,该消息被传递到用户任务并且从消息邮箱中清除。通常中断调用该函数,因为中断不允许挂起等待消息。

参数

pevent 是指向需要查看的消息邮箱的指针。当建立消息邮箱时,该指针返回到用户程序。(参考OSMboxCreate()函数)。

返回值

如果消息已经到达,返回指向该消息的指针;如果消息邮箱没有消息,返回空指针。

注意/警告

必须先建立消息邮箱,然后使用。

参考手册-271

范例:

OS_EVENT *CommMbox;

void Task (void *pdata)

{

void *msg;

pdata = pdata;

for (;;) {

msg = OSMboxAccept(CommMbox); /* 检查消息邮箱是否有消息 */

if (msg != (void *)0) {

. /* 处理消息 */ .

} else {

. /*没有消息 */ .

}

.

.

}

}

272-μC/OS-II:实时操作系统内核

OSMboxCreate( )

OS_EVENT *OSMboxCreate(void *msg);

所属文件调用者开关量

OS_MBOX.C 任务或启动代码OS_MBOX_EN OSMboxCreate()建立并初始化一个消息邮箱。消息邮箱允许任务或中断向其他一个或几个任务发送消息。

参数

msg参数用来初始化建立的消息邮箱。如果该指针不为空,建立的消息邮箱将含有消息。

返回值

指向分配给所建立的消息邮箱的事件控制块的指针。如果没有可用的事件控制块,返回空指针。

注意/警告

必须先建立消息邮箱,然后使用。

参考手册-273 范例:

OS_EVENT *CommMbox;

void main(void)

{

.

.

OSInit(); /* 初始化μC/OS-Ⅱ */

.

.

CommMbox = OSMboxCreate((void *)0); /* 建立消息邮箱 */

OSStart(); /* 启动多任务内核 */

}

274-μC/OS-II:实时操作系统内核

OSMboxPend( )

Void *OSMboxPend ( OS_EVNNT *pevent, INT16U timeout, int8u *err );

所属文件调用者开关量

OS_MBOX.C 任务OS_MBOX_EN OSMboxPend()用于任务等待消息。消息通过中断或另外的任务发送给需要的任务。消息是一个以指针定义的变量,在不同的程序中消息的使用也可能不同。如果调用OSMboxPend()函数时消息邮箱已经存在需要的消息,那么该消息被返回给OSMboxPend()的调用者,消息邮箱中清除该消息。如果调用OSMboxPend()函数时消息邮箱中没有需要的消息,OSMboxPend ()函数挂起当前任务直到得到需要的消息或超出定义等待超时的时间。如果同时有多个任务等待同一个消息,μC/OS-Ⅱ默认最高优先级的任务取得消息并且任务恢复执行。一个由OSTaskSuspend()函数挂起的任务也可以接受消息,但这个任务将一直保持挂起状态直到通过调用OSTaskResume()函数恢复任务的运行。

参数

pevent 是指向即将接受消息的消息邮箱的指针。该指针的值在建立该消息邮箱时可以得到。(参考OSMboxCreate()函数)。

Timeout 允许一个任务在经过了指定数目的时钟节拍后还没有得到需要的消息时恢复运行。如果该值为零表示任务将持续的等待消息。最大的等待时间为65,535个时钟节拍。这个时间长度并不是非常严格的,可能存在一个时钟节拍的误差,因为只有在一个时钟节拍结束后才会减少定义的等待超时时钟节拍。

Err 是指向包含错误码的变量的指针。OSMboxPend()函数返回的错误码可能为下述几种:z OS_NO_ERR :消息被正确的接受。

z OS_TIMEOUT :消息没有在指定的周期数内送到。

z OS_ERR_PEND_ISR :从中断调用该函数。虽然规定了不允许从中断调用该函数,但μC/OS-Ⅱ仍然包含了检测这种情况的功能。

z OS_ERR_EVENT_TYPE :pevent 不是指向消息邮箱的指针。

返回值

OSMboxPend()函数返回接受的消息并将 *err置为OS_NO_ERR。如果没有在指定数目的时钟节拍内接受到需要的消息,OSMboxPend()函数返回空指针并且将 *err设置为OS_TIMEOUT。

注意/警告

必须先建立消息邮箱,然后使用。

不允许从中断调用该函数。

参考手册-275 范例:

OS_EVENT *CommMbox;

void CommTask(void *pdata)

{

INT8U err;

void *msg;

pdata = pdata;

for (;;) {

.

.

msg = OSMboxPend(CommMbox, 10, &err);

if (err == OS_NO_ERR) {

.

. /* 消息正确的接受 */

.

} else {

.

. /* 在指定时间内没有接受到消息*/

.

}

.

.

}

}

276-μC/OS-II:实时操作系统内核

OSMboxPost( )

INT8U OSMboxPost(OS_EVENT *pevent, void *msg);

所属文件调用者开关量

OS_MBOX.C 任务或中断OS_MBOX_EN OSMboxPost()函数通过消息邮箱向任务发送消息。消息是一个指针长度的变量,在不同的程序中消息的使用也可能不同。如果消息邮箱中已经存在消息,返回错误码说明消息邮箱已满。OSMboxPost()函数立即返回调用者,消息也没有能够发到消息邮箱。如果有任何任务在等待消息邮箱的消息,最高优先级的任务将得到这个消息。如果等待消息的任务优先级比发送消息的任务优先级高,那么高优先级的任务将得到消息而恢复执行,也就是说,发生了一次任务切换。

参数

pevent 是指向即将接受消息的消息邮箱的指针。该指针的值在建立该消息邮箱时可以得到。(参考OSMboxCreate()函数)。

Msg 是即将实际发送给任务的消息。消息是一个指针长度的变量,在不同的程序中消息的使用也可能不同。不允许传递一个空指针,因为这意味着消息邮箱为空。

返回值

OSMboxPost()函数的返回值为下述之一:

z OS_NO_ERR :消息成功的放到消息邮箱中。

z OS_MBOX_FULL :消息邮箱已经包含了其他消息,不空。

z OS_ERR_EVENT_TYPE :pevent 不是指向消息邮箱的指针。

注意/警告

必须先建立消息邮箱,然后使用。

不允许传递一个空指针,因为这意味着消息邮箱为空。

参考手册-277 范例:

OS_EVENT *CommMbox;

INT8U CommRxBuf[100];

void CommTaskRx(void *pdata)

{

INT8U err;

pdata = pdata;

for (;;) {

.

.

err = OSMboxPost(CommMbox, (void *)&CommRxBuf[0]);

.

.

}

}

278-μC/OS-II:实时操作系统内核

OSMboxQuery( )

INT8U OSMboxQuery(OS_EVENT *pevent, OS_MBOX_DATA *pdata);

所属文件调用者开关量

OS_MBOX.C 任务或中断OS_MBOX_EN OSMboxQuery()函数用来取得消息邮箱的信息。用户程序必须分配一个OS_MBOX_DATA的数据结构,该结构用来从消息邮箱的事件控制块接受数据。通过调用OSMboxQuery()函数可以知道任务是否在等待消息以及有多少个任务在等待消息,还可以检查消息邮箱现在的消息。

参数

pevent 是指向即将接受消息的消息邮箱的指针。该指针的值在建立该消息邮箱时可以得到。(参考OSMboxCreate()函数)。

Pdata 是指向OS_MBOX_DATA数据结构的指针,该数据结构包含下述成员:

*OSMsg; /* 消息邮箱中消息的复制 */

V oid

INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /*消息邮箱等待队列的复制*/ OSEventGrp;

INT8U

返回值

OSMboxQuery()函数的返回值为下述之一:

z OS_NO_ERR :调用成功

z OS_ERR_EVENT_TYPE :pevent 不是指向消息邮箱的指针。

注意/警告

必须先建立消息邮箱,然后使用。

参考手册-279 范例:

OS_EVENT *CommMbox;

void Task (void *pdata)

{

OS_MBOXDATA mbox_data;

INT8U err;

pdata = pdata;

for (;;) {

.

.

err = OSMboxQuery(CommMbox, &mbox_data);

if (err == OS_NO_ERR) {

. /* 如果mbox_data.OSMsg为非空指针,说明消息邮箱非空*/

}

.

.

}

}

280-μC/OS-II:实时操作系统内核

OSMemCreate( )

OS_MEM *OSMemCreate( void *addr, INT32U nblks ,INT32U blksize, INT8U *err);

所属文件调用者开关量

OS_MEM.C 任务或初始代码OS_/MEM_EN OSMemCreate()函数建立并初始化一块内存区。一块内存区包含指定数目的大小确定的内存块。程序可以包含这些内存块并在用完后释放回内存区。

参数

addr 建立的内存区的起始地址。内存区可以使用静态数组或在初始化时使用malloc()函数建立。

Nblks 需要的内存块的数目。每一个内存区最少需要定义两个内存块。

Blksize 每个内存块的大小,最少应该能够容纳一个指针。

Err 是指向包含错误码的变量的指针。OSMemCreate()函数返回的错误码可能为下述几种:OS_NO_ERR :成功建立内存区。

OS_MEM_INV ALID_PART :没有空闲的内存区。

OS_MEM_INV ALID_BLKS :没有为每一个内存区建立至少两个内存块。

OS_MEM_INV ALID_SIZE :内存块大小不足以容纳一个指针变量。

返回值

OSMemCreate()函数返回指向内存区控制块的指针。如果没有剩余内存区,OSMemCreate()函数返回空指针。

注意/警告

必须首先建立内存区,然后使用。

参考手册-281 范例:

OS_MEM *CommMem;

INT8U CommBuf[16][128];

void main(void)

{

INT8U err;

OSInit(); /* 初始化μC/OS-Ⅱ */

.

.

CommMem = OSMemCreate(&CommBuf[0][0], 16, 128, &err);

.

.

OSStart(); /* 启动多任务内核 */

}

282-μC/OS-II:实时操作系统内核

OSMemGet( )

Void *OSMemGet(OS_MEM *pmem, INT8U *err);

所属文件调用者开关量

OS_MEM.C 任务或中断OS_MEM_EN OSMemGet()函数用于从内存区分配一个内存块。用户程序必须知道所建立的内存块的大小,同时用户程序必须在使用完内存块后释放内存块。可以多次调用OSMemGet()函数。

参数

pmem是指向内存区控制块的指针,可以从OSMemCreate()函数返回得到。

Err 是指向包含错误码的变量的指针。OSMemGet(函数返回的错误码可能为下述几种:

z OS_NO_ERR :成功得到一个内存块。

z OS_MEM_NO_FREE_BLKS :内存区已经没有空间分配给内存块。

返回值

OSMemGet()函数返回指向内存区块的指针。如果没有空间分配给内存块,OSMemGet()函数返回空指针。

注意/警告

必须首先建立内存区,然后使用。

实时操作系统UCOS-II,学会RTOS给你的身价增值

实时操作系统UCOS-II,学会RTOS给你的身价增值 如果,你最近关注一些嵌入式招聘职位描述,你可能会经常看到看到使用过uCOS、Vxworks、QNX等RTOS者优先。 随便打开一个20K的嵌入式开发工作职责: 你会发现熟悉RTOS的开发、移植、剪裁真的很吃香! 今天,我们就来介绍一下实时操作系统UCOS-II。 一、嵌入式操作系统概览 嵌入式操作系统的主要好处就是屏蔽了底层硬件的差别,给上层应用提供统一的接口,并管理进程调度和资源(如CPU时间、内存)分配等。并且可以充分利用硬件资源,如在单任务时(大循环结构,如大部分51程序)遇到delay函数时,CPU在空转。而在多任务系统,遇到delay或需等待资源时系统会自动运行下一个任务,等条件满足再回来运行先前的任务,这样就充分利用了CPU,提高了效率。 uC/OS操作系统与裸机程序的最大不同点就在于uC/OS有任务调度,可以根据任务的重要程度(优先级)优先执行重要的任务,从而确保能及时处理最重要的数据。(所以对于一个系统有必要使用OS的判断是能否划分一个个的任务,并且各任务间的耦合很小)可以思考下裸机程序中断的时候发生的过程。利用堆栈可以很自由的在A、B中切换,如果切换足够快,A、B看以来好像同时在执行,这就是并行,A、B就是任务。如果这个切换操作放到定时器函数中来做,就可以严格按照时间来切换。另外,各个任务之间有存在一定的关系,有逻辑上的先后等,必须引进全局的结构体、变量来标记一些信息,全局的这些数据是不会被释放的,所以所有的任务可以去通过读、写这些数据来实现各个程序块交流信息,实现所谓的同步、互斥。这就是操作系统的原理,而这些不同的通信方式按功能细分就成事件管理、内存管理等。

软件破解入门教程

先教大家一些基础知识,学习破解其实是要和程序打交道的,汇编是破解程序的必备知识,但有可能部分朋友都没有学习过汇编语言,所以我就在这里叫大家一些简单实用的破解语句吧! ---------------------------------------------------------------------------------------------------------------- 语句:cmp a,b //cmp是比较的意思!在这里假如a=1,b=2 那么就是a与b比较大小. mov a,b //mov是赋值语句,把b的值赋给a. je/jz //就是相等就到指定位置(也叫跳转). jne/jnz //不相等就到指定位置. jmp //无条件跳转. jl/jb //若小于就跳. ja/jg //若大于就跳. jge //若大于等于就跳. 这里以一款LRC傻瓜编辑器为例,讲解一下软件的初步破解过程。大家只要认真看我的操作一定会!假如还是不明白的话提出难点帮你解决,还不行的话直接找我!有时间给你补节课!呵呵! 目标:LRC傻瓜编辑器杀杀杀~~~~~~~~~ 简介:本软件可以让你听完一首MP3歌曲,便可编辑完成一首LRC歌词。并且本软件自身还带有MP3音乐播放和LRC歌词播放功能,没注册的软件只能使用15天。 工具/原料 我们破解或给软件脱壳最常用的软件就是OD全名叫Ollydbg,界面如图: 它是一个功能很强大的工具,左上角是cpu窗口,分别是地址,机器码,汇编代码,注释;注释添加方便,而且还能即时显示函数的调用结果,返回值. 右上角是寄存器窗口,但不仅仅反映寄存器的状况,还有好多东东;双击即可改变Eflag的值,对于寄存器,指令执行后发生改变的寄存器会用红色突出显示. cpu窗口下面还有一个小窗口,显示当前操作改变的寄存器状态. 左下角是内存窗口.可以ascii或者unicode两种方式显示内存信息. 右下角的是当前堆栈情况,还有注释啊. 步骤/方法 1. 我们要想破解一个软件就是修改它的代码,我们要想在这代码的海洋里找到我们破解关键的代码确实很棘 手,所以我们必须找到一定的线索,一便我们顺藤摸瓜的找到我们想要的东东,现在的关键问题就是什么

Unity3D经典入门教程(精)

一、Unity基础 本部分是你开始Unity的关键。、这里将解释Unity的界面,菜单项,使用资源,创建场景,和发布。当你完全阅读了该部分后,你将能够理解Unity是如何工作的,以及如何使其更加有效的工作,和如何将简单的游戏放置在一起。 1. 界面学习 现在我们开始学习Unity,如果你还没有打开 Unity,你可以通过双击位于Application->Unity文件夹中的 Unity图标来运行它,当它第一次运行时你将看到如下的场景: Unity运行时的缺省场景,如果你打开过任何实例,你的屏幕会与上图不同 有很多需要学习的东西,让我们花费点时间来观察理解上述界面。我们将介绍每一个接口 元素。 概要主窗口的每一个部分都被称为视图(View)。在 Unity中有多种类型的视图,但是,你

不需要同时看见所有的视图。不同的布局模式(Layout modes)包含的视图是不同的。通过单击布局下拉控件来选择不同的布局,该控件位于窗口的右上角。 布局模式选择下拉列表 现在,单击布局选择,并单击Animation,切换到动画布局 (Animation layout)。还可以从菜单中选择Window->Layouts->Animation来切换。动画布局包含所有的视图,这是昀好的用来介绍它们的方法。

通过视图左上角的名称你可以迅速的分辨这些视图。这些视图是:场景视图(Scene View)-用于放置物体游戏视图(Game View)-表示游戏在运行时的外观层次视图(Hierarchy)-当前场景中的游戏物体的列表工程视图(Project)-显示当前打开工程中所有可用的物体和资源检视视图(Instpector)-显示当前选中物体的细节和属性时间线(Timeline)-用于为当前选中物体创建基本的时间线动画 场景视图(Scene View) 场景视图 场景视图(Scene View)是一个可交互的沙盘。你将使用它来选择并在场景中定位所有的游戏物体(GameObjects),包括玩家,摄像机,敌人等。在场景视图中操纵并修改物体是Unity非常重要的功能。这是昀好的通过设计者而不是玩家的角度来查看场景的方法。在场景视图中你可以随意移动并操纵物体,但是你应该知道一些基本的命令以便有效的使用场景视图。 第一个你应该知道命令是FrameSelected命令。这个命令将居中显示你当前选中的物体。你可以在层次视图(Hierarchy)单击任何物体,然后移动你的鼠标到场景视图上并按F键。场景视图将移动以居中显示当前选择的物体。这个命令是非常有用的,你将在场景编辑的

6、汇编学习从入门到精通(荐书)

汇编学习从入门到精通Step By Step 2007年12月15日星期六00:34 信息来源:https://www.doczj.com/doc/6f6345922.html,/hkbyest/archive/2007/07/22/1702065.aspx Cracker,一个充满诱惑的词。别误会,我这里说的是软件破解,想做骇客的一边去,这年头没人说骇客,都是“黑客”了,嘎嘎~ 公元1999年的炎热夏季,我捧起我哥留在家的清华黄皮本《IBM-PC汇编语言程序设计》,苦读。一个星期后我那脆弱的小心灵如玻璃般碎裂了,为了弥补伤痛我哭爹求妈弄了8k大洋配了台当时算是主流的PC,要知道那是64M内存!8.4G硬盘啊!还有传说中的Celeon 300A CPU。不过很可惜的是在当时那32k小猫当道的时代,没有宽带网络,没有软件,没有资料,没有论坛,理所当然我对伟大的计算机科学体系的第一步探索就此夭折,此时陪伴我的是那些盗版光盘中的游戏,把CRACK_XXX文件从光盘复制到硬盘成了时常的工作,偶尔看到光盘中的nfo 文件,心里也闪过一丝对破解的憧憬。 上了大学后有网可用了,慢慢地接触到了一些黑客入侵的知识,想当黑客是每一个充满好奇的小青年的神圣愿望,整天看这看那,偷偷改了下别人的网页就欢喜得好像第一次偷到鸡的黄鼠狼。 大一开设的汇编教材就是那不知版了多少次的《IBM-PC汇编语言程序设计》,凭着之前的那星期苦读,考试混了个80分。可惜当时头脑发热,大学60分万岁思想无疑更为主流,现在想想真是可惜了宝贵的学习时间。 不知不觉快毕业了,这时手头上的《黑客防线》,《黑客X档案》积了一大摞,整天注来注去的也厌烦了,校园网上的肉鸡一打一打更不知道拿来干什么。这时兴趣自然转向了crack,看着杂志上天书般的汇编代码,望望手头还算崭新的汇编课本,叹了口气,重新学那已经忘光了的汇编语言吧。咬牙再咬牙,看完寻址方式那章后我还是认输,不认不行啊,头快裂了,第三次努力终告失败。虽然此时也可以爆破一些简单的软件,虽然也知道搞破解不需要很多的汇编知识,但我还是固执地希望能学好这门基础中的基础课程。 毕业了,进入社会了,找工作,上班,换工作成了主流旋律,每天精疲力尽的哪有时间呢?在最初的中国移动到考公务员再到深圳再到家里希望的金融机构,一系列的曲折失败等待耗光了我的热情,我失业了,赋闲在家无所事事,唯一陪伴我的是那些杂志,课本,以及过时的第二台电脑。我不想工作,我对找工作有一种恐惧,我靠酒精麻醉自己,颓废一段日子后也觉得生活太过无聊了,努力看书考了个CCNA想出去,结果还是被现实的就业环境所打败。三年时间,一无所获。 再之后来到女朋友处陪伴她度过刚毕业踏入社会工作的适应时期,这段时间随便找了个电脑技术工作,每月赚那么个几百块做生活费。不过这半年让我收获比较大的就是时间充裕,接触到了不少新东西,我下定决心要把汇编学好,这时我在网上看到了别人推荐的王爽《汇编语言》,没抱什么希望在当当网购了人生中的第一次物,19块6毛,我记得很清楚,呵呵。 废话终于完了,感谢各位能看到这里,下面进入正题吧。

Linux基本反汇编结构与GDB入门

Linux下的汇编与Windows汇编最大的不同就是第一个操作数是原操作数,第二个是目的操作数,而Windows下却是相反。 1、基本操作指令 简单的操作数类型说明,一般有三种, (1)立即数操作数,也就是常数值。立即数的书写方式是“$”后面跟一个整数,比如$0x1F,这个会在后面的具体分析中见到很多。 (2)寄存器操作数,它表示某个寄存器的内容,用符号Ea来表示任意寄存器a,用引用R[Ea]来表示它的值,这是将寄存器集合看成一个数组R,用寄存器表示符作为索引。 (3)操作数是存储器引用,它会根据计算出来的地址(通常称为有效地址)访问某个存储器位置。用符号Mb[Addr]表示对存储在存储器中从地址Addr开始的b字节值的引用。通常可以省略下标b。 图1表示有多种不同的寻址模式,一个立即数偏移Imm,一个基址寄存器Eb,一个变址或索引寄存器Ei和一个伸缩因子s。有效地址被计算为Imm+R[Eb]+R[Ei]*s,对于这中寻址方式,我们可以在数组或者结构体中进行对元

注:操作数可以是立即数值、寄存器值或是来自存储器的值,伸缩因子必须是1、2、4、或者是8。从上面的图我们就可以大致了解操作数的类型了。 在操作指令中,最频繁使用的指令是执行数据传送的指令。对于传送指令的两个操作数不能都指向存储器位置(我的理解是一般存储器存储的都是地址,不能够对地址和地址进行操作)。将一个值从一个存储器位置拷到另一个存储器位置需要两条指令——第一条指令将源值加载到寄存器中,第二条将该寄存器值写入到目的位置。下面给出源操作数和目的操作数的五种可能组合。 1、movl $0x4050, %eax 立即数——寄存器 2、movl %ebp, %esp 寄存器——寄存器 3、movl (%edi, %ecx), %eax 存储器——寄存器 4、movl $-17, (%esp) 立即数——存储器 5、movl %eax, -12(%ebp) 寄存器——存储器 注意这里的指令mov可能有不同的形式,不同平台的汇编一般是有些不一样的, 结合例子来进行讲解一下指令的具体操作,在这里将会正式接触到Linux下的GCC开发环境和GDB调试器,不过都是比较简单的应用。我的Linux操作系统是Ubuntu9.10,其它版本的差别应该不大, 如果我们要编写一个程序,我们可以用Linux下自带的vi或vim编辑器,studyrush@studyrush-desktop:~/C$ vi exchange.c vi 后面加我们要创建的程序文件的名字,在这里是exchange.c studyrush@studyrush-desktop:~/C$ gcc -o exchange exchange.c gcc -o exchange exchange.c 或gcc exchange –o exchange这两者都可以对源文件进行编译,-o exchange 表示对我们要输出的文件名称,可能表达的不够准确,大家可以先熟悉一下gcc编译器,应该就会明白的了。 studyrush@studyrush-desktop:~/C$ ./exchange 点加斜线再加输出文件名就表示运行程序,下面是运行的结果。 a = 3, b = 4

嵌入式经典书籍100册

嵌入式工程师必读100本专业书籍 ——从小白到大牛你只差这100本书《大话数据结构》 《鸟哥的linux私房菜》 《疯狂android讲义》 《第一行代码》 《linux内核设计与实现》 《驱动设计开发》 《linux内核解密》 《unix环境高级编程》 《linux内核设计与实现》 《essential C++》 《嵌入式linux》 《linux设备驱动》 《c语言深度解剖》 《linux下的c编程》 《C Primer Plus(第五版)》 《ARM体系结构与编程(第二版)》 《lINUX设备驱动开发详解(第三版)》 《android开发艺术探讨》 《c++plus》 《Unix环境高级编程》 《与大数据同行——学习和教育的未来》 《用户体验的要素》 《编程与艺术》 《ARM嵌入式体系结构与接口技术》 《cortex-m0接口编程》 《C语言程序设计:现代方法》 《C++ Primer》

《数据结构》(严蔚敏) 《算法导论》 《Linux设备驱动开发》 《代码大全》 《深入理解计算机系统》 《UNIX环境高级编程》 《计算机安全原理》 《UNIX网络编程》 《HeadFirst设计模式》 《linux驱动》(宋保华) 《C++ primer4》 《qt5精彩实例》 《ldd3》 《C++高级编程》 《c语言教程》 《实战linux编程精髓》 《ARM教程》 《JAVA编程思想》 《HTML+CSS网页设计与布局从入门到精通》《C语言深度解剖》 《深度实践嵌入式Linux系统移植》 《unix高级编程》 《c嵌入式一站式教学》 《编译原理》 《深度实践嵌入式Linux系统移植》《UNIX环境高级编程》 《linux网络编程》 《C语言程序设计》 《unix环境高级编程》 《嵌入式linuxc语言程序设计基础教程》

ucos-ii操作系统复习大纲

ucos-ii操作系统复习大纲 一.填空题 1.uC/OS-II是一个简洁、易用的基于优先级的嵌入式【抢占式】多任务实时内核。 2.任务是一个无返回的无穷循环。uc/os-ii总是运行进入就绪状态的【最高优先级】的任务。 3.因为uc/os-ii总是运行进入就绪状态的最高优先级的任务。所以,确定哪 个任务优先级最高,下面该哪个任务运行,这个工作就是由【调度器(scheduler)】来完成的。 4.【任务级】的调度是由函数OSSched()完成的,而【中断级】的调度 是由函数OSIntExt() 完成。对于OSSched(),它内部调用的是【OS_TASK_SW()】完成实际的调度;OSIntExt()内部调用的是【 OSCtxSw() 】实现调度。 5.任务切换其实很简单,由如下2步完成: (1)将被挂起任务的处理器寄存器推入自己的【任务堆栈】。 (2)然后将进入就绪状态的最高优先级的任务的寄存器值从堆栈中恢复到【寄存器】中。 6.任务的5种状态。 【睡眠态(task dormat) 】:任务驻留于程序空间(rom或ram)中,暂时没交给ucos-ii处理。 【就绪态(task ready)】:任务一旦建立,这个任务就进入了就绪态。 【运行态(task running)】:调用OSStart()可以启动多任务。OSStart()函数只能调用一次,一旦调用,系统将运行进入就绪态并且优先级最高的任务。 【等待状态(task waiting)】:正在运行的任务,通过延迟函数或pend(挂起)相关函数后,将进入等待状态。

【中断状态(ISR running)】:正在运行的任务是可以被中断的,除非该任务将中断关闭或者ucos-ii将中断关闭。 7.【不可剥夺型】内核要求每个任务自我放弃CPU的所有权。不可剥夺型调度法也称作合作型多任务,各个任务彼此合作共享一个CPU。 8.当系统响应时间很重要时,要使用【可剥夺型】内核。最高优先级的任务一旦就绪,总能得到CPU的控制权。 9.使用可剥夺型内核时,应用程序不应直接使用不可重入型函数。调用不可重入型函数时,要满足互斥条件,这一点可以用【互斥型信号量】来实现。 10.【可重入型】函数可以被一个以上的任务调用,而不必担心数据的破坏。 11.可重入型函数任何时候都可以被中断,一段时间以后又可以运行,而相应数据不会丢失。可重入型函数或者只使用【局部变量】,即变量保存在CPU寄存器中或堆栈中。如果使用全局变量,则要对全局变量予以【保护】。 12.每个任务都有其优先级。任务越重要,赋予的优先级应【越高】。 13.μC/OS-Ⅱ初始化是通过调用系统函数【OSIint()】实现的,完成μC/OS-Ⅱ所有的变量和数据结构的初始化。 14.多任务的启动是用户通过调用【OSStart()】实现的。然而,启动μC/OS-Ⅱ之前,用户至少要建立一个应用【任务】。 15. μC/OS-Ⅱ的参数配置文件名为【】。 16.删除任务,是说任务将返回并处于【休眠状态】,并不是说任务的代码被删除了,只是任务的代码不再被μC/OS-Ⅱ调用。 17.μC/OS-Ⅱ要求用户提供【定时中断】来实现延时与超时控制等功能。 18.定时中断也叫做【时钟节拍】,它应该每秒发生10至100次。 19. 时钟节拍的实际频率是由用户的应用程序决定的。时钟节拍的频率越高,系统的负荷就【越重】。 20.μC/OS-II中的信号量由两部分组成:一个是信号量的【计数值】,它是一个16位的无符号整数(0 到65,535之间);另一个是由等待该信号量的任务组成的【等待任务表】。用户要在中将OS_SEM_EN开关量常数置成【1 】,这样μC/OS-II 才能支持信号量。 21. μC/OS-II中表示当前已经创建的任务数全局变量名为:【 OSTaskCtr 】。

汇编语言入门教程

汇编语言入门教程 2007-04-29 22:04对初学者而言,汇编的许多命令太复杂,往往学习很长时间也写不出一个漂漂亮亮的程序,以致妨碍了我们学习汇编的兴趣,不少人就此放弃。所以我个人看法学汇编,不一定要写程序,写程序确实不是汇编的强项,大家不妨玩玩DEBUG,有时CRACK 出一个小软件比完成一个程序更有成就感(就像学电脑先玩游戏一样)。某些高深的指令事实上只对有经验的汇编程序员有用,对我们而言,太过高深了。为了使学习汇编语言有个好的开始,你必须要先排除那些华丽复杂的命令,将注意力集中在最重要的几个指令上(CMP LOOP MOV JNZ……)。但是想在啰里吧嗦的教科书中完成上述目标,谈何容易,所以本人整理了这篇超浓缩(用WINZIP、WINRAR…依次压迫,嘿嘿!)教程。大言不惭的说,看通本文,你完全可以“不经意”间在前辈或是后生卖弄一下DEBUG,很有成就感的,试试看!那么――这个接下来呢?――Here we go!(阅读时看不懂不要紧,下文必有分解) 因为汇编是通过CPU和内存跟硬件对话的,所以我们不得不先了解一下CPU和内存:(关于数的进制问题在此不提) CPU是可以执行电脑所有算术╱逻辑运算与基本I/O 控制功能的一块芯片。一种汇编语言只能用于特定的CPU。也就是说,不同的CPU其汇编语言的指令语法亦不相同。个人电脑由1981年推出至今,其CPU发展过程为:8086→80286→80386→80486→PENTIUM →……,还有AMD、CYRIX等旁支。后面兼容前面CPU的功能,只不过多了些指令(如多能奔腾的MMX指令集)、增大了寄存器(如386的32位EAX)、增多了寄存器(如486的FS)。为确保汇编程序可以适用于各种机型,所以推荐使用8086汇编语言,其兼容性最佳。本文所提均为8086汇编语言。寄存器(Register)是CPU内部的元件,所以在寄存器之间的数据传送非常快。用途:1.可将寄存器内的数据执行算术及逻辑运算。2.存于寄存器内的地址可用来指向内存的某个位置,即寻址。3.可以用来读写数据到电脑的周边设备。8086 有8个8位数据寄存器,这些8位寄存器可分别组成16位寄存器:AH&AL=AX:累加寄存器,常用于运算;BH&BL=BX:基址寄存器,常用于地址索引;CH&CL=CX:计数寄存器,常用于计数;DH&DL=DX:数据寄存器,常用于数据传递。为了运用所有的内存空间,8086设定了四个段寄存器,专门用来保存段地址:CS(Code Segment):代码段寄存器;DS(Data Segment):数据段寄存器;SS(Stack Segment):堆栈段寄存器;ES(Extra Segment):附加段寄存器。当一个程序要执行时,就要决定程序代码、数据和堆栈各要用到内存的哪些位置,通过设定段寄存器CS,DS,SS 来指向这些起始位置。通常是将DS固定,而根据需要修改CS。所以,程序可以在可寻址空间小于64K的情况下被写成任意大小。所以,程序和其数据组合起来的大小,限制在DS 所指的64K内,这就是COM文件不得大于64K的原因。8086以内存做为战场,用寄存器做为军事基地,以加速工作。除了前面所提的寄存器外,还有一些特殊功能的寄存器:IP(Intruction Pointer):指令指针寄存器,与CS配合使用,可跟踪程序的执行过程;SP(Stack Pointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置。BP(Base Pointer):基址指针寄存器,可用作SS的一个相对基址位置;SI(Source Index):源变址寄存器可用来存放相对于DS 段之源变址指针;DI(Destination Index):目的变址寄存器,可用来存放相对于ES 段之目的变址指针。还有一个标志寄存器FR(Flag Register),有九个有意义的标志,将在下文用到时详细说明。

嵌入式实时操作系统UCOS 2优劣势分析

嵌入式实时操作系统ucos ii的优劣势分析 引言 早在20世纪60年代,就已经有人开始研究和开发嵌入式操作系统。但直到最近,它才在国内被越来越多的提及,在通信、电子、自动化等需要实时处理的领域所曰益显现的重要性吸引了人们越来越多的注意力。但是,人们所谈论的往往是一些著名的商业内核,诸如VxWorks、PSOS等。这些商业内核性能优越,但价格昂贵,主要用于16位和32位处理器中,针对国内大部分用户使用的51系列8位单片机,可以选择免费的ucos ii。 ucos ii的特点 1.ucos ii是由Labrosse先生编写的一个开放式内核,最主要的特点就是源码公开。这一点对于用户来说可谓利弊各半,好处在于,一方面它是免费的,另一方面用户可以根据自己的需要对它进行修改。缺点在于它缺乏必要的支持,没有功能强大的软件包,用户通常需要自己编写驱动程序,特别是如果用户使用的是不太常用的单片机,还必须自己编写移植程序。 2.ucos ii是一个占先式的内核,即已经准备就绪的高优先级任务可以剥夺正在运行的低优先级任务的CPU使用权。这个特点使得它的实时性比非占先式的内核要好。通常我们都是在中断服务程序中使高优先级任务进入就绪态(例如发信号),这样退出中断服务程序后,将进行任务切换,高优先级任务将被执行。拿51单片机为例,比较一下就可以发现这样做的好处。假如需要用中断方式采集一批数据并进行处理,在传统的编程方法中不能在中断服务程序中进行复杂的数据处理,因为这会使得关中断时间过长。所以经常采用的方法是置一标志位,然后退出中断。由于主程序是循环执行的,所以它总有机会检测到这一标志并转到数据处理程序中去。但是因为无法确定发生中断时程序到底执行到了什么地方,也就无法判断要经过多长时间数据处理程序才会执行,中断响应时间无法确定,系统的实时性不强。如果使用μC/OS-II的话,只要把数据处理程序的优先级设定得高一些,并在中断服务程序中使它进入就绪态,中断结束后数据处理程序就会被立即执行。这样可以把中断响应时间限制在一定的范围内。对于一些对中断响应时间有严格要求的系统,这是必不可少的。但应该指出的是如果数据处理程序简单,这样做就未必合适。因为ucos ii要求在中断服务程序末尾使用OSINTEXIT函数以判断是否进行任务切换,这需要花费一定的时间。 3.ucos ii和大家所熟知的Linux等分时操作系统不同,它不支持时间片轮转法。ucos ii是一个基于优先级的实时操作系统,每个任务的优先级必须不同,分析它的源码会发现,ucos ii把任务的优先级当做任务的标识来使用,如果优先级相同,任务将无法区分。进入就绪态的优先级最高的任务首先得到CPU的使用权,只有等它交出CPU的使用权后,其他任务才可以被执行。所以它只能说是多任务,不能说是多进程,至少不是我们所熟悉的那种多进程。显而易见,如果只考虑实时性,它当然比分时系统好,它可以保证重要任务总是优先占有CPU。但是在系统中,重要任务毕竟是有限的,这就使得划分其他任务的优先权变成了一个让人费神的问题。另外,有些任务交替执行反而对用户更有利。例如,用单

OllyDBG完美教程

关键词:OD、OllyDBG、破解入门、调试专用工具、反汇编 一、OllyDBG 的安装与配置 OllyDBG 1.10 版的发布版本是个 ZIP 压缩包,只要解压到一个目录下,运行 OllyDBG.exe 就可以了。汉化版的发布版本是个 RAR 压缩包,同样只需解压到一个目录下运行 OllyDBG.exe 即可: OllyDBG 中各个窗口的功能如上图。简单解释一下各个窗口的功能,更详细的内容可以参考 TT 小组翻译的中文帮助: 反汇编窗口:显示被调试程序的反汇编代码,标题栏上的地址、HEX 数据、反汇编、注释可以通过在窗口中右击出现的菜单界面选项->隐藏标题或显示标题来进行切换是否显示。用鼠标左键点击注释标签可以切换注释显示的方式。

寄存器窗口:显示当前所选线程的 CPU 寄存器内容。同样点击标签寄存器 (FPU) 可以切换显示寄存器的方式。 信息窗口:显示反汇编窗口中选中的第一个命令的参数及一些跳转目标地址、字串等。 数据窗口:显示内存或文件的内容。右键菜单可用于切换显示方式。 堆栈窗口:显示当前线程的堆栈。 要调整上面各个窗口的大小的话,只需左键按住边框拖动,等调整好了,重新启动一下 OllyDBG 就可以生效了。 启动后我们要把插件及 UDD 的目录配置为绝对路径,点击菜单上的选项->界面,将会出来一个界面选项的对话框,我们点击其中的目录标签: 因为我这里是把 OllyDBG 解压在 F:\OllyDBG 目录下,所以相应的 UDD 目录及插件目录按图上配置。还有一个常用到的标签就是上图后面那个字体,在这里你可以更改 OllyDBG 中显示的字体。上图中其它的选项可以保留为默认,若有需要也可以自己修改。修改完以后点击确定,弹出一个对话框,说我们更改了插件路径,要重新启动 OllyDBG。在这个对话框上点确定,重新启动一下 OllyDBG,我们再到界面选项中看一下,会发现我们原先设置好的路径都已保存了。有人可能知道插件的作用,但对那个 UDD 目录

嵌入式软件工程师学习指南

嵌入式软件工程师学习 1. 嵌入式软件课程体系 自学嵌入式确实不大现实(当然也不是说没有这个可能),毕竟嵌入式难度也是比较大的。嵌入式的应用主要是几个方向: 一是系统开发:侧重开发环境搭建、内核原理、交叉编译等; 二是嵌入式Linux应用开发:侧重Linux应用编程、内核编译、系统调用; 三是底层驱动开发:侧重嵌入式Linux系统下的驱动开发、内核的深入分析。 不过初进门者主要往系统开发和应用开发发展,有了相关工作经验再进一步向底层驱动靠。 嵌入式课程的目标,想自学完课程,要掌握以下知识点: ◆Linux命令、工具和C编程基础 ◆嵌入式Linux C语言强化 ◆嵌入式Linux上的C编程训练 ◆Linux高级编程及编程训练 ◆嵌入式ARM处理器体系结构及编程训练 ◆嵌入式Linux内核环境搭建和编程训练 ◆嵌入式Linux驱动理论及驱动程序开发训练 ◆Android应用研究和系统开发 ◆Android体系结构和系统移植 ◆嵌入式ARM Linux项目实践和训练 嵌入式软件方面最重要的课程包括: (1)嵌入式微处理器结构与应用 这是一门嵌入式硬件基础课程,我院用这门课取代了传统的“微机原理与接口”课程(目前国内已有少部分高校IT专业这样做了,因为讲x86微机原理与接口很难找到实际用处,只为教学而已)。我们说过,嵌入式是软硬件结合的技术,搞嵌入式软件的人应对ARM 处理器工作原理和接口技术有充分了解,包括ARM的汇编指令系统。若不了解处理器原理,怎么能控制硬件工作,怎么能写出节省内存又运行高速的最优代码(嵌入式软件设计特别讲究时空效率),怎么能写出驱动程序(驱动程序都是与硬件打交道的)?很多公司招聘嵌入式软件人员时都要求熟悉ARM处理器,将来若同学到公司中从事嵌入式软件开发,公司都会给你一本该设备的硬件规格说明书 (xxx Specification),您必须能看懂其中的内存分布和端口使用等最基本的说明(就像x86汇编一样),否则怎么设计软件。有些同学觉得嵌入式处理器课程较枯燥,这主要是硬件课程都较抽象的原因,等我们的嵌入式实验室10月份建好后,您做了一些实验后就会觉得看得见摸得着。还有同学对ARM汇编不感兴趣,以为嵌入式开发用C语言就足够了。其实不应仅是将汇编语言当成一个程序设计语言,学汇编主要是为了掌握处理器工作原理的。一个不熟悉汇编语言的人,怎么能在该处理器写出最优的C 语言代码。在嵌入式开发的一些关键部分,有时还必须写汇编,如Bootloader等(可能还包括BSP)。特别是在对速度有极高要求的场合(如DSP处理器的高速图像采集和图像解压缩),目前主要还要靠汇编写程序(我看到过很多公司是这样做的)。当您在一个嵌入式公司工作时,在查看描述原理的手册时,可能很多都是用汇编描述的(我就遇到过),这是因为很多硬件设计人员只会写或者喜欢用汇编描述,此时您就必须看懂汇编程序,否则软硬件人

OllyICE反汇编教程及汇编命令详解

OllyICE反汇编教程及汇编命令详解[转] 2009-02-11 08:09 OllyICE反汇编教程及汇编命令详解 内容目录 计算机寄存器分类简介 计算机寄存器常用指令 一、常用指令 二、算术运算指令 三、逻辑运算指令 四、串指令 五、程序跳转指令 ------------------------------------------ 计算机寄存器分类简介: 32位CPU所含有的寄存器有: 4个数据寄存器(EAX、EBX、ECX和EDX) 2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP) 6个段寄存器(ES、CS、SS、DS、FS和GS) 1个指令指针寄存器(EIP) 1个标志寄存器(EFlags) 1、数据寄存器 数据寄存器主要用来保存操作数和运算结果等信息,从而节省读取操作数所需占用总线和访问存储器的时间。 32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。 对低16位数据的存取,不会影响高16位的数据。 这些低16位寄存器分别命名为:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。4个16位寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄存器都有自己的名称,可独立存取。 程序员可利用数据寄存器的这种“可分可合”的特性,灵活地处理字/字节的信息。 寄存器EAX通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。可用于乘、除、输入/输出等操作,使用频率很高; 寄存器EBX称为基地址寄存器(Base Register)。它可作为存储器指针来使用; 寄存器ECX称为计数寄存器(Count Register)。 在循环和字符串操作时,要用它来控制循环次数;在位操作中,当移多位时,要用CL来指明移位的位数; 寄存器EDX称为数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址。 在16位CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,在32位CPU中,其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果, 而且也可作为指针寄存器,所以,这些32位寄存器更具有通用性。 2、变址寄存器 32位CPU有2个32位通用寄存器ESI和EDI。 其低16位对应先前CPU中的SI和DI,对低16位数据的存取,不影响高16位的数据。 寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量,

嵌入式系统开发基础1

青岛理工大学琴岛学院计算机系实验教材 Linux嵌入式系统 实验指导书

青岛理工大学琴岛学院计算机科学系 二0一0年四月

前言 随着后PC时代的到来,嵌入式系统技术已经成为了一个万众瞩目的焦点。目前已广泛应用于信息家电、数据网络、工业控制、医疗卫生、航空航天等众多领域。巨大的市场潜力,无穷的商机,吸引了各路英豪纷踵沓来。 硬件方面,各大电子厂商相继推出了自己的专用嵌入式芯片,漫天而至的是mp3,PDA,无线上网装置,让人们充分感受到了这股强劲之势;软件方面,在Vxworks、pSOS、Neculeus 和Windows CE等嵌入式操作系统引领下,也出现了空前繁荣的局面,但这些专用操作系统都是商业化产品,其高昂的价格使许多面向低端产品的小公司望而却步,并且其源代码的封闭性也大大限制了开发者的积极性。 近两年在我国登陆并蓬勃发展的Linux,也已广泛应用于各类计算应用,不仅包括IBM 的微型Linux腕表、手持设备(PDA和蜂窝电话)、因特网装置、客户机、防火墙、工业机器人和电话基础设施设备,甚至还包括了基于集群的超级计算机。Linux在高端服务器的优越表现及其天生具有的突出特点,就注定它必将在低端嵌入式系统中再次给人们以惊喜,而基于嵌入式Linux操作系统的应用,必定给我们未来的工作和生活带来翻天覆地的变化。 Linux价格低廉、功能强大,可以运行在X86,Alpha,Sparc,MIPS,PPC,MOTOROLA,NEC,ARM等硬件平台上,而且开放源代码,可以定制。我们所介绍的硬件平台是基于ARM体系结构,由北京博创兴业科技有限公司开发的UP-CUP 3000 平台、UP-CUP 2410-S 平台系列以及UP-CUP P270A 平台系列实验仪器。UP-CUP 3000 平台的CPU为ARM7TDMI内核的三星 S3C44B0X01芯片,由于没有MMU(内存管理单元)只能运行uClinux,UP-CUP 2410-S 平台系列的CPU为ARM920T内核的三星S3C2410芯片,由于有MMU可以运行标准的ARM-LINUX 内核。UP-CUP P270 平台系列实验仪器为Intel XSCALE ARM10系列CPU。通过这些硬件平台,我们可以学习嵌入式LINUX中的针对有MMU和无MMU的不同开发过程。UP-CUP 3000 平台和UP-CUP P270 平台系列产品及其相关资料可以访问博创公司的网站获得。本书以 S3C2410系列中的UP-CUP S2410 经典平台为例,详细介绍嵌入式 Linux的开发过程。 指导书参考与引用了许多相关资料,在此一并致谢。本指导书仅供内部学生学习使用。由于时间仓促,编者水平有限,书中疏漏之处在所难免,欢迎读者批评指正,并提出宝贵意见和建议,以便不断改进。 编者江艳飞 二0一一年四月 目录

OllyDbg入门完全教程(完美排版)

OllyDbg完全教程 目录 第一章概述 (1) 第二章组件 (5) 一、一般原理[General prnciples] (5) 二、反汇编器[Disassembler] (8) 三、分析器[Analysis] (9) 四、Object扫描器[Object scanner] (12) 五、Implib扫描器[Implib scanner] (12) 第三章 OllyDbg的使用 (13) 一、如何开始调试[How to start debugging session] (13) 二、CPU 窗口[CPU window] (14) 三、断点[Breakpoints] (14) 四、数据窗口[Dump] (15) 五、可执行模块窗口[Executable modules window] (16) 六、内存映射窗口[Memory map window] (17) 七、监视与监察器[Watches and inspectors] (19) 八、线程[Threads] (19) 九、调用栈[Call stack] (20) 十、调用树[Call tree] (21) 十一、选项[Options] (21) 十二、搜索[Search] (22) 十三、自解压文件[Self—extracting (SFX) files] (22) 十四、单步执行与自动执行[Step—by—step execution and animation] (23) 十五、Hit跟踪[Hit trace] (23) 十六、Run 跟踪[Run trace] (24) 十七、快捷键 (26) 十八、插件[Plugins] (29) 十九、技巧提示[Tips and tricks] (29) 第四章其他功能 (30) 一、调试独立的DLL[Debugging of stand—alone DLLs] (30) 二、解码提示[Decoding hints] (32) 三、表达式赋值[Evaluation of expressions] (32) 四、自定义函数描述[Custom function descriptions] (34)

嵌入式软件开发入门教程

C语言是嵌入式软件开发人员必须熟练掌握的编程语言。作为C语言的初学者重点掌握基本数据类型、复合数据类型、流程控制、数组、指针、函数这几方面的基本知识。本人建议通过观看视频教学的方式进行学习,这样既快速又通俗易懂,当然前提是必须找到优质的教学视频资源。此外,可以配合入门书籍谭浩强的《C语言程序设计》进行学习。如果想深入的学习可以参考美国人写的人民邮电出版社出版的《C Primer Plus》。 方法/步骤2: C语言的磨炼 掌握了基本的C语言语法以后并不代表我们就学会了C语言,关键是如何灵活的去运用。我们可以练习编写C语言学习书籍的课后习题或者在网站上搜索C语言笔试题库进行练习。也可以百度寻找经典的C 语言编程案例进行学习。总之,就是将C语言运用的越熟练越好。至于开发环境可以选择VC++ 6.0 或者linux。 方法/步骤3: 硬件电路基础

嵌入式软件工程师还必须懂一些硬件电路的基本知识。当然,对于刚入门的软件开发人员没必要非常精通电路技术,熟悉基本的电子元器件的功能即可。例如,电阻、电容、电感的作用以及符号,三极管、MOS管导通截止的条件,微处理器、晶振的基本概念等。至于,以上这些基本知识我们可以通过童诗白的第四版《模拟电子技术基础》和网上查阅的资料进行学习。 方法/步骤4: 如何看懂原理图 作为嵌入式软件开发人员我们经常会和硬件打交道,我们的程序最终会被烧录到微处理器内部运行。所以,我们必须要会看硬件原理图,看懂之后才知道如何写程序。首先,我们要知道嵌入式硬件最小系统的组成部分,包括电源电路、晶振、微处理器、复位电路。然后以微处理器为中心向四周查看,主要看我们可以操纵的外设资源。以上知识的学习我们不妨经常浏览一下某些知名IT网站其他人上传的经典原理图。 方法/步骤5: 基本外设知识

反汇编 第二节 常用汇编指令

——啊冲 第二节常用汇编指令 说明:汇编语言也是一门语言,其指令相当的多,非常丰富,在此我只介绍几个常用的、简单的汇编指令,让大家与我一同入门。其实在超多的计算机知识领域里我和大家一样只是个学生而已。所以,我所要求的同学级别(本视频所针对的对象)是:有一点编程经验,对反汇编感兴趣、零基础的朋友。 堆栈操作指令PUSH和POP ?格式: PUSH XXXX ?POP XXXX ?功能: 实现压入操作的指令是PUSH指令;实现弹出操作的指令是POP指令. ? 加减法操作add和sub指令 ?格式: ADD XXXX1,XXXX2 ?功能: 两数相加 ?格式: SUB XXXX1,XXXXX2 ?功能: 两个操作数的相减,即从OPRD1中减去OPRD2,其结果放在OPDR1中.

调用和返回函数CALL和RET(RETN) ?过程调用指令CALL ?格式: CALL XXXX ?功能: 过程调用指令 ?返回指令RET ?格式: RET ?功能: 当调用的过程结束后实现从过程返回至原调用程序的下一条指令,本指令不影响标志位. ? 数据传送MOV 格式: MOV XXXX1,XXXX2 ?功能: 本指令将一个源操作数送到目的操作数中,即XXXX1<--XXXX2. ? 逻辑异或运算XOR ?格式: XOR OPRD1,OPRD2 ?功能: 实现两个操作数按位‘异或’运算,结果送至目的操作数中. ? 逻辑或指令OR ?格式: OR OPRD1,OPRD2 ?功能: OR指令完成对两个操作数按位的‘或’运算,结果送至目的操作数中,本指令可以进行字节或字的‘或’运算.

有效地址传送指令LEA ?格式: LEA OPRD1,OPRD2 ?功能: 将源操作数给出的有效地址传送到指定的的寄存器中. ?实际上,有时候lea用来做mov同样的事情,比如赋值: ?Lea edi,[ebp-0cch] ? 字符串存储指令STOS ?格式: STOS OPRD ?功能: 把AL(字节)或AX(字)中的数据存储到DI为目的串地址指针所寻址的存储器单元中去.指针DI将根据DF的值进行自动调整. ?说明:在VC的DEBUG版里经常用来为局部变量空间写上cccccccc指令 ? 比效指令CMP(CoMPare) ?格式: CMP OPRD1,OPRD2 ?功能: 对两数进行相减,进行比较. ?说明:经常与跳转指令相配合来形成循环或跳出操作 ? 跳转指令JXX ?JMP:无条件转移指令

经典嵌入式面试题

经典嵌入式面试题 C语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法。这些年,我既参加也组织了许多这种测试,在这过程中我意识到这些测试能为带面试者和被面试者提供许多有用信息,此外,撇开面试的压力不谈,这种测试也是相当有趣的。 从被面试者的角度来讲,你能了解许多关于出题者或监考者的情况。这个测试只是出题者为显示其对ANSI标准细节的知识而不是技术技巧而设计吗?这个愚蠢的问题吗?如要你答出某个字符的ASCII值。这些问题着重考察你的系统调用和内存分配策略方面的能力吗?这标志着出题者也许花时间在微机上而不上在嵌入式系统上。如果上述任何问题的答案是"是"的话,那么我知道我得认真考虑我是否应该去做这份工作。 从面试者的角度来讲,一个测试也许能从多方面揭示应试者的素质:最基本的,你能了解应试者C语言的水平。不管怎么样,看一下这人如何回答他不会的问题也是满有趣。应试者是以好的直觉做出明智的选择,还是只是瞎蒙呢?当应试者在某个问题上卡住时是找借口呢,还是表现出对问题的真正的好奇心,把这看成学习的机会呢?我发现这些信息与他们的测试成绩一样有用。 有了这些想法,我决定出一些真正针对嵌入式系统的考题,希望这些令人头痛的考题能给正在找工作的人一点帮住。这些问题都是我这些

年实际碰到的。其中有些题很难,但它们应该都能给你一点启迪。 这个测试适于不同水平的应试者,大多数初级水平的应试者的成绩会很差,经验丰富的程序员应该有很好的成绩。为了让你能自己决定某些问题的偏好,每个问题没有分配分数,如果选择这些考题为你所用,请自行按你的意思分配分数。 预处理器(Preprocessor) 1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情: ?; #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) ?; 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。 ?; 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。 ?; 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。

相关主题
文本预览
相关文档 最新文档