Kithara使用其他注意事项汇总

共享内存注意事项

  1. 内核层的初始化函数里可以创建共享内存,然而如果共享内存首先在内核创建,则flag需要加上KSF_ALTERNATIVE否则会导致蓝屏现象的产生
  2. 多个不同的进程或内核层和用户层之间创建(指定同一名称)共享内存的时候Flag和大小要统一,否则可能存在创建的共享内存虽然是同一名称但是其实质上是两个不同的共享内存,导致数据没法共享
    具体创建共享内存的代码如下
//!!!!!!!!!!!根据调试模式和实时模式的不同创建共享内存的方式不同!!!!!!!!!!!!!!!
    int createShareMemFlag = 0;
    int getShareMemFlag = 0;
    if (false == gpShareMemFbDebugCfgData->isDebugMode)
    {
        //createShareMemFlag = KSF_ALTERNATIVE | KSF_CONTINUOUS;
        //注意这里的Flag一定要和用户层统一,否则虽然指定同一个名称,但是实质上创建的是两个不一样的共享内存!!
        createShareMemFlag = KSF_ALTERNATIVE | KSF_CONTINUOUS;
        getShareMemFlag = KSF_KERNEL_EXEC;
    }
    else
    {
        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//注意这里的Flag一定要和用户层统一,否则虽然指定同一个名称,但是实质上创建的是两个不一样的共享内存!!
    //createShareMemFlag = 0;       //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        createShareMemFlag = KSF_ALTERNATIVE | KSF_CONTINUOUS;
        getShareMemFlag = KSF_USER_EXEC;
    }

    //-------------------------------------------------------------------------------
    //如果KS_createSharedMemEx第一次调用在内核下,即在内核下创建实际的内存空间,
    //则需要加上KSF_ALTERNATIVE标志,否则会蓝屏
    //-------------------------------------------------------------------------------
    KS_printK("ShareMem_PLCopenFbItfData size = %d", sizeof(ShareMem_PLCopenFbItfData));
    ksError = KS_createSharedMemEx(&hShareMem_MachineInfo,
        ShareMemPLCopenItfDataName,
        sizeof(ShareMem_PLCopenFbItfData),
        createShareMemFlag
        );
    if (ksError != KS_OK)
    {
        KS_printK("LinBao: KS_createSharedMem Error");
    }
    ksError = KS_getSharedMemEx(hShareMem_MachineInfo, (void**)&gpShareMemFbItfData, getShareMemFlag);
    if (ksError != KS_OK)
    {
        KS_printK("LinBao: KS_getSharedMemEx Error");
    }
    KS_printK("SysModule_BusSlaveDebug: _InitRoutine_Demo  111 KS_createSharedMemEx");
//初始化共享内存相关数据
    InitFbItfShareMemData(gpShareMemFbItfData);

互斥体使用的注意事项

注意KS_execKernelFunction只有 flag 带KSF_REALTTIME_EXEC的时候才能保证执行的函数在内核是实时的。 因此要想通过KS_execKernelFunction执行的代码与内核其他task任务的代码同步,如用互斥体,事件,那必须用KSF_REALTTIME_EXECflag

if (false == m_isDebugMode)
    {
        m_funcExecFlag = KSF_REALTIME_EXEC | KSF_SAVE_FPU;
    }
    else
    {
        m_funcExecFlag = 0;
    }

    //执行功能块回调函数
    ksError = KS_execKernelFunction(
        m_hSoftMotionDll,
        m_callbackName_GetDI,
        m_pKernelFbItf_IoCtrl,
        NULL,
        m_funcExecFlag);
    if (ksError != KS_OK) {
        EZCode_LogMessage_Error(EZCode_Error_KRTS, "IOCtrlManage:exec EZCode_GetDI error", ksError);
        return -1;
    }

    //更新输入数据
    value = m_pAppFbItf_IoCtrl->diVal;

管道使用的注意事项

管道是不同进程,或内核层和用户层之间共享数据,简单高效的一种方式。 其实质上也是共享内存,只是做了同步(循环缓冲区)。不同windows进程,不能通过共享内存共享管道句柄。 由于Windows进程内存空间都是独立的,所以每个windows进程都能调用创建指定名称的管道,获得当前进程下的句柄。

关于句柄的使用注意事项

由于内核层的内存空间是说有任务共享,因此内核层的句柄所有内核任务都可以使用。然而由于Windows进程每个进程内存空间都是独立的,因此一个进程下的句柄不能再另一个windows进程下使用。 通过再次调用创建资源的Kithara相关API,通过指定资源的全局名称,来获得同一资源在不同windows进程下的句柄。