I have written a sample KMDF driver. I dont know if I did every thing right but have seen KMDF driver printing Debug message in DebugView utility - when I added this driver as new hardware. It also showed up as "Sample Device" under device manager.
Now I want to write a sample client that could call this Driver - so I can establish a connection between driver and client. I read that we need to use 'CreateFile' and 'DEviceIOControl' etc. But I am not able to get a start on it.
Can you please guide me around creating sample client to access the sample KMDF driver ?
My INF file for the driver looks like this :-
***My INF FILE****
; myshelldriver.INF
; Windows installation file for installing the myshelldriver driver
; Copyright (c) Microsoft Corporation All rights Reserved
;
; Installation Notes:
;
; Using Devcon: Type "devcon install myshelldriver.inf myshelldriver" to install
;
[Version]
Signature="$WINDOWS NT$"
Class=Sample
ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171}
Provider=%MSFT%
DriverVer=09/24/2012,1.0
CatalogFile=myshell.cat
[DestinationDirs]
DefaultDestDir = 12
[ClassInstall32]
Addreg=SampleClassReg
[SampleClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-5
[DiskCopyfiles]
wdfmyshelldriver.sys
[SourceDisksNames]
1=%InstDisk%,
[SourceDisksFiles]
Wdfmyshelldriver.sys=1
[Manufacturer]
%MSFT% = DiskDevice,NTAMD64
; For Win2K
[DiskDevice]
%DiskDevDesc% = DiskInstall, wdfmyshelldriver
; For XP and later
[DiskDevice.NTAMD64]
%DiskDevDesc% = DiskInstall, wdfmyshelldriver
[DiskInstall.NT]
CopyFiles = DiskCopyfiles
;;specify that this is the installation
;;for nt based systems.
[DriverInstall.ntx86]
DriverVer=09/24/2012,1.0
CopyFiles=DriverCopyFiles
[DiskInstall.NT.Services]
AddService = wdfmyshelldriver, %SPSVCINST_ASSOCSERVICE%, DiskServiceInst
[DiskServiceInst]
ServiceType = %SERVICE_KERNEL_DRIVER%
StartType = %SERVICE_DEMAND_START%
ErrorControl = %SERVICE_ERROR_NORMAL%
DisplayName = %DiskServiceDesc%
ServiceBinary = %12%\Wdfmyshelldriver.sys
AddReg = DiskAddReg
[DiskAddReg]
HKR, "Parameters", "BreakOnEntry", %REG_DWORD%, 0x00000000
HKR, "Parameters", "DiskSize", %REG_DWORD%, 0x00100000
HKR, "Parameters", "DriveLetter", %REG_SZ%, "R:"
HKR, "Parameters", "RootDirEntries", %REG_DWORD%, 0x00000200
HKR, "Parameters", "SectorsPerCluster", %REG_DWORD%, 0x00000002
[Strings]
MSFT = "Microsoft"
ClassName = "My Shell Device"
DiskDevDesc = "WDF My Shell Driver"
DiskServiceDesc = "myshelldriver Driver"
InstDisk = "myshelldriver Install Disk"
;*******************************************
;Handy macro substitutions (non-localizable)
SPSVCINST_ASSOCSERVICE = 0x00000002
SERVICE_KERNEL_DRIVER = 1
SERVICE_DEMAND_START = 3
SERVICE_ERROR_NORMAL = 1
REG_DWORD = 0x00010001
REG_SZ = 0x00000000
**** END OF INF FILE***
There are many relevant samples in the WDK. For example, take a look at KMDF Echo sample.
First you will need to name your object.
Second you will need to do at least one of the following:
Create a Symbolic link in the \GLOBAL??\
Register a Device Interface.
Option 1 will let you do the simple
CreateFile("\\\\.\\<device_name>, ...);
Option 2 and you will need to use the Setup DI Api routines to find your device to open it.
Related
I'm trying to get the data stream of a sensor transmitter that uses the modbus rtu communication protocol on my raspberry pi 3B. I'm able to get the data with the pymodbus2.5.3 library.
For this I use this code:
from pymodbus.client.sync import ModbusSerialClient # Import the pymodbus library part for syncronous master (=client)
client = ModbusSerialClient(
method='rtu', #Modbus Modus = RTU = via USB & RS485
port='/dev/ttyUSB0', #Connected over ttyUSB0, not AMA0
baudrate=19200, #Baudrate was changed from 38400 to 19200
timeout=3, #
parity='N', #Parity = None
stopbits=2, #Bites was changed from 1 to 2
bytesize=8 #
)
if client.connect(): # Trying to connect to Modbus Server/Slave
#Reading from a holding register
res = client.read_holding_registers(address=100, count=8, unit=1) #Startregister = 100, Registers to be read = 8, Answer size = 1 byte
if not res.isError(): #If Registers don't show Error
print(res.registers) #Print content of registers
else:
print(res) #Print Error Message, for meaning look at (insert git hub)
else: #If not able to connect, do this
print('Cannot connect to the Transmitter M80 SM and Sensor InPro 5000i.')
print('Please check the following things:')
print('Does the RS485-to-USB Adapter have power? Which LEDs are active?')
print('Are the cables connected correctly?')
And get the following output:
[15872, 17996, 16828, 15728, 16283, 45436, 16355, 63231]
With the help of the Modbus Poll and Slave Programms I know that those results should decoded be:
[0.125268, --, 23.53, --, 1.21094, --, 1.77344, --]
To get to the right results I tried the command that the pymodbus github suggests .decode():
res.decode(word_order = little, byte_order = little, formatters = float64)
[I know that those aren't the needed options but I copied the suggested github code to check if it works.]
After putting the code segment into the code the changed part looks like this:
if not res.isError(): #If Registers don't show Error
res.decode(word_order = little, byte_order = little, formatters = float64)
print(res.registers) #Print content of registers
else:
print(res) #Print Error Message, for meaning look at (insert git hub)
When I run this code, I get the following output, that traces to the decoding segment:
NameError: name 'little' is not defined
After this, I imported also the pymodbus part translation. But it showed the same output.
How can I decode my incoming data?
You can use BinaryPayloadDecoder to help decoding your payload, here is a simplified example, change Endian.Big and Endian.Little if needed.
if client.connect(): # Trying to connect to Modbus Server/Slave
#Reading from a holding register
res = client.read_holding_registers(address=100, count=8, unit=1) #Startregister = 100, Registers to be read = 8, Answer size = 1 byte
# ====== added code start ======
decoder = BinaryPayloadDecoder.fromRegisters(res.registers, Endian.Little, wordorder=Endian.Little)
first_reading = decoder.decode_32bit_float()
second_reading = decoder.decode_32bit_float()
# ====== added code end ======
if not res.isError(): #If Registers don't show Error
print(res.registers) #Print content of registers
else:
print(res) #Print Error Message, for meaning look at (insert git hub)
Remember to import from pymodbus.payload import BinaryPayloadDecoder at top and add necessary exception handlers in your final code.
Reference document: https://pymodbus.readthedocs.io/en/latest/source/library/pymodbus.html#pymodbus.payload.BinaryPayloadDecoder
I've started a project where I need to actively (all the time) scan for BLE Devices. I'm on Linux, using Bluez 5.49 and I use Python to communicate with dbus 1.10.20).
I' m able to start scanning, stop scanning with bluetoothctl and get the BLE Advertisement data through DBus (GetManagedObjects() of the BlueZ interface). The problem I have is when I let the scanning for many hours, dbus-deamon start to take more and more of the RAM and I'm not able to find how to "flush" what dbus has gathered from BlueZ. Eventually the RAM become full and Linux isn't happy.
So I've tried not to scan for the entire time, that would maybe let the Garbage collector do its cleanup. It didn't work.
I've edited the /etc/dbus-1/system.d/bluetooth.conf to remove any interface that I didn't need
<policy user="root">
<allow own="org.bluez"/>
<allow send_destination="org.bluez"/>
</policy>
That has slow down the RAM build-up but didn't solve the issue.
I've found a way to inspect which connection has byte waiting and confirmed that it comes from blueZ
Connection :1.74 with pid 3622 '/usr/libexec/bluetooth/bluetoothd --experimental ' (org.bluez):
IncomingBytes=1253544
PeakIncomingBytes=1313072
OutgoingBytes=0
PeakOutgoingBytes=210
and lastly, I've found that someone needs to read what is waiting in DBus in order to free the memory. So I've found this : https://stackoverflow.com/a/60665430/15325057
And I receive the data that BlueZ is sending over but the memory still built-up.
The only way I know to free up dbus is to reboot linux. which is not ideal.
I'm coming at the end of what I understand of DBus and that's why I'm here today.
If you have any insight that could help me to free dbus from BlueZ messages, it would be highly appreciated.
Thanks in advance
EDIT Adding the DBus code i use to read the discovered devices:
#!/usr/bin/python3
import dbus
BLUEZ_SERVICE_NAME = "org.bluez"
DBUS_OM_IFACE = "org.freedesktop.DBus.ObjectManager"
DEVICES_IFACE = "org.bluez.Device1"
def main_loop(subproc):
devinfo = None
objects = None
dbussys = dbus.SystemBus()
dbusconnection = dbussys.get_object(BLUEZ_SERVICE_NAME, "/")
bluezInterface = dbus.Interface(dbusconnection, DBUS_OM_IFACE)
while True:
try:
objects = bluezInterface.GetManagedObjects()
except dbus.DBusException as err:
print("dbus Error : " + str(err))
pass
all_devices = (str(path) for path, interfaces in objects.items() if DEVICES_IFACE in interfaces.keys())
for path, interfaces in objects.items():
if "org.bluez.Adapter1" not in interfaces.keys():
continue
device_list = [d for d in all_devices if d.startswith(path + "/")]
for dev_path in device_list:
properties = objects[dev_path][DEVICES_IFACE]
if "ServiceData" in properties.keys() and "Name" in properties.keys() and "RSSI" in properties.keys():
#[... Do someting...]
Indeed, Bluez flushes memory when you stop discovering. So in order to scan continuously you need start and stop the discovery all the time. I discover for 6 seconds, wait 1 second and then start discovering for 6 seconds again...and so on. If you check the logs you will see it deletes a lot of stuff when stopping discovery.
I can't really reproduce your error exactly but my system is not happy running that fast while loop repeatedly getting the data from GetManagedObjects.
Below is the code I ran based on your code with a little bit of refactoring...
import dbus
BLUEZ_SERVICE_NAME = "org.bluez"
DBUS_OM_IFACE = "org.freedesktop.DBus.ObjectManager"
ADAPTER_IFACE = "org.bluez.Adapter1"
DEVICES_IFACE = "org.bluez.Device1"
def main_loop():
devinfo = None
objects = None
dbussys = dbus.SystemBus()
dbusconnection = dbussys.get_object(BLUEZ_SERVICE_NAME, "/")
bluezInterface = dbus.Interface(dbusconnection, DBUS_OM_IFACE)
while True:
objects = bluezInterface.GetManagedObjects()
for path in objects:
name = objects[path].get(DEVICES_IFACE, {}).get('Name')
rssi = objects[path].get(DEVICES_IFACE, {}).get('RSSI')
service_data = objects[path].get(DEVICES_IFACE, {}).get('ServiceData')
if all((name, rssi, service_data)):
print(f'{name} # {rssi} = {service_data}')
#[... Do someting...]
if __name__ == '__main__':
main_loop()
I'm not sure what you are trying to do in the broader project but if I can make some recommendations...
A more typical way of scanning for service/manufacturer data is to subscribe to signals in D-Bus that trigger callbacks when something of interest happens.
Below is some code I use to look for iBeacons and Eddystone beacons. This runs using the GLib event loop which is maybe something you have ruled out but is more efficient on resources.
It does use different Python dbus bindings as I find pydbus more "pythonic".
I have left the code in processing the beacons as it might be a useful reference.
import argparse
from gi.repository import GLib
from pydbus import SystemBus
import uuid
DEVICE_INTERFACE = 'org.bluez.Device1'
remove_list = set()
def stop_scan():
"""Stop device discovery and quit event loop"""
adapter.StopDiscovery()
mainloop.quit()
def clean_beacons():
"""
BlueZ D-Bus API does not show duplicates. This is a
workaround that removes devices that have been found
during discovery
"""
not_found = set()
for rm_dev in remove_list:
try:
adapter.RemoveDevice(rm_dev)
except GLib.Error as err:
not_found.add(rm_dev)
for lost in not_found:
remove_list.remove(lost)
def process_eddystone(data):
"""Print Eddystone data in human readable format"""
_url_prefix_scheme = ['http://www.', 'https://www.',
'http://', 'https://', ]
_url_encoding = ['.com/', '.org/', '.edu/', '.net/', '.info/',
'.biz/', '.gov/', '.com', '.org', '.edu',
'.net', '.info', '.biz', '.gov']
tx_pwr = int.from_bytes([data[1]], 'big', signed=True)
# Eddystone UID Beacon format
if data[0] == 0x00:
namespace_id = int.from_bytes(data[2:12], 'big')
instance_id = int.from_bytes(data[12:18], 'big')
print(f'\t\tEddystone UID: {namespace_id} - {instance_id} \u2197 {tx_pwr}')
# Eddystone URL beacon format
elif data[0] == 0x10:
prefix = data[2]
encoded_url = data[3:]
full_url = _url_prefix_scheme[prefix]
for letter in encoded_url:
if letter < len(_url_encoding):
full_url += _url_encoding[letter]
else:
full_url += chr(letter)
print(f'\t\tEddystone URL: {full_url} \u2197 {tx_pwr}')
def process_ibeacon(data, beacon_type='iBeacon'):
"""Print iBeacon data in human readable format"""
print('DATA:', data)
beacon_uuid = uuid.UUID(bytes=bytes(data[2:18]))
major = int.from_bytes(bytearray(data[18:20]), 'big', signed=False)
minor = int.from_bytes(bytearray(data[20:22]), 'big', signed=False)
tx_pwr = int.from_bytes([data[22]], 'big', signed=True)
print(f'\t\t{beacon_type}: {beacon_uuid} - {major} - {minor} \u2197 {tx_pwr}')
def ble_16bit_match(uuid_16, srv_data):
"""Expand 16 bit UUID to full 128 bit UUID"""
uuid_128 = f'0000{uuid_16}-0000-1000-8000-00805f9b34fb'
return uuid_128 == list(srv_data.keys())[0]
def on_iface_added(owner, path, iface, signal, interfaces_and_properties):
"""
Event handler for D-Bus interface added.
Test to see if it is a new Bluetooth device
"""
iface_path, iface_props = interfaces_and_properties
if DEVICE_INTERFACE in iface_props:
on_device_found(iface_path, iface_props[DEVICE_INTERFACE])
def on_device_found(device_path, device_props):
"""
Handle new Bluetooth device being discover.
If it is a beacon of type iBeacon, Eddystone, AltBeacon
then process it
"""
address = device_props.get('Address')
address_type = device_props.get('AddressType')
name = device_props.get('Name')
alias = device_props.get('Alias')
paired = device_props.get('Paired')
trusted = device_props.get('Trusted')
rssi = device_props.get('RSSI')
service_data = device_props.get('ServiceData')
manufacturer_data = device_props.get('ManufacturerData')
if address.casefold() == '00:c3:f4:f1:58:69':
print('Found mac address of interest')
if service_data and ble_16bit_match('feaa', service_data):
process_eddystone(service_data['0000feaa-0000-1000-8000-00805f9b34fb'])
remove_list.add(device_path)
elif manufacturer_data:
for mfg_id in manufacturer_data:
# iBeacon 0x004c
if mfg_id == 0x004c and manufacturer_data[mfg_id][0] == 0x02:
process_ibeacon(manufacturer_data[mfg_id])
remove_list.add(device_path)
# AltBeacon 0xacbe
elif mfg_id == 0xffff and manufacturer_data[mfg_id][0:2] == [0xbe, 0xac]:
process_ibeacon(manufacturer_data[mfg_id], beacon_type='AltBeacon')
remove_list.add(device_path)
clean_beacons()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--duration', type=int, default=0,
help='Duration of scan [0 for continuous]')
args = parser.parse_args()
bus = SystemBus()
adapter = bus.get('org.bluez', '/org/bluez/hci0')
bus.subscribe(iface='org.freedesktop.DBus.ObjectManager',
signal='InterfacesAdded',
signal_fired=on_iface_added)
mainloop = GLib.MainLoop()
if args.duration > 0:
GLib.timeout_add_seconds(args.duration, stop_scan)
adapter.SetDiscoveryFilter({'DuplicateData': GLib.Variant.new_boolean(False)})
adapter.StartDiscovery()
try:
print('\n\tUse CTRL-C to stop discovery\n')
mainloop.run()
except KeyboardInterrupt:
stop_scan()
I have custom board with kernel 4.14 and vivante drivers 6.2.4p4.0 (Official Freescale's ones).
I want to test my Qt application using the mesa drivers instead of the Freescale's.
I've already downloaded and manually compiled and installed the mesa drivers with kmsro and etnaviv drivers options enabled, but these steps doesn't seem to be enough.
What are the steps to do after installing the mesa drivers to enable them?
I don't have access to a Yocto layer for my board, so rebuilding the image is not an option.
thanks!
To get the etnaviv kernel module enabled, I did the following:
Download and compile kernel source v4.14, enabling the following options:
Device Drivers-> Graphics Support-> [M]ETNAVIV
MXC support drivers-> MXC Vivante GPU support->[*]MXC Vivante GPU support
Then install or compile MESA. If you choose to compile MESA remember to enable the options kmsro and etnaviv on the meson_options.txt file.
Lastly, to check if etnaviv was successfully loaded, do:
# dmesg | grep etnaviv
Should output something like this:
[ 6.249793] etnaviv gpu-subsystem: bound 134000.gpu (ops gpu_ops [etnaviv])
[ 6.249866] etnaviv gpu-subsystem: bound 130000.gpu (ops gpu_ops [etnaviv])
[ 6.249919] etnaviv gpu-subsystem: bound 2204000.gpu (ops gpu_ops [etnaviv])
[ 6.249934] etnaviv-gpu 134000.gpu: model: GC320, revision: 5007
[ 6.332274] etnaviv-gpu 130000.gpu: model: GC2000, revision: 5108
[ 6.402442] etnaviv-gpu 2204000.gpu: model: GC355, revision: 1215
[ 6.402474] etnaviv-gpu 2204000.gpu: Ignoring GPU with VG and FE2.0
[ 6.416880] [drm] Initialized etnaviv 1.1.0 20151214 for gpu-subsystem on minor 1
Check also your dtb file for proper initialization, mine has the following entries regarding the gpu:
gpu#00130000 {
compatible = "vivante,gc";
reg = <0x130000 0x4000>;
interrupts = <0x0 0x9 0x4>;
clocks = <0x2 0x1b 0x2 0x7a 0x2 0x4a>;
clock-names = "bus", "core", "shader";
power-domains = <0x9>;
linux,phandle = <0x82>;
phandle = <0x82>;
};
gpu#00134000 {
compatible = "vivante,gc";
reg = <0x134000 0x4000>;
interrupts = <0x0 0xa 0x4>;
clocks = <0x2 0x1a 0x2 0x79>;
clock-names = "bus", "core";
power-domains = <0x9>;
linux,phandle = <0x81>;
phandle = <0x81>;
};
gpu#02204000 {
compatible = "vivante,gc";
reg = <0x2204000 0x4000>;
interrupts = <0x0 0xb 0x4>;
clocks = <0x2 0x8f 0x2 0x79>;
clock-names = "bus", "core";
power-domains = <0x9>;
linux,phandle = <0x83>;
phandle = <0x83>;
};
gpu-subsystem {
compatible = "fsl,imx-gpu-subsystem";
cores = <0x81 0x82 0x83>;
};
Note: If you get a dmesg error output like "command buffer outside valid memory window", it might be the case that you need to increase the cma being reserved. You must do it via kernel parameter, In my case I had to set via uboot the following: cma=256M#2G
Is it possible to start an enterprise node, using an Oracle 12c backed up
vault configured via Oracle Wallet (i.e., configure the node.conf using only a
dataSource.url="jdbc:oracle:thin:#host:port:#SOME_ORACLE_WALLET_TNS" without
specifying any dataSource.username or dataSource.password parameters ) ?
In this case, please inform which additional oracle .jar files should be
added to the node drivers dir.
Oracle wallet is supported in Corda Enterprise. Below is a working configuration with Oracle Wallet, and has been tested with Oracle 11g and Oracle 12c.
Prerequisites
Oracle wallet is configured with auto login (-auto_login_local) for the node's database
Assuming that the node's database connection URL is configured in tnsnames.ora, with alias "db11g":
$ echo 'For JDBC URL ==> "jdbc:oracle:thin:#localhost:1521/xe" ==> below is an example of tnsnames.ora'
$ cat ~/oracle_experiment/tnsnames.ora
db11g =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = xe)
)
)
Wallet location is configured in sqlnet.ora:
$ cat ~/oracle_experiment/sqlnet.ora
WALLET_LOCATION =
(SOURCE =
(METHOD = FILE)
(METHOD_DATA =
(DIRECTORY = /Users/corda/oracle_wallet/)
)
)
SQLNET.WALLET_OVERRIDE = TRUE
SSL_CLIENT_AUTHENTICATION = FALSE
SSL_VERSION = 0
Sqlplus should be able to login without a password challenge:
sqlplus /#db11g
SQL*Plus: Release 12.2.0.1.0 Production on Tue Nov 27 15:17:00 2018
Copyright (c) 1982, 2017, Oracle. All rights reserved.
Last Successful login time: Tue Nov 27 2018 14:46:09 +08:00
Connected to:
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production
SQL>
Necessary steps
Change the database-specific configuration from:
$ cat dbconfig_oracle11g.conf
dataSourceProperties = {
dataSourceClassName = "oracle.jdbc.pool.OracleDataSource"
dataSource.url = "jdbc:oracle:thin:#localhost:1521/xe"
dataSource.user = corda_es_user
dataSource.password = corda_es_passwd
}
To
$ cat dbconfig_oracle_wallet.conf
dataSourceProperties = {
dataSourceClassName = "oracle.jdbc.pool.OracleDataSource"
dataSource.url = "jdbc:oracle:thin:/#db11g"
dataSource.user=null
dataSource.password=null // user and password can't be ignored and can't be left blank.
}
Download and copy the following JARs into the node's drivers folder:
]$ ls <corda>/drivers/
ojdbc8.jar
osdt_cert.jar
osdt_core.jar
oraclepki.jar
Start the node with the oracle.net.wallet_location and oracle.net.tns_admin options:
]$ java -Doracle.net.wallet_location=/Users/corda/oracle_wallet/ -Doracle.net.tns_admin=/Users/corda/oracle_experiment/ -jar corda.jar
Refer to the SSL with JDBC blog for more details.
I'm having a problem with configuring oracle odbc
the dialog page is blank
when I enter TNS name as : XE
I get the following error:
unable to connect SQLState=08004
my tnsnames file is:
KPI_SERVER=
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST =localhost)(PORT =1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)
the connection is successful in SQL developer by the following data:
hostname: localhost
port number: 1521
service: XE
and the trns_admin variable is set to: C:\oracle_odbc\tnsnames
Path is set to: C:\oracle_odbc
what did I do wrong?
thank you for your time
We try to make order: open a command prompt,
launch echo %TNS_ADMIN% the result is C:\oracle_odbc\?
launch dir C:\oracle_odbc\, the result is tnsnames.ora?
launch type C:\oracle_odbc\tnsnames.ora the result is the content of "my tnsnames file is" section of your initial post?
If all the response are yes, can you retry to lauch 'sqlplus.exe dbuser/dbpassword#KPI_SERVER