Microsoft Windows CE .NET 中的中断体系结构

概述

通过 Microsoft Windows CE .NET,Microsoft 已经升级了 Windows CE 的中断体系结构。该操作系统 (OS) 所具有的处理共享中断的能力极大地扩展了 Windows CE .NET 支持许多中断体系结构的能力。本文从原始设备制造商 (OEM) 和应用程序开发人员的角度探讨了处理中断的方案。本文还探讨了 OEM 适配层 (OAL) 中断服务例程 (ISR) 处理;提供了可安装 ISR,包括一个简单的入门级外壳程序;介绍了中断服务线程 (IST) 中断处理,并提供了一个初始化和执行模板。最后,本文分析了 ISR 和 IST 的延迟根源。

返回页首

中断体系结构

探讨 Microsoft Windows CE .NET 中断体系结构的第一步是定义中断过程中硬件、内核、OAL 和线程交互的总体模型。下图大概说明了这些不同级别的职责以及导致状态变化的转换。

winceinterruptarch_fig1

图 1.

该图阐述了中断过程中的主要转换,时间按从左到右的顺序递增。该图的最低层为硬件和中断控制器的状态。次低层是中断服务过程中的内核交互。OAL 描述了主板支持软件包 (BSP) 的职责。最顶层阐述了中断服务所需的应用程序或驱动程序线程交互。该图阐述了单个中断过程中的交互;它表示了 Windows CE .NET 拥有共享中断的新能力。

活动从该图最左侧部分以直线表示的中断开始。生成了一个异常,导致内核 ISR 向量被加载到处理器中。内核 ISR 与硬件交互,禁用所有处理器上的所有具有相同和较低优先级的中断(ARM 和 Strong ARM 体系结构除外)。然后,内核推进到已为该特定中断注册的 OAL ISR。此后,OAL ISR 既可以直接处理中断,也可以使用 NKCallIntChain 遍历已安装的 ISR 列表。主 ISR 或任何已安装的 ISR 随后执行任意工作,并且为该设备返回名为 SYSINTR 的映射中断。如果该 ISR 确定其相关设备没有导致该中断,该 ISR 将返回 SYSINTR_CHAIN,这会使 NKCallIntChain( ) 遍历 ISR 列表以到达链中的下一个中断。ISR 按照它们的安装顺序调用(它们在安装时会在调用列表上创建一个优先级)。

在调用了单个 ISR 或其相关 ISR 链之后,返回值可能为下列值之一:

返回值

操作

SYSINTR_NOP

中断不与设备的任何已注册 ISR 关联。内核启用所有其他中断。

SYSINTR

中断与已知的已注册 ISR 和设备关联。

SYSINTR_RESCHED

中断是由请求 OS 重新调度的计时器到期引起的。

SYSINTR 返回值是我们讨论的重点。一旦 ISR 完成,内核将重新启用处理器上除已识别的中断之外的所有中断。然后,内核将通知与 SYSINTR 值关联的事件。

然后,驱动程序或应用程序的 IST 将能够运行(假设它是准备好运行的最高优先级线程)。IST 将与相关设备通讯,并从完成它的中断交互的设备中读取所有必要的数据。然后,IST 用关联的 SYSINTR 值来调用 InterruptDone( ),以通知它已完成。

内核在接收到 SYSINTR 值的 InterruptDone 时,将重新启用指定的中断。只有从这时开始,才能接收该设备的其他中断。

这只是对 Windows CE .NET 内部活动的中断序列的一个粗略介绍。现在,我们将详细研究上述每个组件及其职责。

返回页首

OAL ISR 处理

OAL ISR 是属于平台的基本中断处理程序。下面是 X86 平台的实际 ISR。配置分析和 ILTiming 支持已被删除。X86 ISR 是所有基于 Windows CE 的平台的代表。它演示了能够处理系统中所有中断的单个 ISR。

该 ISR 的目标是向内核交还引起中断的相关设备的 SYSINTR 号。ISR 执行以下活动序列。

  • PICGetCurrentInterrupt (PIC) 中获取当前硬件中断

  • 如果该中断是 INTR_TIMER0(系统计时器)

    • 更新OS 的 CurMSec 保持时间

    • 检查并确认是否已经注册了重新启动地址 (RebootHandler)

  • 如果中断是 INTR_RTC

    • ISR 检查并确认闹钟是否已到期 (SYSINTR_RTC_ALARM)

  • 如果中断小于 INTR_MAXIMUM

    • 调用中断链 (NKCallIntrChain)

    • NKCallIntrChain 的返回值设置为该返回值

    • 如果中断链未包含中断:(SYSINTR_CHAIN)

      映射当前硬件中断 (OEMTranslateIRQ)

      如果该中断被注册到 OEMInit 中的 HookInterrupt

      OEMTranslateIRQ 返回 SYINTR

      如果该中断未注册,则返回 SYSINTR_NOP

    • 启用除当前中断以外的所有中断。(PICEnableInterrupt}

    • 完成恰当的中断结束工作以通知 PIC 中断已完成 (EOI)

  • ISR 返回下列值之一:

    • SYSINTR_NOP — 没有任何 ISR 包含该中断

    • SYSINTR_RESCHED — 重新调度计时器已到期

    • SYSINTR — ISR 已经包含该中断

    • SYSINTR_RTC_ALARM — 闹钟已到期

ULONG PeRPISR(void)
{
ULONG ulRet = SYSINTR_NOP;
UCHAR ucCurrentInterrupt;
ucCurrentInterrupt = PICGetCurrentInterrupt();
if (ucCurrentInterrupt == INTR_TIMER0) {
CurMSec += SYSTEM_TICK_MS;
CurTicks.QuadPart += TIMER_COUNT;
if ((int) (CurMSec - dwReschedTime) >= 0)
ulRet = SYSINTR_RESCHED;
}
//
// Check if a reboot was requested.
//
if (dwRebootAddress) {
RebootHandler();
}
} else if (ucCurrentInterrupt == INTR_RTC) {
UCHAR cStatusC;
// Check to see if this was an alarm interrupt
cStatusC = CMOS_Read( RTC_STATUS_C);
if((cStatusC & (RTC_SRC_IRQ)) == (RTC_SRC_IRQ))
ulRet = SYSINTR_RTC_ALARM;
} else if (ucCurrentInterrupt <= INTR_MAXIMUM) {  
// We have a physical interrupt ID, return a SYSINTR_ID
// Call interrupt chain to see if any installed ISRs handle this
// interrupt
ulRet = NKCallIntChain(ucCurrentInterrupt);
if (ulRet == SYSINTR_CHAIN) {
ulRet = OEMTranslateIrq(ucCurrentInterrupt);
if (ulRet != -1)
PICEnableInterrupt(ucCurrentInterrupt, FALSE);
else
ulRet = SYSINTR_NOP;
} else {
PICEnableInterrupt(ucCurrentInterrupt, FALSE);
}
}
if (ucCurrentInterrupt > 7 || ucCurrentInterrupt == -2) {
__asm {
mov al, 020h    ; Nonspecific EOI
out 0A0h, al
}
}
__asm {
mov al, 020h        ; Nonspecific EOI
out 020h, al
}
return ulRet;
}

如果 ISR 没有为已经用 OAL 的 OEMInit 中的 HookInterrupt 初始化的中断安装,则该 ISR 将返回适当的 SYSINTR 值。

如果只能通过 IST 交互为设备提供服务,则不需要为中断安装可安装的 ISR。通过对 OALOEMInit 中的 HookInterrupt 进行调用以启用中断就足够了。

ISR 代码是一段非常小且快速的代码。它的执行时间将直接影响整个系统中的中断的延迟。Windows CE 3.0 中引入的中断体系结构更改是能够嵌套中断。在进入 OAL ISR 的那一刻,所有具有较高优先级的中断都已被启用。ISR 可能被占先。如果该 ISR 内部的计时非常关键,则可能要求在该时间段内禁用中断。就像 ISR 执行时间一样,中断被关闭的这一时间将增加平台的最差情形延迟。

当 ISR 交还与特定设备相关的 SYSINTR 时,内核将通知 IST 醒来。处理驱动程序或应用程序内部代码的 IST 中断负责结束中断交互。

返回页首

可安装的 ISR

可安装的 ISR 是为响应 Windows CE .NET 为嵌入式空间带来的开放性而创建的。OEM 再也不必完全负责平台和应用程序代码了。现在平台提供商和应用程序开发人员都可涉及嵌入式空间这一领域的工作。如果某个应用程序开发人员在使用 Windows CE 3.0 的平台上向开放总线添加了新的设备,OEM 将必须说服该 OEM 将 ISR 添加到该平台。

要将 ISR 安装到平台中,需要完成两个步骤:

  • 调用 LoadIntChainHandler 函数以加载包含 ISR 代码的 DLL。

  • 必须将 ISR 编码为用 SYSINTR_ . . . 响应进行响应,就像在 OAL ISR 中一样。

LoadIntChainHandler 函数将 ISR 动态链接库 (DLL) 加载到内核的地址空间中。这意味着代码不能调用任何非内核函数,包括任何 C 语言运行时库函数。记住,某些结构到结构赋值会降格为 memcpy 调用,必须检查所有代码以确保不需要任何外部库(即使这些库是由编译器创建的)。

下面的源代码示例说明了一个用于创建可安装的 ISR 的基本外壳程序。有四个函数:

  • DLLEntry — 接收进程和线程附加消息

  • InfoCopy — 在进行任何结构赋值时使用的复制例程

  • IOControl — 任何使用 KernelLibIOControl 的 IST 调用的处理程序

  • ISRHandler — 实际的 ISR

BOOL __stdcall  DllEntry(   HINSTANCE hinstDll,
DWORD dwReason,
LPVOID lpReserved )
{
if (dwReason == DLL_PROCESS_ATTACH) {}
if (dwReason == DLL_PROCESS_DETACH) {}
return TRUE;
}
// The compiler generates a call to memcpy() for assignments of large 
objects.
// Since this library is not linked to the CRT, define our own copy 
routine.
void  InfoCopy( PVOID  dst, PVOID  src, DWORD size  )
{
while (size--) {
*((PBYTE)dst)++ = *((PBYTE)src)++;
}
}
BOOL IOControl(     DWORD   InstanceIndex,
DWORD   IoControlCode, 
LPVOID  pInBuf, 
DWORD   InBufSize,
LPVOID  pOutBuf, 
DWORD   OutBufSize, 
LPDWORD pBytesReturned ) 
{
switch (IoControlCode) {
case IOCTL_DEMO_DRIVER:  
// Your I/O Code Here
return TRUE;
break;
default:
// Invalid IOCTL
return FALSE;
}
return TRUE;
}
DWORD   ISRHandler(  DWORD InstanceIndex  )
{
BYTE  Value;
Value = READ_PORT_UCHAR((PUCHAR)IntrAddress );
// If interrupt bit set, return corresponding SYSINTR
if ( Value & 0x01 )
{
return SYSINTR_DEMO;
}
else
{
return SYSINTR_CHAIN;
}
}

ISR 处理程序代码使用端口 I/O 调用来检查设备的状态。您的方案可能要求复杂得多的询问。如果该设备不是中断源,则返回值将是 SYSINTR_CHAIN。此返回值告诉 NKChainIntr 函数该设备不是中断源,应该评估链中的其他 ISR。如果 ISR 返回有效的 SYSINTR,则 NKChainIntr 将立即返回并且不调用列表中的任何其他 ISR。这将提供优先级排序。第一个加载的可安装 ISR 被首先加载到该列表中(或具有最高优先级),然后将后续可安装 ISR 添加到该列表的底部。由于优先级和执行速度这两方面的原因,应该首先安装链中具有最高优先级的可安装 ISR。

返回页首

IST 中断处理

处理来自应用程序或驱动程序的中断需要进行两个步骤的处理。首先,必须使用关联的事件初始化中断。其次,IST 必须等待中断事件以响应内核中的中断。

中断初始化

以下示例代码将设置 IST 并将 IST 与特定的中断相关联。初始化中断的关键步骤包括:

  • 创建事件

  • 获取 IRO 的系统中断号

  • 创建挂起的中断线程 (IST)

  • 调用 InterruptInitialize 以创建 IRQ 与事件之间的关联

    • 创建未挂起的 IST 可能会导致 InterruptInitialize 失败,因为该事件已经处于被等待状态

  • 将线程优先级设置为相应的优先级

  • 恢复 IST

Void SetupInterrupt( void )
{
// Create an event
//
g_hevInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hevInterrupt == NULL) 
{
RETAILMSG(1, (TEXT("DEMO: Event creation failed!!!\r\n")));
return;
}
// Have the OAL Translate the IRQ to a system irq
//
fRetVal    = KernelIoControl( IOCTL_HAL_TRANSLATE_IRQ, 
&dwIrq,
sizeof( dwIrq ),
&g_dwSysInt,
sizeof( g_dwSysInt ),
NULL );
// Create a thread that waits for signaling
//
g_fRun  = TRUE;
g_htIST      = CreateThread(NULL,  // Security
0,     // No Stack Size
ThreadIST,  // Interrupt Thread                NULL,    // No
Parameters
CREATE_SUSPENDED, // Create Suspended
&dwThreadID  // Thread Id
);
// Set the thread priority – arbitrarily 5
//
m_nISTPriority = 5;
if( !CeSetThreadPriority( g_htIST, m_nISTPriority ))
{
RETAILMSG(1,(TEXT("DEMO: Failed setting Thread Priority.\r\n")));
return;
}
// Initialize the interrupt
//
if ( !InterruptInitialize(g_dwSysInt,g_hevInterrupt,NULL,0) ) 
{
RETAILMSG (1, (TEXT("DEMO: InterruptInitialize failed!!!\r\n")));
return;
}
// Get the thread started
//
ResumeThread( g_htIST );
}

需要注意的是,对 InterruptInitialize 的调用仅采用 SYSINTR 值和事件作为参数。内核不知道或者不关心将要等待该事件的线程。这样,就可以建立多种应用程序和驱动程序体系结构。应用程序的简单主循环可以初始化中断,然后立即等待该事件。中断只能与一个事件关联,并且该事件不能用于对 WaitForMultipleObjects 的调用中。我们将观察一个简单的为中断提供服务的线程。这是大多数实现中的标准解决方案。

IST - 中断服务例程

本节提供了一个 IST 的示例代码。该 IST 中断处理线程的关键组件包括:

  • 等待中断事件。

  • 确认有一个来自 OS 的脉动性事件

  • 执行任何必要的板级中断处理以完成中断。在该示例中,我们将确认该中断。

  • 在尽可能短的时间内处理该中断

  • 创建 CELOGDATA 以供在 Kernel Tracker 中查看。

  • 检查并确认是否设置了 g_fPRRunning 标志,然后设置 g_hevPRStart 事件。

  • 调用 InterruptDone()。

    • 在调用 InterruptDone 之前,OS 不会提供此 IRQ 上的其他中断。

  • 再次等待中断事件。

DWORD  WINAPI  ThreadIST( LPVOID lpvParam )
{
DWORD  dwStatus;
BOOL  fState = TRUE;
// Always chec the running flag
//
while( g_fRun )
{
dwStatus  = WaitForSingleObject(g_hevInterrupt, INFINITE);
// Check to see if we are finished
//
if(!g_fRun ) return 0;
// Make sure we have the object
//
if( dwStatus == WAIT_OBJECT_0 )
{
// Do all interrupt processing to complete the interaction
// with the board so we can receive another interrupt.
//
if (!( READ_REGISTER_ULONG(g_pBoard Register) & INTR_MASK))
{
RETAILMSG(1, (TEXT("DEMO: Interrupt...")));
g_dwInterruptCount ++;
}
// Finish the interrupt
//
InterruptDone( g_dwSysInt );
}
}
return 0;
}

该示例读取一个 ULONG 寄存器以确定中断状态。您只需用您的代码替换该代码段。非常关键的一点是,要使 IST 处理尽可能地简单。如果将来需要处理来自该设备的数据:

  • 在 IST 中尽可能快速地从该设备获取数据。

  • 创建一个事件,以通知某个优先级较低的线程完成该工作。

  • 通过 InterruptDone 从该 IST 中立即返回。

  • 让优先级较低的线程进一步处理数据。

  • 在 IST 与优先级较低的线程之间放置 FIFO 以处理溢出。

返回页首

导致延迟的因素

从 Windows CE .NET 中的中断体系结构示意图中,可以了解硬件、内核、OAL 与驱动程序/应用程序线程之间的交互。Microsoft 已经提供了多种工具(包括 ILTiming、CEBench 和 Kernel Tracker),以便帮助您评估平台上的 Windows CE .NET 的性能。通过了解导致 ISR 和 IST 延迟的因素,有助于确定调查领域。

ISR 延迟

正如您在本文前面的中断体系结构示意图中可以看到的,ISR 延迟被定义为从发生中断到 OAL ISR 首次执行之间的时间。因为当中断被关闭时,中断不会在处理器中引发异常,所以第一个导致延迟的因素是系统中的中断被关闭的总时间。在每个机器指令开始执行时都将检查是否有处理器中断。如果调用了长字符串移动指令,则会锁定中断,从而造成第二个延迟源,即总线访问锁定处理器的时间量。第三个因素是内核导向 OAL ISR 处理程序所花费的时间量。这是一个进程上下文切换。总之,导致 ISR 延迟的因素包括:

  • 中断被关闭的时间。

  • 总线指令锁定处理器的时间。

  • 内核 ISR 的执行时间加上导向 OAL ISR 的时间。

IST 延迟

本文前面的体系结构示意图中显示,IST 延迟是从中断发生到执行 IST 中的第一行代码之间的时间量。这与 Windows CE .NET 中的 Microsoft 度量工具的输出不同。Microsoft 工具将 IST 延迟定义为从 OAL ISR 执行结束到 IST 开始之间的时间。因为标准的 ISR 花费的时间很少,您需要将 ISR 延迟和 Microsoft 度量工具所得到的 IST 延迟加起来,才能获得“中断体系结构示意图”中所定义的 IST 延迟。

导致 IST 延迟的第一个因素是本文前面定义的 ISR 延迟。第二个因素是 ISR 执行时间。根据共享中断调用链的长度的不同,此时间是可变的。对于延迟较小的情况,没有必要对永远不会被共享的中断调用 NKCallIntChain

Windows CE 中的内核函数(如计划程序)被称为 KCALL。在这些 KCALL 执行期间,将设置一个软件标志,以便让计划程序知道它此时不能被中断。仍然将调用 ISR,但用于重新调度 OS 或调度 IST 的返回值将被延迟,直至 KCALL 完成为止。这一不可占先的时间是导致 IST 延迟的第三个因素。最后,内核必须调度 IST。这一上下文切换是导致延迟的最后一个因素。总之,导致 IST 延迟的因素包括:

  • ISR 延迟时间

  • OAL ISR 执行时间

  • OS 执行 KCALL 的时间

  • 调度 IST 的时间

返回页首

小结

通过 Windows CE .NET,Microsoft 已经升级了 Windows CE 中断体系结构。该 OS 所具有的处理共享中断的能力极大地扩展了 Windows CE .NET 支持许多中断体系结构的能力。这一中断体系结构方面的知识可以大大加快调查驱动程序和延迟问题的速度。操作系统交互模型是了解该体系结构的关键。共享中断已经大大提高了 Windows CE .NET 的开放性,能够支持遍布于不同公司之间以及公司内部的平台提供商和应用程序开发人员方案。了解延迟根源将有助于诊断驱动程序和实时问题。Windows CE .NET 中的中断结构定义完善且易于理解。简而言之,“它不是魔术!”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/435565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软企业库5.0学习笔记(三十三)数据访问模块

前言 鉴于企业库5.0已经发布正式版&#xff0c;同时有广大读者的要求&#xff08;臭屁一下&#xff0c;o(∩_∩)o...&#xff09;&#xff0c;后面文章的内容和代码将基于Enterprise Library5.0和Unity2.0来写&#xff0c;感谢大家的一贯支持。 正文 数据库访问模块都能实现哪些…

ARM中断分析之一:中断控制器和CPU、外设的关系

“中断控制器”也是CPU众多外设中的一个&#xff0c;不同的是&#xff0c;它一方面接收其它外设中断引脚的输入&#xff0c;另一方面&#xff0c;它会发出中断信号给CPU。下图是一张中断控制器外设的框图&#xff0c;s3c2410的框图。 为了把中断控制器、CPU、外设联系起来&…

【转】Jenkins项目常用三种构建类型风格详解

转自&#xff1a;Jenkins项目常用三种构建类型风格详解_ぃ小小宇宙的博客-CSDN博客_jenkins项目类型 Jenkins构建的项目类型介绍 jenkins 的安装配置请参考&#xff1a;《jenkins war包安装部署&#xff0c;tomcatJDKmaven》 Jenkins中自动构建项目的类型有很多&#xff0c;…

ARM中断分析之二:裸机下面的中断处理

EINT4中断的裸机处理 这是基于S3C2410的EINT4中断的裸机处理&#xff0c;当中断发生时就把LED灯取反显示。下面是电路图。 上面是外部KEY连接到CPU的EINT4引脚上面&#xff0c;即&#xff1a;按下键就会产生一个中断。 按照先前介绍的&#xff0c;中断处理流程来介绍&#xff0…

【转】Jenkins 构建触发器操作详解

转自&#xff1a;Jenkins 构建触发器操作详解 - 习久性成 - 博客园 前言 触发远程构建 【https://www.cnblogs.com/Rocky_/p/8297260.html】 例如&#xff0c;使用脚本&#xff1a;通过一个网址的访问来触发构建&#xff0c;这样就不需要登录jenkins系统也能触发构建了。 示…

ARM中断分析之三:WinCE驱动的中断分析

现在有许多高端的ARM芯片&#xff0c;像苹果、三星、华为都采用ARM芯片做为智能手机芯片。 这篇文章介绍基于ARM的WinCE操作系统的驱动的中断分析。WinCE驱动分为两类&#xff0c;这里介绍流驱动&#xff0c;流驱动比较简单。 关于流驱动&#xff0c;下面是一张框图&#xff0c…

【转】密码破解全能工具:Hashcat密码破解攻略

转自&#xff1a;密码破解全能工具&#xff1a;Hashcat密码破解攻略 - FreeBuf网络安全行业门户 Hashcat密码破解 hashcat号称世界上最快的密码破解&#xff0c;世界上第一个和唯一的基于GPGPU规则引擎&#xff0c;免费多GPU&#xff08;高达128个GPU&#xff09;&#xff0c…

基于Visual Studio2010讲解LINQ读出数据库数据生成XML

LINQ to XML 是一种启用了 LINQ 的内存 XML 编程接口&#xff0c;使用它&#xff0c;可以在 .NET Framework 编程语言中处理 XML。 LINQ to XML 最重要的优势是它与 Language-Integrated Query (LINQ) 的集成。 由于实现了这一集成&#xff0c;因此&#xff0c;可以对内存 XML…

【转】详解JS的四种异步解决方案:回调函数、Promise、Generator、async/await

转自&#xff1a;详解JS的四种异步解决方案&#xff1a;回调函数、Promise、Generator、async/await 同步&异步的概念 在讲这四种异步方案之前&#xff0c;我们先来明确一下同步和异步的概念&#xff1a; 所谓同步(synchronization)&#xff0c;简单来说&#xff0c;就是…

wince6.0 s5pv210 中断

1. 在smdkv210\src\oal\oallib\ksarm.h头文件里可以看到wince的中断定义。 设备中断的起始编号即wince预定义的设备中断ID的基值 SYSINTR_DEVICES EQU 8 一共支持64个设备中断 SYSINTR_MAX_DEVICES EQU 64 可用的设备…

【转】vsftp配置实例-虚拟用户锁定目录

转自&#xff1a; vsftp配置实例-虚拟用户锁定目录_jasonyang69的博客-CSDN博客_vsftpd锁定用户目录 快速解决 vsftpd nologin 虚拟用户 拒绝访问 无法登录_小飞飞飞鱼的博客-CSDN博客_vsftpd 拒绝访问 一、实验步骤 0、启用 nologin shell #vim /etc/shells /bin/sh /bi…

【转】高端球管使用了哪些高科技?

转自&#xff1a;高端球管使用了哪些高科技&#xff1f; 本文来源&#xff1a;第三方维修平台 本文作者&#xff1a;RepairCT 随着人类发现X射线&#xff0c;这项技术不断应用到医学领域&#xff0c;比如X光机、DR、CT、乳腺钼靶等医疗设备&#xff0c;它们的主要核心均是利用…

关于代码组织的一些看法(上)

今天看了一个篇关于架构的文章&#xff0c;略有所感&#xff0c;记录一下。 软件的架构基本是从一个原始需求出发&#xff0c;逐步构建可维护、更灵活的开发框架的过程&#xff0c;在这个构建过程中可能会逐渐的增加代码的复杂度来满足灵活性的要求&#xff0c;从这个层面来讲&…

CE下基于Zylonite硬件平台的SD卡驱动开发

摘要&#xff1a;本文结合实际项目&#xff08;一款以WINCE为操作系统内核的GSM/PHS双模智能手机&#xff09;对嵌入式系统Windows CE5.0的底层驱动&#xff08;SD卡&#xff09;的架构进行了分析和研究&#xff0c;以MARVELL公司提供的基于INTEL Zylonite硬件平台的BSP为基础&…

pthread-win32在VC2005下的使用

pthread-win32是一个在Win32环境下的Unix POSIX线程库的移植. 有了它, 可以比较方便的移植Unix/Linux多线程程序到Windows下. 在VC2005下使用也很简单: 下载, 地址是 http://sourceware.org/pthreads-win32 里面include目录中是头文件, lib目录中是.lib和.dll文件. 在VC项目的属…

【转】apt命令

转自&#xff1a;apt命令详解 - 简书 apt命令可以说是Ubuntu系统下最为重要的命令&#xff0c;安装、更新、卸载软件&#xff0c;升级系统内核都离不开apt命令。 一、apt的简介 apt的全称是Advanced Packaging Tool是Linux系统下的一款安装包管理工具。 最初的时候&#xff…

maple 2018 窗口关闭提示乱码_如果解决SOLIDWORKS工程图转CAD字体出现乱码的问题_SolidWorks生信科技...

操作SOLIDWORKS工程图转CAD时&#xff0c;由于SOLIDWORKS使用的是Windows字体&#xff0c;而CAD使用的是线性字体&#xff0c;字体就容易出现乱码的苦恼。一般出现乱码是因为字体映射里面没有中文&#xff0c;所以会导致乱码。遇到这种情况&#xff0c;只需找到字体映射文件&am…

【转】apt 和 apt-get的区别

转自&#xff1a;https://www.sysgeek.cn/apt-vs-apt-get/ Ubuntu 16.04 发布时&#xff0c;一个引人注目的新特性便是 apt 命令的引入。其实早在 2014 年&#xff0c;apt 命令就已经发布了第一个稳定版&#xff0c;只是直到 2016 年的 Ubuntu 16.04 系统发布时才开始引人关注…

准确检测图像的轮廓 opencv_图像处理案例实战

1. 切边源图像&#xff1a; 需求&#xff1a;扫描仪扫描到的法律文件&#xff0c;需要切边&#xff0c;去掉边缘空白&#xff0c;这样看上去才真实&#xff0c;人工操作成本与时间花费高&#xff0c;希望程序自动实现&#xff0c;高效、准确。 实现思路&#xff1a;边缘检测 轮…

pp助手苹果版_再见!PP助手iOS端即将下线 曾是中国最大的苹果助手

苹果PP助手即将下线 在今日PP助手官方发布公告&#xff1a;尊敬的PP助手iOS版用户&#xff1a;衷心感谢您多年以来对我们的支持及厚爱。因业务调整&#xff0c;PP助手将于2020年2月28日正式下线iOS版产品&#xff0c;包括PP助手iOS版、PP助手iOS PC版等。 对您造成的不便还望理…