利用MC68K的C编译器的μC/OS-II向MC68K移植的实现

发布者:SparklingBeauty最新更新时间:2018-02-07 来源: eefocus关键字:MC68K  C编译器  μC  OS-II 手机看文章 扫描二维码
随时随地手机看文章

    一、MC68K CPU简介

    MC68K及68020、68040等的著名的MOTOROLA32位微处理器,和与之兼容的68K、CPU32、CPU32+等CPU扩充定时处理单元TPU、队列串行模块QSM、系统控制模块和RAM等组成MC683xx系列单片机。

    CPU32 内部有8个32位通用数据寄存器,8个32位通用地址寄存器。8个通用数据寄存器可作为累加器使用,也可看成C语言中各种类型的变量;8个通用地址寄存器,可作为变址寄存器使用,也可看成C语言中的指针型变量。CPU32有独立的用户堆栈指针和系统堆栈指针,可区分程序区、数据区、系统区、用户区等存储空间,有7级中断。


    要实现μC/OS-II向MC68K的移值,需要有MC68K的C编译器。我们使用的HIWARE公司的C编译器。该C编译器允许嵌入行汇编。

    二、移植中所需修改的文件

    和CPU相关的文件主要有三个:C语言文件OS_CPU32.C、头文件OS_CPU32.H和汇编文件OS_CPU32.ASM。

    1.INCLUDES.H文件

    INCLUDES.H 是主头文件,在所有后缀名为.C文件的开始都包含INCLUDES.H文件。对于不同类型的处理器,用户需要改定INCLUDES.H文件,增加自己的头文件,但必须加在文件末尾。在安装μC/OS-II的时候,附带了几个移植实例,例如,针对Intel 80x86的代码安装到IIL目录。我们为MC68K编写的移植实例都放在II下,在INCLUDES.H文件中增加有:

    #include "iiK_CPU32.ASM"

    #include "iiK_CPU32.C"

    #include "iiK_CPU32.H"

    2.OS_CPU32.H文件

    OS_CPU32.H文件中定义了与硬件相关的基本信息:

    typedef unsigned char INT8U; /*无符号8位数*/

    typedef signed char INT8S; /*带符号8位数*/

    typedef unsigned int INT16U; /*无符号16位数*/

    typedef signed int INT16S; /*带符号16位数*/

    typedef signed long INT32S; /*带符号32位数*/

    typedef unsigned int OS_STK; /*堆栈入口宽度为16位*/

    #define OS_STK_GROWTH1 /*堆栈由高地址向低地址增长*/

    #define UCOS 0 /*用于任务切换的软中断*/

    define OS_TASK_SW() _TRAP(UCOS)

    #define OS_ENTER_CRITICAL() move.w#$2700,SR /*进入临界区*/

    #define OS_EXIT_CRITICAL() move.w #$2000,SR /*退出临界区*/

    (1)数据类型

    由于不同的处理器有不同的字长,μC/OS-II的移植需要重新定义一系列的数据结构。由于 MC68K为32位MCU,整数(int)类型数据为16位,长整开有(long)为32位。在MC68K中堆栈都是按字进行操作的,所以堆栈数据类型 OS_STK声明为16位。所有的堆栈必须用OS_STK声明。

    (2)代码临界区

    μC/OS -II在进入系统临界代码区之间要关中断,等到退出临界区后再打开,从而保护核心数据不被多任务环境下的其他任务或中断破坏。在MC68K中,开关中断可以通过设置状态寄存器SR中的中断屏蔽位来实现。μC/OS-II中的宏OS_ENTER_CRITICAL()定义将状态寄存器的中断屏蔽位置位,屏蔽所有的七级中断;OS_EXIT_CRITICAL()定义将状态寄存器的中断屏蔽位清零,打开所有的七级中断。这种处理方法非常简单,但CPU32提供分级中断机制得不到使用。如果要使用分级中断,必须改写一些相关的函数,将在第4节中阐明。

    (3)堆栈方向

    MC68K处理器的堆栈是由高地址向低地址递减的,所以OS_STK_GROWTH必须设置为1。

    (4)OS_TASK_SW()函数的定义

    在μC/OS -II中,OS_TASK_SW()用来实现任务切换。就绪任务的堆栈初始化应该模拟一次中断发生后的样子,椎栈中应该按入栈次序设置好各个寄存器。 OS_TASK_SW()函数模拟一次断过程,在中断返回的进修进行任务切换。CPU32有16个软中断可供选用,称为陷阱TRAP调用。中断程序程序的入口必须指向汇编函数OSCtxSw()。

    我们在μC/OS-II所提供的例程中使用的0号陷阱调用,由下面的语句完成定义:

    #define OS_TASK_SW() -TRAP(UCOS)

    3.OS_CPU32.ASM文件

    μC/OS-II的移植需要用户改写OS_CPU_A.ASM中的4个函数:OSStartHighRdy()、OSCtxSw()、OSINTCtxSw()和OSTICkISR()。

    (1)OSStartHighRdy()函数

    该函数由OSStart()函数调用,功能是运行优先级最高的就绪态任务。在调用OSStart() 之前,用户必须先调用OSInit(),并且已经至少创建了一个任务。为启动任务,OSStartHighRdy()首先找到当前就绪的优先级最高的任务,OSTCBHighRdy中保存有优先级最高任务的任务控制块(TCB)的地址,并从任务的任务控制块中找到指向堆栈的指针,然后运行指令 MOVEM.L(A7)+,A0-A6/D0-D7,从堆栈中弹出全部寄存器的内容,运行RTE中断返回。由于任务创建时堆栈的结构就是按中断捕捞堆栈结构初始化的,执行RET指令后就切换到了新任务。有关μC/OS- II的任务切换机制,请参考系列计座(3).

    OSStartHighRdy的汇编代码如下:

    _OSStarHighRdy

    MOVE.L(_OSTCBHighRdy),A1

    ;获取最高优先级就绪任务的TCB地址

    MOVE.L A1,(_OSTCBCur)

    MOVE.L (A1),A7 ;取得堆栈指针

    MOVEM.L (A7)+,A0-A6/D0-D7

    RTE ;中断返回,切换任务

    (2)OSCtxSw( )函数

    OSCtxSw( )是一个任务级的任务切换函数(在任务中调用,区别于在中断程序中调用的OSIntCtxSw(),在MC68K系统上,通过执行一条软中断指令来实现任务切换。软中断向量指向函数,而该函数的执行结构可能造成系统任务重新调度(例如,试图唤醒一个优先级更高的任务),则在函数的末尾会调用OSSched (),OSSched()将查找当前就绪的优先级最高的任务。如果不是当前任务,则判断是否需要进行任务调度,再找到该任务控制块OS_TCB的地址,并将该地址拷贝到变量OSTCBHighRdy中,然后通过宠OS_TASK_SW()执行软中断,进行任务切换。在此过程中,变量OSTCBCur始终包含一个指向当前运行任务OS_TCB的指针。OSCtxSw()的汇编代码如下:

    _OSCtxSw

    MOVEM.L A0-A6/D0-D7,-(A7) ;存储当前任务环境

    MOVE.L (_OSTCBCur),A1 ;保存当前任务TCB指针

    MOVE.L A7,(A1)

    MOVE.L (_OSTCBHighRdy),A1 ;获取最高优先级就绪任务的TCB地址

    MOVE.L A1,(_OSTCBCur) ;将就绪任务设置为当前运行任务

    MOVE.L (A1),A7 ;取得新任务的堆栈指针

    MOVEM.L (A7)+,A0-A6/D0-D7 ;

    RTE ;中断返回,切换任务

    (3)OSIntCtxSw()函数

    在μC/OS -II中,由于中断的产生可能会引起任务切换,在中断服务程序的最后会调用OSICntExit()函数检查任务就绪状态。如果需要进行任务切换,将调用 OSIntCtxSw(),所以,OSIntCtxSw()又称为中断级的任务切换函数。由于在调用OSIntCtxSw()之前已经发生了中断, OSIntCtxSw()默认CPU寄存器已经保存在被中断任务的堆栈了。OSIntCtxSw()的代码与OSCtxSw()的大部分相同,不同之处是:第一,由于中断已经发生,此处不需要再保存CPU寄存器;第二,OSIntCtxSw()需要调整堆栈指针,去掉堆栈中一些不需要的内容,以使堆栈中包含任务的运行环境。

    _OSIntCtxSw

    ADDA #10,A7 ;忽略掉由于函数嵌套调

    ;用而压入堆栈的内容

    MOVE.L (_CSTCBCur),A1 ;在TCB中保存当前

    ;任务的堆栈指针

    MOVE.L A7,(A1)

    MOVE.L (_OSTCBHighRdy),A1

    ;获取最高优先级就绪任务的TCB地址

    MOVE.L A1,(_OSTCBCur) ;将就绪任务设备为当前

    ;运行任务

    MOVE.L (A1),A7 ;取得堆栈指针

    MOVEM.L (A7)+,A0-A6/D0-D7 ;

    RTE ;中断返回,切换任务

    (4)OSTickISR()函数

    在μC/OS-II中,当调用OSStart()启动多任务环境后,时钟中断非常重要。在时钟中断中处理所有与定时相关的工作,如任务的延时、等待操作等等。在时钟中断中将查询处于等待状态的任务,判断是否延时结束,以重新进行任务调度。

   56

    和μC/OS -II中的其他中断服务程序一样,OSTICkISR()首先在被不断任务堆栈中保存CPU寄存器的值,然后调用OSIntEnter()。ΜC/OS- II要求在中断服务程序开头调用OSIntEnter(),其作用是将记录中断嵌套层数的全局变量OSIntNesting加1。如果不调用 OSIntEnter(),直接将OSIntNesting加1也是允许的。随垢,OSTickISR()调用OSTimeTick(),检查所有处于延时等待状态的任务,判断是否有延时结束并就绪的任务。在OSTickISR()的最后调用OSIntExit(),如果在中断中(或其他嵌套的中断)有更高优先级的任务就绪,并且当前中断为中断嵌套的最后一层,OSIntExit()将进行任务调度。注意,如果进行了任务调度,OSIntExit()将不再返回调用者,而是用新任务堆栈中的寄存器数值恢复CPU现场,然后用RTE实现任务切换。如果当前中断不是中断嵌套的最后一层,或中断中没有改变任务的就绪状态,OSIntExit()将返回调用者OSTickISR(),最后OSTickISR()返回被中断的任务。

    4.OS_CPU32.C文件

    μC/OS-II的移值需要用户在OS_CPU32.C中定义6个函数,而实际上需要定义的只有OSTaskStkInit()一个函数,其他5个函数需要声明,但不一定有实际内容。这5个函数都是用户定义的,所以OS_CPU32.C中没有给出代码。如果用户需要使用这些函数,请将文件OS_CDG.H中的#define constant OS_CPU_HOOKS_EN设为1,设为0表示不使用这些函数。

    OSTaskStkInit ()函数由任务创建函数OSTaskCreate()或OSTaskCreateExt()调用,用来初始化任务的堆栈。初始状态的堆栈模拟发生一次中断后的堆栈结构。按照中断后的进栈次序预留各个寄存器的存储空间,而中断返回地址指向任务代码的起始地址。当调用OSTaskCreate()或 OSTaskCreateExt()创建一个新任务时,需要传递的参数是:任务代码的起始地址、参数指针、任务堆栈顶端的地址、任务的优先级。 OSTaskCreateExt()还需要一些其他参数,但与OSTaskStkInit()没有关系。OSTaskStkInit()只需要以上提到的 3个参数:task、pdata、ptos。由于MC68K堆栈是16位宽的(以字为单位),OSTaskStkInit()将创立一个指向以字为单位的内存区域的指针,同时要求堆栈指针指向空堆栈的顶端。堆栈初始化工作结束后,OSTaskStkInit()返回新的堆栈顶指针, OSTaskCreate()或OSTaskCreateExt()将指针保存在任务的OS_TCB中。

    三、移植中的几点注意事项

    由于μC/OS-II运行的实时性,调试内核几乎不可能。一旦移植过程中内核运行不稳定,很难确定是什么地方的问题,更困难的是有些现象几乎是不可重复的。这就需要详细了解内核运行机理,认真分析,找出可能存在的问题。下面就来分析这些移植过程中的问题。

    1.编译器的优化选项

    在移植过程中,除了要熟悉μC/OS-II和目标芯片之外,熟悉使用的C编码器也非常重要。通常C编译器都会提供一些优化代码的选项,在移植μc/OS-II的过程中,这些选项往往会带来麻烦。下面是移植中与HIWARE的C编译器有关的例子。

    通常在调用子程序或进入中断时,C编译器会自动保存CPU内部寄存器到堆栈中。例如,在进入中断时编译器会加入下面2条指令:

    LINK #$0000,A6;

    MOVEM.L D0/D1/D3/D4/D5/D6/D7/A0/A1/A2/A3/A4/A5,-(A7);

    这2 条汇编指令的作用是将CPU的数据寄存器D0~D7、地址寄存器A0~A5保存到堆栈中,再将此时的堆栈指针A7也保存到堆栈中,并使用A6作为临时的堆栈指针。这本是一个非常好的优化选项,可以防止在中断中偶然地更改了数据寄存器或地址寄存器;但在μC/OS-II中,这个机制将对OS_CPU_C.C 和OS_CPU_ASM.ASM中的几个子程序和中断服务例程产生致命的影响。

    OS_CPU_C.C和OS_CPU_ASM.ASM中的子程序中断引发任务调度,当前的任务被挂起。挂起任务是通过下面的语句来完成的:

    MOVEM.L A0-A6/D0-D7,-(A7);

    MOVE.L @OSTCBCur,A2;

    MOVE.L (A2),A1;

    MOVE.L A7,(A1);

    保存任务的指针和所有数据地址寄存器的值,那么理想情况下,此时的任务堆栈应该是如图1所示的情况(以OSCtxSw()函数为例,可以对应到OS_CPU_C.C和OS_CPU_ASM.ASM中的其他函数和中断处理例程)。

    那么恢复挂起的任务时,只要通过如下语句:

    MOVE.L OSTCBHighRdy,A1;

    MOVE.L @OSTCBCur,A2;

    MOVE.L A1,(A2);

    MOVE.L (A1),A7;

    MOVEM.L (A7)+,A0-A6/D0-D7;

    将保存在任务TCB中的任务堆栈指针恢复,再恢复数据地址寄存器,最后执行OSCtxSw()的中断返回,就可以顺利地恢复被挂起的任务。

    如果C编译器在OSCtxSw()函数入口处插入了2条保存数据地址寄存器和堆栈指针的语句后,再执行挂起任务的语句,任务的堆栈会变成图2所示的情况。编译器引起了堆栈的变化,如果所有的任务都是用这种方式挂起和恢复的,并不会产生致命的问题,因为编码器退出OSCtxSw()函数时会插入如下语句恢复堆栈:

    MOVEM.L (A7)+,D0-D7/A0-A5;

    UNLK A6;

    问题在于初始化任务的时候,每个任务实际上是按照图1所示的堆栈结构被初始化的,那么,按照图2的堆栈结构来恢复自然会导致堆栈崩溃。

    解决这个问题的方法很多,可以改定任务初始化的代码以适应C编译器的这个“优化”,也可以在进入OSCtxSw()函数时首先调用如下语句恢复堆栈,抵消C编码器的影响:

    MOVEM.L (A7)+,D0-D7/A0-A5;

    UNLK A6;

    而在退出OSCtxSw()函数前再调用如下语句模拟出更动的堆栈:

    LINK #$0000,A6

    MOVEM.L D0-D7/A0-A5,-(A7);

    较好的方法当然是调整编译器,取消这个优化选项。如果无法调整编译器,就只有用以上办法来适应编译器了。

    2.开关中断的方法

    在μC/OS -II中,开关中断是非常重要的,它可以保证关键代码或访问全局变量时不受中断的意外影响。CPU32的中断控制比较复杂,提供了7级具有不同级别的中断;可以选择关闭或打开某几级中断。但多级中断会使得μC/OS-II的中断处理变得复杂。在简单的应用或初次尝试移植μC/OS-II时,可以使用全开全关的方法。

 

    如果考虑多级中断,必须注意到中断开关级别的控制是一个重要的信息,在关闭中断之前需要将这个信息保存起来,在对应的开中断时恢复这个中断级别控制信息。最容易想到的方法是用一个全局变量存存这个信息。

    使用这个方法的程序如下:

    #define OS_EXIT_CRITICAL() asm move SR_TEMP,sr;

    #define OS_ENTER_CRITICAL() asm move.w SR,SR_TEMP;

    asm ori.w #0x0700,SR;

    接着构造两个任务,每个任务分别向屏幕输出一句话,同时修改内核的代码,让空闲任务也输出一句话。运行内核,通常在几分钟内会发现内核停止调试,只有空闲任务不停地向屏幕输出。这种情况非常麻烦,因为根据无法通过调试手段判断何时何处导致内核停止调度。

    分析一下,当只有空闲任务运行时,代码为:

    move.w sr,sr_temp

    ori.w #0700,sr

    addi.1 #1,OSIdleCTR

    move.w sr_temp,sr

    jmp ****

    这5句语句在循环运行,而中断(这时只有定时中断)可以在任意一句语句中间切入。那么,如果在MOVE.W SR,SR_TEMP的时候产生了中断,就会执行中断(因为正要关中断,但还没有关上);而中断程序调用的OSIntENTER和OSIntEXIT都会调用 OS_ENTER_CRITICAL()来关闭中断,递增中断嵌套层数全局变量。这时,再次执行MOVE.W SR,SR_TEMP变量就被改写成关中断的值,当从中断返回到IDLE任务执行MOVE.W SR_TEMP,SR时,就关闭了中断,而不是恢复原来的状态寄存器。这样就导致内核无法响应中断,无法调度任务,只有IDLE任务在运行。

    如何解决?最容易想到的方法是再增加一个全局变量,用来保存进入中断时的中断开关信息,退出中断恢复这个信息;但如果考虑到中断嵌套,相同的情况又出现了,并且如果一个任务在执行MOVE.W SR,SR_TEMP时被中断打断并且发生了任务调度,那么当个任务恢复时,它使用的中断信息SR_TEMP可以已经是被其他任务更改后的值了。内核无法响应中断,无法调度的任务可能依然存在。

    给每个任务和中断都定义一个这样的全局变量,在不考虑中断嵌套的情况下似乎可以解决问题,但想象一下为每一个任务和中断提供一个单独的OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()函数所带来的工作量。显然这不一个好办法。

    将中断信息推入堆栈是一个好主意,但我们会看到由此带来的一些更加隐蔽而复杂的问题。实现这个方法的程序代码如下:

    #define OS_ENTER_CRITICAL() asm move SR,-(A7);

    asm ori.w #0x0700,SR;

    #define OS_EXIT_CRITICAL() asm move (A7)+,sr;

    这样,每次调用OS_ENTER_CRITICAL(),都将当前的中断开关信息保存到当前任务堆栈或系统堆栈中断OS_EXIT_CRITICAL()时,恢复这个信息。

    使用了这个方法后,必须小心地计算堆栈的使用情况,修改OS_CPU_A.ASM和 OS_CPU_C.C文件里的函数。以OSINTCtxSw()函数为例,这个函数将导致中断级的任务调度,即被中断打断的程序不能继续运行,退出中断中另一个优先级更高的任务得以运行。在这个函数中必须对被中断的任务堆栈进行清理,使得这个任务的堆栈看起来和一次正常的任务切换后的情况相同,这样,才能保证这个任务被正确地恢复运行。OSIntCtxSw()函数仅仅在 OSICntExit()函数中被调用。

    须指出的是,在中断发生时,CPU32已经将全部的寄存器和状态寄存器,PC指针内容保存到了堆栈中,这样已经为被打断的任务的恢复作好了准备。如果按照正常的中断流程,在退出中断时,被打断的任务应该恢复运行。现在,由于执行了中断级的任务切换,被打断的任务不能立刻恢复,而是被挂起,这就要求在执行任务调度前调整堆栈,使得被中断打断的任务处于随时可以被恢复的状态。

    在中断处理程序中,当执行到OSIntExit()时,堆栈的情况和刚刚进入中断还是相同的,是能够随时恢复被打断的任务的情况。那么,只需要忽略 OSIntExit()函数造成的堆栈变化。首先,是OSIntExit()函数本身的返回地址,长度为2个字;调用OS_ENTER_CRITICAL ()压入堆栈的状态寄存器,长度为1个字;最后,是OSIntCtxSw()函数的返回地址,长度为2个字。那么在OSIntCtxSw()进行任务切换时,首先要把这5个字的堆栈的内容清除,才能保证被中断任务的正确恢复。该语句如下:

    ADDA #10,A7;

    在完成了这些调整后,由于开关中断可能导致的内核调度死锁的可能已经不存在了。但是在这种情况下,另一个更加隐蔽的问题会出现,这个问题又是和使用的C编码器相关的。

    问题出现在使用OSSemPend()函数时,一旦调用这个函数,CPU就会出现地址错误而进入异常处理,内核被终止。这个问题相当奇怪,因为, OSSemPend()函数完全是一个C语言写成的子函数,函数本身不应出现地址错误。通过阅读编译器编译出来的目标码发现了问题。EmPend()函数,发现这个函数没有任何局部变量。在进入OSSemPend()函数时,编译器不需要产生LINK指令来提供局部变量空间。所有的参数都是使用带偏移量的地址寄存器间接寻址方式直接从堆栈中取得,而且使用的地址寄存器就是A7寄存器。问题可能就在这里,OS_ENTER_CRITICAL()和 OS_EXIT_CRITICAL()对堆栈的操作都会调整A7寄存器,这就会导致下面的语句在利用A7作寄存器间接寻址时发生错乱,出现地址错误。

    这需要详细研究编译器的特性。我们使用的HIWARE的编译器实际上已经考虑到了这一点,当调用 OS_ENTER_CRITICAL()或 OS_EXIT_CRITICAL()函数更加了A7寄存器后,使用A7的地址寄存器间接寻址也会做出相应的调整,保证仍然能够得到函数调用时传递的变量。每出现一个OS_ENTER_CRITICAL(),接下来的A7寄存器间接寻址的偏移量就会加2;每出现一个OS_EXIT_CRITICAL (),接下来的A7寄存器间接寻址的偏移量就会减2。但是问题却依然存在,对OSSemPend()的调用会导致地址错误,这应该是一个更深层次的错误。

    这个问题的解决方法是:定义一个局部变量,迫使编译器生成LINK指令,构造内部参数寻址指针A6,这样调用OS_ENTER_CRITICAL()或OS_EXIT_CRITICAL()时,更动的只是A7,而对参数寻址用的是A6,不受影响。

    如果强迫编译器在调用函数时都加上LINK和UNLINK指令也可以解决这个问题,但是又会面临最先提到的编译器的优化选项问题。可以看出,编译器的特性对移植μC/OS-II是非常重要的,并且往往这些特性是相互制约的。

    在移植和运行μC/OS-II的过程中,也许还会有新的问题出现,遇到问题时只要仔细分析,分析堆栈的使用、中断的影响,分析编译生成的代码,就可以实现μC/OS-II的稳定可靠运行.


关键字:MC68K  C编译器  μC  OS-II 引用地址:利用MC68K的C编译器的μC/OS-II向MC68K移植的实现

上一篇:基于嵌入式技术的远程网络控制温控系统设计
下一篇:基于MIPS处理器内核的通用MPU

推荐阅读最新更新时间:2024-03-16 15:54

基于TMS320C6455的视频动目标检测装置设计
摘要:介绍一种基于高速DSP芯片TMS320C6455构建的视频动目标检测装置,有效地利用6455的大容量内存空间等特点,采用EDMA功能实现了高速数据传输的乒乓缓冲结构设计,软件设计是基于背景更新的动目标检测算法,测试结果证明该装置功能完备,实时性好,环境适应性强,在实时监控等领域有很大的应用前景。 关键词:动目标检测;背景更新;TMS320C6455;SAA7113H 视频动目标检测与跟踪技术是当今世界重要的研究课题,它涉及图像处理、自动控制、计算机应用等学科,广泛应用于军事领域的各个方面:预警、火控、制导等;在民用领域的应用也随着该技术的日益成熟,以及成本的大幅度下降而逐渐得到越来越广泛的推广。 所谓视频动目标
[嵌入式]
基于TMS320<font color='red'>C</font>6455的视频动目标检测装置设计
iPhone 6c电池现身! 1715mAh容量不及6
    今日外国媒体公布了一张图片,图片上显示的是iPhone 6C的电池,根据电池上的标识,我们可以知道Phone 6C拥有 1715 mAh 的容量,高于 iPhone 5c 的 1507mAh,却不及 iPhone 6 的 1810mAh,因此体积上也会相对小一些。   据此前消息,我们可能在即将到来的苹果发布会上见到iPhone 6S,不过一个发布会只发布一个产品似乎不太可能,根据如今爆出关于iPhone 6C的消息,我们推测发布会上iPhone 6C很有可能亮相。   此外外媒还表示下一代的iPhone将会采用升级的的零部件,并且将生产的重心放在升级后的零部件上面,下一代iPhone将会得益于升级的部件,续航时间将
[手机便携]
C64x系列DSP/BIOS中设备驱动程序的设计
摘要:为了高效地对外部设备进行控制,给硬件设备编写驱动程序是一种有效的解决方法。C64x系列的DSP系统提出了类/微型驱动模型的驱动程序结构。实践结果表明,采用类/微型驱动模型进行驱动程序设计后,应用软件可以复用绝大部分相似设备的驱动程序,因而极大地提高了驱动程序的开发效率。 关键词:数字信号处理器 I/O设备驱动 类/微型驱动模型 实时操作系统 随着新技术的不断涌现和DSP实时系统的日趋复杂,不同类型的外部设备越来越多。为这些外部设备编写驱动程序已经成为依赖操作系统管理硬件的内在要求。但是,由于内存管脚、响应时间和电源管理等条件的限制,为一个给定的DSP系统编写设备驱动程序有时候会很困难。针对设备驱动程序开发者遇到的上述难
[应用]
白带变细丝 中国提供机三星C9工信部谍照曝光
    如果不出意外,本月三星要发布一款专为中国市场打造的神机,它的有些待遇可是比Note 7规格都高。   现在工信部已经出现了三星这款旗舰神机的配置和外形信息,其外形亮点主要集中在背部,虽然还是三段式设计,但原先突兀的大白条被换成了三条很细的细线,跟OPPO即将发布的R9s处理方式一致(MSA微缝天线工艺),而这样出来的视觉效果更好也更统一。   配置方面,三星C9机身厚度6.9mm,整机重约185g(背部金属材质),配备6寸1080p屏,内置的电池是4000mAh容量,支持全网通,而它还会是首款配备6GB内存的三星手机,完全满足国人的需求。   此外,三星这款6GB内存新机搭载的处理器型号应该骁龙653,相比骁
[手机便携]
TDK推出为USB-C提供完整ESD保护的超紧凑型TVS二极管
TDK株式会社 针对USB-C端口和其他高速接口的ESD保护应用推出一款超紧凑型TVS二极管。 对于USB-C等符合USB4(第1版)规范且传输速度高达40 Gbit/s的高速接口 (Tx / Rx),ESD保护应用特别需要具有超低寄生电容和低钳位电压的TVS二极管。新的B74111U0033M060和B74121U0033M060型元件的在1 MHz条件下的寄生电容分别为0.48 pF和0.65 pF,钳位电压仅为3.8 V或3.9 V,ITLP为8 A,不会干扰信号完整性,因此非常适合此类应用。这些TVS二极管保护元件的设计ESD放电电压高达15 kV,并采用超紧凑的WLCSP 01005和WLCSP 0201扁平结构封装,高
[电源管理]
TDK推出为USB-<font color='red'>C</font>提供完整ESD保护的超紧凑型TVS二极管
s3c2440学习之路-007uart的简单配置
1.基本知识 串口算是各种芯片最基本的功能之一,串口配置好后程序就可以通过串口来打印各种信息,方便代码的调试。 串口最主要的参数有4个:波特率,数据宽度, 校验位,停止位 常用的串口配置为:波特率115200,8bit数据宽度,无校验位,1bit停止位,通常缩写为115200 8N1 2440有3组UART, 每组UART都有2个64Bytes 的FIFO jz2240使用的串口0与电脑通信,之间通过PL2303来转换电脑和开发板之间的逻辑电平。 2.主要寄存器 2.1 GPHCON & GPHUP 串口需要用的Pin脚就3个:Tx,RX,GND, 因此首先需要把对应的Pin设置为TX,RD模式,除此外,还需
[单片机]
s3<font color='red'>c</font>2440学习之路-007uart的简单配置
C51语言中断函数结构,C51中断函数的写法
1、一、中断允许控制CPU 对中断系统所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器IE 控制的。EX0(IE.0),外部中断 0 允许位;ET0(IE.1),定时/计数器 T0 中断允许位;EX1(IE.2),外部中断 0 允许位;ET1(IE.3),定时/计数器 T1 中断允许位;ES(IE.4),串行口中断允许位;EA (IE.7), CPU 中断允许(总允许)位。80C51 单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD 用于设置其工作方式;TCON 用于控制其启动和中断申请。一、工作方式寄存器 TMOD工作方式寄存器 TMOD 用于设置定时/计数器的工作方式,低四位用于。 2、 T0,高四位用于 T
[单片机]
基于增强型80C51内核的超低功耗安全MCU——RJM8L003系列
RJM8L003系列是基于增强型 80C51内核,专为电池供电的物联网终端而设计的超低功耗安全MCU。丰富完善的功能安全特性,内置硬件真随机数发生器。集成12位高精度逐次逼近型ADC,符合国家密码管理局《随机数检测规范》标准。已大量应用到烟雾报警器、LoRa模组、智能门锁、灯控设备、GPS定位器、安防探测器、电子烟等应用领域。 RJM8L003 功能特性 RJM8L003基于增强型哈佛架构的CPU内核和多级流水线指令系统,主频16MHz,4KB SRAM,32KB FLASH。相同时钟频率的处理性能是传统8051的3倍,采用 Keil uVision4或IAR集成开发环境开发调试应用代码。 RJM8L003系统
[单片机]
基于增强型80<font color='red'>C</font>51内核的超低功耗安全MCU——RJM8L003系列
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved