/* 功能:改变所有设备的power state 参数: newState 设备将要达到的power state context 函数体中木有用到。。。。。????? 返回:0 __flase 失败 1 __true 成功 */ static __bool PMC_API _power_callback(int newState, int context) { PDEVICE_INFO dev; DEVICE_LIST::iterator it; PDRIVER_INFO drv; IOSS_STATUS code; //遍历设备列表中的所有设备 for(it = g_Devices.begin(); it != g_Devices.end(); it++){ dev = it->second;//设备信息 drv = dev->d;//驱动信息 //调用驱动dll导出函数改变power state if( (dev->flags & DF_Active) && (drv->dispatch)){ code = drv->dispatch(dev, DISP_POWER_STATE_CHANGED, newState); if(code){ utils_error( "Error : device %s vetoed `power-state-changed' command," "error code 0x%08x.\n" "This may cause unpredictable result.\n", (char*)CDeviceName(dev->k), code ); return __false; } } } return __true; }
/* 功能:从设备驱动中更新并得到实时值 参数: tag 更新的标签结构体,包含更新实时值所需要的配置信息[in] new_value 实时值指针,用于存储更新所得到的实时值[in, out] now 更新时间[in] 返回: 1 成功 0 tag中动态属性的设备信息丢失 或 tag中动态属性设备信息的驱动信息丢失 或 tag中驱动信息中的更新tag的导出函数丢失 */ IO_API __bool PMC_API io_update_tag( PCRTK_TAG tag, Ppmc_value_t new_value, PCRTK_TIME now ) { PDRIVER_INFO drv; //1 设置新实时值的Flags new_value->Flags = 0; set_value_type(new_value->Flags, get_value_type(tag->s.Flags)); //2 将实时值的union清0,u64是union中的最大元素,即可表示union的大小 /* pre-set all unused bytes to zero, this will make it easier to write code depending on the tag types */ new_value->Value.u64 = 0; // assert(tag->d.DeviceObj == io_open_device(&tag->s.Device)); //3 从标签的动态属性中得到设备驱动信息的结构体 if(!tag->d.DeviceObj){ return __false; } drv = ((PDEVICE_INFO)tag->d.DeviceObj)->d; if(!drv){ return __false; } //4 调用设备驱动DLL的导出函数更新实时值 if(!drv->update_tag){ return __false; } if(drv->update_tag){ drv->update_tag(tag, new_value, now); } //5 某些设备驱动可能会重写实时值的类型标识,需要再用标签静态属性中的类型标识设置一下 // some ill-behavioured driver will overwrite the type field set_value_type(new_value->Flags, get_value_type(tag->s.Flags)); //6 若静态属性配置为开关量,则将true转化为1,false转化为0 if(get_value_type(tag->s.Flags) == dt_bool){ /* make digital variable cannonical */ new_value->Value.b = new_value->Value.b? 1 : 0; } return __true; }
/* 功能:调用设备驱动导出函数,将单点单实时值写入设备 参数: p 待写入的指定标签点数据结构RTK_TAG指针 value 待写入的指定标签点的实时值 返回:即设备驱动导出函数write_device()的返回值 */ static __bool _writeDevice(PRTK_TAG p, PCTAG_VALUE value) { PDRIVER_INFO npu; __bool retval = false; // p->d.DeviceObj = io_open_device(&p->s.Device); if(p->d.DeviceObj){ npu = ((PDEVICE_INFO)p->d.DeviceObj)->d; if(npu){ if(npu->write_device){ retval = npu->write_device(p, value); } } } return retval; }
void detach_tag_from_device(PRTK_TAG tag) { PDRIVER_INFO drv; // TODO: notify the device we're depriving this tag if(tag->d.DeviceObj){ drv = tag->d.DeviceObj->d; if(drv && drv->dispatch){ drv->dispatch(tag->d.DeviceObj, DISP_DB_DROP_TAG, (int)tag); } // detach tag from the old device RtkRemoveEntryList(&tag->d.DeviceLink); RtkInitializeListHead(&tag->d.DeviceLink); }else{ assert(RtkIsListEmpty(&tag->d.DeviceLink)); } tag->d.DeviceObj = 0; }
IO_API __bool PMC_API io_unload_driver(PDRIVER_INFO driver) { DRIVER_LIST::iterator it; utils_trace("Unloading driver %s\n", driver->dllname); for(it = g_Drivers.begin(); it != g_Drivers.end(); it++){ if(&(*it) == driver){ break; } } if(it == g_Drivers.end()){ DEBUG_PRINTF(( "Warning : unload a non-existing driver : 0x%08x\n", driver )); return __false; } if(driver->device_count){ utils_error( "Driver %s cannot unload with %d devices active.\n", driver->dllname, driver->device_count ); return __false; } if(driver->unload){ if(!driver->unload()){ DEBUG_PRINTF(( "Error : driver %s rejected unload request.\n", driver->dllname )); return __false; } } if(driver->plugin_handle){ FreeLibrary((HINSTANCE)driver->plugin_handle); } g_Drivers.erase(it); return __true; }