d3d 设备丢失和reset

2024-03-23 12:30
文章标签 丢失 reset 设备 d3d

本文主要是介绍d3d 设备丢失和reset,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://www.cnblogs.com/kex1n/archive/2011/04/25/2026877.html


DirectX 3D 设备丢失(lost device)的处理

Posted on 2011-04-25 11:24  拳拳的Blog 阅读(357)  评论(0)  编辑  收藏 
在创建时使用D3DPOOL_MANAGED标志的资源可以不需要重新载入,但D3DPOOL_DEFAULT加载的资源就需要先释放,后重建。

通常需要这样处理的有ID3DXFont和ID3DXSprite,而.X模型什么的就不需要。
在发现设备丢失时,我们要调用 OnLostDevice( void ) 函数让D3DPOOL_DEFAULT加载的资源释放掉。
好在ID3DXFont和ID3DXSprite有设备丢失处理函数,直接调用就好了
void  OnLostDevice( void )
{
    m_sprite -> OnLostDevice(); 
    m_font -> OnLostDevice();
}


可是,怎么知道设备丢失了呢?
如果设备丢失,Present()函数就会“出问题”,返回值是D3DERR_DEVICELOST。

m_pIDirect3DDevice -> EndScene();

HRESULT hr;
hr 
 =  m_pIDirect3DDevice -> Present(NULL, NULL, NULL, NULL);
if (hr  ==  D3DERR_DEVICELOST)
{
    
if (m_pIDirect3DDevice -> TestCooperativeLevel()  == D3DERR_DEVICENOTRESET)
    {
        OnLostDevice();
        OnResetDevice();
    }
}
TestCooperativeLevel() ==  D3DERR_DEVICENOTRESET时,就可以恢复设备了。
于是,我们调用
 OnLostDevice( ) 让D3DPOOL_DEFAULT加载的资源释放掉,之后,调用OnResetDevice()来恢复设备就可以了。

怎么恢复设备呢?
void  OnResetDevice(  void )
{
      if (FAILED(m_pIDirect3DDevice -> Reset( & d3dpp)))
    {
          return ;
    }

    m_sprite -> OnResetDevice();
    m_font -> OnResetDevice();

    InitDevice();
}
先让D3D设备reset,然后调用 ID3DXFont和ID3DXSprite的恢复函数,最后,需要把 D3D设备中的状态啊,矩阵变换啊这些重新设置下就完成了,也就是调用  InitDevice()。

void  InitDevice()
{
m_pIDirect3DDevice -> SetRenderState( D3DRS_ZENABLE, TRUE );

m_pIDirect3DDevice -> SetRenderState( D3DRS_AMBIENT,  0xffffffff  );

m_pIDirect3DDevice -> SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
m_pIDirect3DDevice -> SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
m_pIDirect3DDevice -> SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

D3DXMatrixPerspectiveFovLH(  & matProj, D3DX_PI / 4 ,  1.0f ,  1.0f ,  1000.0f  );
m_pIDirect3DDevice -> SetTransform( D3DTS_PROJECTION,  & matProj );

vEyeVec = D3DXVECTOR3( 0.0f , 0.0f , - 1.0f );
vLookatVec = D3DXVECTOR3( 0.0f , 0.0f , 0.0f );
vUpVec = D3DXVECTOR3( 0.0f , 1.0f , 0.0f );
D3DXMatrixLookAtLH(  & matView,  & vEyeVec,  & vLookatVec,  & vUpVec );
m_pIDirect3DDevice -> SetTransform( D3DTS_VIEW,  & matView );
}
丢失的设备

一 个Microsoft? Direct3D?可以处于操作状态或丢失状态。操作状态是设备的正常状态,设备按预期运行并present所有渲染结果。当事件发生时,如全屏应用程序 失去键盘输入焦点,设备就转变到丢失状态,这会导致渲染无法进行。丢失状态表现为所有渲染操作的悄然失败,这意味着即使渲染操作失败所有的渲染方法仍可以 返回成功码。在这种情况下,IDirect3DDevice9: resent返回错误码D3DERR_DEVICELOST。

Direct3D 有意没有对可能导致设备丢失的所有情况进行详细说明。一些典型的例子包括窗口失去焦点,例如用户按下了ALT+TAB或弹出了一个系统对话框。设备也会因 为电源管理事件而丢失,或者另一个应用程序进行全屏操作。另外,任何对IDirect3DDevice9::Reset调用的失败会把设备置为丢失状态。

注意    可以保证所有继承自IUnknown的方法在设备丢失后仍能正常工作。设备丢失后,每个函数一般有三种可能:

调用失败,返回值为D3DERR_DEVICELOST – 这意味着应用程序必须发现设备已经丢失,从而知道一些事情没有按照预期进行。 
悄然失败,返回值为S_OK或其它值 – 若函数调用悄然失败,则应用程序一般无法区分出“调用成功”或“悄然失败”。 
函数返回一个返回值。 
对丢失的设备作出响应

设备在被重置后,应该重新创建资源(包括显存资源)。如果设备丢失了,那么应用程序应该查询设备状态,看是否可以将之恢复回操作状态。如果不行,那么就等到设备可以被恢复为止。

如 果设备可以被恢复,那么应用程序应该销毁所有显存资源和交换链,并准备恢复。然后,应用程序调用IDirect3DDevice9::Reset方法。 Reset方法是当设备丢失时唯一有效的方法,并且是应用程序可用来把设备从丢失状态恢复到操作状态的唯一方法。除非应用程序释放所有在 D3DPOOL_DEFAULT中分配的资源,包括用IDirect3DDevice9::CreateRenderTarget和 IDirect3DDevice9::CreateDepthSstencilSurface方法创建的资源,否则Reset将会失败。

Direct3D中大部分被频繁调用的方法不返回任何关于设备是否已丢失的信息。应用程序可以继续调用渲染方法,如IDirect3DDevice9: rawPrimitive,而不会收到设备丢失的通知。在Direct3D内部,这些操作被抛弃,直到设备被重置为操作状态为止。

通过查询IDirect3DDevice9::TestCooperativeLevel方法的返回值,应用程序可以决定在遇到设备丢失时如何处理。

管理资源


资 源管理是将资源从系统内存提升到设备可访问存储器及从设备可访问存储器中抛弃的过程。Microsoft? Direct3D?运行库有自己的基于最近最少使用(least-recently-used)优先级技术的管理算法。当Direct3D检测到在一帧中 ——在IDirect3DDevice9::BeginScene和IDirect3DDevice9::EndScene调用之间——设备可访问内存无 法同时存储所有资源时,它就切换到最近最多使用(most-recently-used)优先级技术。

在创建时使用 D3DPOOL_MANAGED标志指定一个由系统管理的资源。由系统管理的资源在设备的丢失状态和操作状态间的转换中持续存在。通过调用 IDirect3DDevice9::Reset设备可以被重置,并且这类资源可以继续正常运作而无需重新载入图片。但是,如果设备必须被销毁和重建,那 么所有用D3DPOOL_MANAGED创建的资源也必须被重建。

在创建时使用D3DPOOL_DEFAULT标志指定把资源放在默认的池中。在默认的池中的资源在设备从丢失状态到操作状态的转换过程中不持续存在,这些资源必须在调用Reset之前释放,然后重建。

更多有关设备的丢失状态的信息,请参阅丢失的设备。

注 意不是所有的类型和用途都支持资源管理。例如,用D3DUSAGE_RENDERTARGET标志创建的对象不支持资源管理。另外,不建议对需要频繁改变 其内容的对象使用资源管理。例如,在某些硬件上对一个每帧都需改变的顶点缓存进行自动管理会严重降低性能。但是,对纹理资源来说这不是一个问题。


例子(摘自codesampler):

以下内容为程序代码:

//-----------------------------------------------------------------------------
// Name: invalidateDeviceObjects()
// Desc: If the lost device can be restored, the application prepares the 
//        device by destroying all video-memory resources and any 
//        swap chains. This is typically accomplished by using the SAFE_RELEASE 
//        macro.
//-----------------------------------------------------------------------------
HRESULT invalidateDeviceObjects( void )
{
     //
     // To see how mismanagement of an object''s reference counter can cause us
     // problems when calling Reset on the device, uncomment the line below.
     // The line below will call AddRef() on the vertex buffer object, which w
     // ill add one to the vertex buffer''s reference count. This will cause it
     // to hang around after we call Release() on it, which is not what we 
     // wanted to happen here.
     //
     //g_pVertexBuffer->AddRef();

     //
     // NOTE: You could use the SAFE_RELEASE macro to invalidate your device 
     //        objects like so:
     //
      SAFE_RELEASE( g_pTexture )
      SAFE_RELEASE( g_pVertexBuffer )
      SAFE_RELEASE( g_pTeapotMesh )
    
     return S_OK;
}

//-----------------------------------------------------------------------------
// Name: restoreDeviceObjects()
// Desc: You are encouraged to develop applications with a single code path to 
//        respond to device loss. This code path is likely to be similar, if not 
//        identical, to the code path taken to initialize the device at startup.
//-----------------------------------------------------------------------------
HRESULT restoreDeviceObjects( void )
{
     //
     // Set some important state settings...
     //

     D3DXMATRIX matProj;
     D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian( 45.0f ),
                                 640.0f / 480.0f,
                                 //(float)(g_d3dpp.BackBufferWidth / g_d3dpp.BackBufferHeight), 
                                 0.1f, 100.0f );
     g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

     g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
     g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
     g_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE );

     g_pd3dDevice->SetLight( 0, &g_pLight0 );
     g_pd3dDevice->LightEnable( 0, TRUE );

     g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_COLORVALUE( 0.2f, 0.2f, 0.2f, 1.0f ) );

     //
     // Create a texture object...
     //

     D3DXCreateTextureFromFile( g_pd3dDevice, "test.bmp", &g_pTexture );

     g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
     g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );

     //
     // Create a vertex buffer...
     //
     // NOTE: When a device is lost, vertex buffers created using  
     // D3DPOOL_DEFAULT must be released properly before calling 
     // IDirect3DDevice9::Reset.
     //

     g_pd3dDevice->CreateVertexBuffer( 4*sizeof(QuadVertex),
                                       D3DUSAGE_WRITEONLY,
                                       QuadVertex::FVF_Flags,
                                       //D3DPOOL_MANAGED, // Does not have to be properly Released before calling IDirect3DDevice9::Reset
                                       D3DPOOL_DEFAULT,    // Must be Released properly before calling IDirect3DDevice9::Reset
                                       &g_pVertexBuffer, NULL );
     void *pVertices = NULL;

     g_pVertexBuffer->Lock( 0, sizeof(g_quadVertices), (void**)&pVertices, 0 );
     memcpy( pVertices, g_quadVertices, sizeof(g_quadVertices) );
     g_pVertexBuffer->Unlock();

     //
     // Create a mesh object...
     //
     // NOTE: When a device is lost, meshes created using D3DXMESH_DYNAMIC 
     // must be released properly before calling IDirect3DDevice9::Reset.
     //

     D3DXLoadMeshFromX( "teapot.x",
                        //D3DXMESH_SYSTEMMEM, // Does not have to be properly Released before calling IDirect3DDevice9::Reset
                        //D3DXMESH_MANAGED,    // Does not have to be properly Released before calling IDirect3DDevice9::Reset
                        //D3DXMESH_WRITEONLY, // Does not have to be properly Released before calling IDirect3DDevice9::Reset
                        D3DXMESH_DYNAMIC,      // Must be Released properly before calling IDirect3DDevice9::Reset
                        g_pd3dDevice,
                        NULL, NULL, NULL, NULL, &g_pTeapotMesh );
     return S_OK;
}

//-----------------------------------------------------------------------------
// Name: render()
// Desc: 
//-----------------------------------------------------------------------------
void render( void )
{
     //
     // Before we render, we need to make sure we haven''t lost our device.
     // If we have, we''ll need to restore it before we can continue.
     //

     HRESULT hr;

     if( g_bDeviceLost == true )
     {
         // Yield some CPU time to other processes
         Sleep( 100 ); // 100 milliseconds

         //
         // Test the cooperative level to see if it''s okay to render.
         // The application can determine what to do on encountering a lost 
         // device by querying the return value of the TestCooperativeLevel 
         // method.
         //

         if( FAILED( hr = g_pd3dDevice->TestCooperativeLevel() ) )
         {
             // The device has been lost but cannot be reset at this time. 
             // Therefore, rendering is not possible and we''ll have to return 
             // and try again at a later time.
             if( hr == D3DERR_DEVICELOST )
                 return;

             // The device has been lost but it can be reset at this time. 
             if( hr == D3DERR_DEVICENOTRESET )
             {
                 //
                 // If the device can be restored, the application prepares the 
                 // device by destroying all video-memory resources and any 
                 // swap chains. 
                 //

                 invalidateDeviceObjects();

                 //
                 // Then, the application calls the Reset method.
                 //
                 // Reset is the only method that has an effect when a device 
                 // is lost, and is the only method by which an application can 
                 // change the device from a lost to an operational state. 
                 // Reset will fail unless the application releases all 
                 // resources that are allocated in D3DPOOL_DEFAULT, including 
                 // those created by the IDirect3DDevice9::CreateRenderTarget 
                 // and IDirect3DDevice9::CreateDepthStencilSurface methods.
                 //

                 hr = g_pd3dDevice->Reset( &g_d3dpp );

                 if( FAILED(hr ) )
                     return;

                 //
                 // Finally, a lost device must re-create resources (including  
                 // video memory resources) after it has been reset.
                 //

                 restoreDeviceObjects();
             }

             return;
         }

         g_bDeviceLost = false;
     }

     //
     // Render a teapot and textured quad...
     //

     g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                          D3DCOLOR_COLORVALUE(0.35f,0.53f,0.7f,1.0f), 1.0f, 0 );

     g_pd3dDevice->BeginScene();
     {
         D3DXMATRIX matView;
         D3DXMATRIX matWorld;
         D3DXMATRIX matRotation;
         D3DXMATRIX matTranslation;

         D3DXMatrixIdentity( &matView );
         g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

         // Place and render first teapot...
         D3DXMatrixRotationYawPitchRoll( &matRotation, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f );
         D3DXMatrixTranslation( &matTranslation, 1.5f, 0.0f, 6.0f );
         matWorld = matRotation * matTranslation;
         g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

         g_pd3dDevice->SetMaterial( &g_teapotMtrl );
         g_pTeapotMesh->DrawSubset(0);

         // Place and render textured quad...
         D3DXMatrixTranslation( &matTranslation, -1.5f, 0.0f, 6.0f );
         matWorld = matRotation * matTranslation;
         g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

         g_pd3dDevice->SetMaterial( &g_quadMtrl );
         g_pd3dDevice->SetTexture( 0, g_pTexture );
         g_pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0, sizeof(QuadVertex) );
         g_pd3dDevice->SetFVF( QuadVertex::FVF_Flags );
         g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
     }
     g_pd3dDevice->EndScene();

     //
     // If Present fails with D3DERR_DEVICELOST the application needs to be 
     // notified so it cleanup resources and reset the device.
     //

     hr = g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

if( g_bHandleLostDevice == true )
{
if( hr == D3DERR_DEVICELOST )
g_bDeviceLost = true;
}
}

『当设备丢失之后』

  不论通过任何方式发生了设备丢失, 所有的操作几乎都会失效,只有Release()可以用——其实D3D会保证有部分操作可以成功,但是也仅仅是“可以”成功而不是“一定”成功,所以你还 不如认定丢失的时候全都会失败比较好——以及IDirect3DDevice9::TestCooperativeLevel。因此在设备丢失之后,你应 该停止整个游戏循环,而通过反复调用IDirect3DDevice9::TestCooperativeLevel判断设备是否可用。

『IDirect3DDevice9::TestCooperativeLevel』

   这个方法检测当前的设备状态。返回值有四种:D3D_OK一切正常,D3DERR_DEVICELOST设备丢 失,D3DERR_DEVICENOTRESET设备可以Reset。另外还有D3D9新增的D3DERR_DRIVERINTERNALERROR,遇 到这个你就完蛋了,基本不可能恢复了,终止程序吧。
  按照顺序来讲,如果游戏在正常运行,D3D_OK会返回;如果发生了设备丢失并且在这个时 候不能恢复,比如全屏幕模式的时候用户切换到了Windows桌面,就会返回D3DERR_DEVICELOST;如果用户又切换回了游戏,设备可以恢复 了(还没恢复呢!只是“可以”恢复而已),就会返回D3DERR_DEVICENOTRESET。
  另 外,IDirect3DDevice9::Present也会返回类似的值,不过你最好别指望这个,老老实实的用 TestCooperativeLevel。因为Present在设备可以恢复的时候还是返回D3DERR_DEVICELOST(外一句:D3D10的 时候TestCooperativeLevel就会完全整合到Present里面了,可喜可贺可喜可贺)

『处理设备丢失』

  看下面的伪代码:

switch (IDirect3DDevice9::TestCooperativeLevel()){
  case D3D_OK:
    GameLoop();
    break;
  case D3DERR_DEVICELOST:
    break;
  case D3DERR_DEVICENOTRESET
    OnLostDevice();
    IDirect3DDevice9::Reset();
    OnResetDevice();
    break;
  default:
    QuitGame();
    break;
}

  GameLoop()就是你的游戏运行的过程了。把这个switch写在我们游戏框架的GameMain()部分,具体的位置可以看任何一话附带的源代码。
  好像我一直没有讲IDirect3DDevice9::Reset的参数啊?因为只有一个参数,就是指向D3DPRESENT_PARAMS的指针。把你第一次创建设备时使用的D3DPRESENT_PARAMS结构保存起来,供Reset来用。
   OnLostDevice()就是Release掉所有D3DPOOL_DEFAULT的资源,OnResetDevice()就是Create*() 恢复啦!你可能注意到ID3DXFont、ID3DXSprite等等都有同名的方法,就是在这个时候调用的。如果你没有这么做,也就是说还保留着任何 D3DPOOL_DEFAULT的资源的话,IDirect3DDevice9::Reset就一定会失败。
  另外在 OnResetDevice里面你还要重新进行SetRenderState、SetSamplerState等等,Reset之后这些东西也丢失了。实 际上Reset和重新创建一次设备类似,所不同的是重新创建设备的话你需要连D3DPOOL_MANAGED的资源也Release掉。这个话题就不讨论 了。
  从代码可以看出来,D3DERR_DEVICELOST时程序什么都没做,只是在傻等。我认为这是一个好习惯,因为实在不能保证在D3DERR_DEVICELOST时除了Release还能干什么,与其这样还不如等设备能用了再说。

  实在懒得管资源的话,全部D3DPOOL_MANAGED好了。至于渲染对象?自己想办法。

『人工制造“设备丢失”』

   “干嘛还要制造设备丢失啊?”如果更改游戏分辨率、色深、切换全屏幕及窗口状态,进行这样的操作也要通过Reset,同样的,Reset之前也要释放掉 所有D3DPOOL_DEFAULT资源(其实严格来说,还有更多的资源也要释放,不过在2D下基本不会创建这类资源,你就不用管了)并且调用 ID3DXSprite::OnLostDevice之类的方法。这就是人工制造“设备丢失”了。实际上在这个过程设备并没有真正的丢失,只是会有一段时 间处于不可用的状态,此时Reset尚未返回,整个D3D设备就好像死了一样。举个例子,你切换桌面分辨率,会有那么一段时间显示器上什么都不显示,然后 很快就正常了。和这个现象是同一个原因。Reset成功后记得恢复资源。
  你可能注意到这里的Reset和上面的Reset不是一回事。的确是 这样,这里是为了重设状态而不是恢复设备。因此更改分辨率、色深的Reset需要写到switch外面,也就是别和它搅和的意思-_-bb。而且你只需要 OnLostDevice -> Reset -> OnResetDevice。记住:正确的调用Reset不会造成设备丢失,这个概念别弄混了。 

不3k就业不给1分学费(java, .net, php, android)
最新IT新闻:
·  小米预订名额网上遭大量抛售 粉丝称等不及
·  Maide Contro:用iPad来操作你的3D软件
·  乔布斯去世衍生多种周边产品
·  谷歌今日发布财报:移动与广告业务成焦点
·  淘宝商城应对攻击:暂时关闭货到付款功能
»  更多新闻...
最新知识库文章:
·  快速失败、经常失败、故意失败
·  JavaScript 单元测试现状
·  HTML5本地存储不完全指南
·  作为投资人和创业者最重要的经验
·  再谈JavaScript的数据类型问题
»  更多知识库文章...

China-pub 2011秋季教材巡展
China-Pub 计算机绝版图书按需印刷服务

这篇关于d3d 设备丢失和reset的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/838309

相关文章

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑燃料电池和电解槽虚拟惯量支撑的电力系统优化调度方法》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python

全英文地图/天地图和谷歌瓦片地图杂交/设备分布和轨迹回放/无需翻墙离线使用

一、前言说明 随着风云局势的剧烈变化,对我们搞软件开发的人员来说,影响也是越发明显,比如之前对美对欧的软件居多,现在慢慢的变成了对大鹅和中东以及非洲的居多,这两年明显问有没有俄语或者阿拉伯语的输入法的增多,这要是放在2019年以前,一年也遇不到一个人问这种需求场景的。 地图应用这块也是,之前的应用主要在国内,现在慢慢的多了一些外国的应用场景,这就遇到一个大问题,我们平时主要开发用的都是国内的地

驱动(RK3588S)第七课时:单节点设备树

目录 需求一、设备树的概念1、设备树的后缀名:2、设备树的语法格式3、设备树的属性(重要)4、设备树格式举例 二、设备树所用函数1、如何在内核层种获取设备树节点:2、从设备树上获取 gpio 口的属性3、获取节点上的属性只针对于字符串属性的4、函数读取 np 结点中的 propname 属性的值,并将读取到的 u32 类型的值保存在 out_value 指向的内存中,函数的返回值表示读取到的

海鲜加工污水处理设备处理效果高

诸城市鑫淼环保小编带大家了解一下海鲜加工污水处理设备处理效果高   海鲜加工污水处理设备通常采用物理、化学和生物处理相结合的方法,对废水中的污染物进行高xiao去除。设备设计紧凑,占地面积小,操作简便,适用于不同规模的海鲜加工厂。   设备特点   高xiao性:采用先进的处理工艺和技术,确保废水处理效果稳定可靠。   占地面积小:设备设计紧凑,占地面积小,适合在有限的空间内安装。

集运系统需要与哪些硬件设备集成?

随着电商和跨境贸易的不断发展,集运服务越来越受到海外用户的青睐。集运系统作为一种高效的跨境物流管理工具,可以协调各个环节之间的物流流程,提高物流效率和管理水平,被越来越多的集运企业采用。而集运系统作为集运服务的重要组成部分,也需要配套相应的硬件设备才能更好地支持跨境集运业务。下面就来介绍一下集运系统需要哪些硬件设备支持呢? 1.PDA:是一种便携式电子设备,可以轻松地进行数据采集和处理,具有移

3.门锁_STM32_矩阵按键设备实现

概述 需求来源: 门锁肯定是要输入密码,这个门锁提供了两个输入密码的方式:一个是蓝牙输入,一个是按键输入。对于按键输入,采用矩阵按键来实现。矩阵按键是为了模拟触摸屏的按键输入,后续如果项目结束前还有时间就更新为触摸屏按键输入。 矩阵按键开发整体思路: 由于矩阵按键就是GPIO的控制,所以不进行芯片和设备的分层编写,控制写在同一个文件中,最终向应用层提供一个接口。 代码层级关系:

六种msvcp110.dll丢失修复的方法分享,有效快速修复msvcp110.dll丢失

在日常使用电脑的过程中,我们可能会遭遇各种程序运行错误,其中“msvcp110.dll丢失”是一种非常常见的问题。这个问题通常发生在尝试启动某些程序时,系统会弹出一个错误消息,提示“程序无法启动,因为计算机缺少msvcp110.dll”,这可能会让用户感到困惑和无助。幸运的是,这个问题有多种解决方法,本文将指导你通过几种简单的步骤来修复“msvcp110.dll丢失”的问题,让你的程序回到正常运行

Anroid BLE蓝牙(手机分别作为中心设备和外围设备)

蓝牙是一种短距的无线通讯技术,可实现固定设备、移动设备之间的数据交换。一般将蓝牙3.0之前的BR/EDR蓝牙称为传统蓝牙,而将蓝牙4.0规范下的LE蓝牙称为低功耗蓝牙。  BLE蓝牙模块主要应用领域     1、移动扩展设备     2、汽车电子设备     3、健康医疗用品:心跳带、血压计等     4、定位应用:室内定位、井下定位等     5、近距离数据采集:无线

RS在不同设备间同步文件

参考: 1. Resilio(BtSync)搭建 2. 使用Resilio Sync共享文件【附操作指南】 4. Linux 下挂载新硬盘方法 5. Partition 1 does not start on physical sector boundary. 6. Ubuntu 16.04添加开机启动脚本的方法 7. Ubuntu 16.04以普通用户身份开机启动 8. Ubunt