When I go through the SDk provided by the stack supplier, there are some definitions confuse me. I am not sure if those are standards or proprietary.
By configuring the endpoint information, it requests an device ID.
In this case, it sets ZCL_DEVICE_ONOFF_SWIRCH 0x0000. What I am trying now is related to IAS cluster. Is device ID defined in the spec ? where can I find the document about it ?
To configure the endpoint information, it includes the clientInCluster, clientOutCluster, and serverInCluster, serverOutCluster. I dont find any clue how to fill this variable so far. Please provide an example if you have one.
Thanks
The device ID is defined in the HA Spec:
https://docs.zigbee.org/zigbee-docs/dcn/07/docs-07-5367-02-0afg-home-automation-profile-for-public-download.pdf
ZCL_DEVICE_ONOFF_SWITCH 0x0000
Is an On/Off switch device. An IAS device could be:
// Intruder Alarm Systems (IAS) Device IDs
#define ZCL_HA_DEVICEID_IAS_CONTROL_INDICATING_EQUIPMENT 0x0400
#define ZCL_HA_DEVICEID_IAS_ANCILLARY_CONTROL_EQUIPMENT 0x0401
#define ZCL_HA_DEVICEID_IAS_ZONE 0x0402
#define ZCL_HA_DEVICEID_IAS_WARNING_DEVICE 0x0403
For the cluster information you should consult the HA Spec for the device types you want to create. The HA Spec will define the server side and client side mandatory and optional clusters that need to be implemented for that device. The clusters are defined in the ZCL Spec (http://www.zigbee.org/download/standards-zigbee-cluster-library/) and define which commands and attributes are mandatory and optional for that cluster.
If you are using the Texas Instruments ZigBee SDK then more information about implementing a ZigBee IAS device (in this example a smoke alarm) can be found here:
http://processors.wiki.ti.com/index.php/Fire_Alarm_System
Regards, TC.
Related
My team has been struggling with a pretty strange issue while using the WinRT/C++ APIs for Windows to connect to both a MIDI port and receive BLE notifications through a proprietary service on the same device.
The WinRT/C++ library itself is really nice and provides easy and modern C++ interfaces to access the managed Windows runtime classes.
I've pushed a sample repo to Github where we've replicated the issue with a minimal example.
The repo's readme goes over the problem in detail, but I'll post the relevant bits here for completeness.
The sample program is performing roughly these steps:
Check for available MIDI devices using a DeviceWatcher.
Check for available Bluetooth LE devices using another instance of a DeviceWatcher.
Match discovered MIDI and BluetoothLE devices on their ContainerId property (see DeviceInfo for details). This is the method JUCE employs in the native WinRT code for their library, and works as expected.
Open the MIDI port and attach a handler to the MessageReceived event (see the code).
This causes the system to create a connection to the Bluetooth LE device. The program detects this state change, creates a BluetoothLEDevice, we perform GATT service discovery and attach a handler to the ValueChanged event for the characteristic we're interested in notifications from (see the code).
The program then counts how many MIDI messages are received on each port and how many BLE notifications are received from the corresponding device.
The behaviour we notice is that data from the most recently connected device streams just fine, while the throughput for the others is severly limited. We are at quite a standstill regarding this issue, and are not sure where the problem may lie.
We are at quite a standstill here. I'd be more willing to accept it if all the devices would exhibit this behaviour, but that's not the case. Is there any reason that creating both a MidiInPort and an BluetoothLEDevice from the same peripheral should cause this issue?
A BLE radio can only receive or send at any given time. And therefore only communicate with one device at any given time. It uses a scheduler to allocate radio time for every device when you have many devices. That way a second connection can "interrupt" a connection event from another device, decreasing the throughput for that device. See https://infocenter.nordicsemi.com/topic/sds_s132/SDS/s1xx/multilink_scheduling/central_connection_timing.html
I've recently started playing with esp32. I was searching for various WiFi.mode() options available for esp32 but I couldn't find it anywhere. Can anyone help point out the source for that information?
Thanks
The code for the ESP32 Arduino SDK WiFi class is located at
https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi/src
WiFi.h doesn't define a method for mode() but it does inherit from WiFiGeneric.h which does have methods for mode() and getMode(). You can find the code for those methods in WiFiGeneric.cpp.
The mode is represented using type wifi_mode_t, which is defined in WiFiType.h. The available options are WIFI_MODE_OFF, WIFI_MODE_STA, WIFI_MODE_AP, and WIFI_MODE_APSTA.
There is some resonable but partial doc on the Espressif pages: Espressif Wifi doc
This doc explains some of the different wifi modes of the esp32 that can be found in WiFiType.h.
WIFI_MODE_NULL : The null mode or the WIFI_MODE_OFF which is the OFF mode
WIFI_MODE_STA : The Station mode, which is the standard client mode
WIFI_MODE_AP : The Access Point mode where clients can connect to the ESP32
WIFI_MODE_APSTA : The hybrid mode where the ESP connect to an AP as a client and recieve connections from client as an AP.
WIFI_MODE_MAX : The MAX mode has no explaination on what it is supposed to do. But it dose not seems to be implemented anyway.
The WiFi mode types come from an enumerated list. WIFI_MODE_MAX is the last entry in the list (and I guess that's why it's MAX). An odd convention as WIFI_MODE_UNKNOWN or similar would be more intuitive.
From a general standpoint, I am trying to figure out how to access a platform device from userspace. To be more specific, I have a EMIF controller on and SoC of which I have added to my device tree and I believe it is correctly bound to a pre-written EMIF platform device driver. Now I am trying to figure out how I can access this EMIF device from a userspace application. I have come accross a couple different topics that seem to have some connection to this issue but I cannot quite find out how they relate.
1) As I read it seems like most I/O is done through the use of device nodes which are created by mknod(), do I need to create a device node in order to access this device?
2) I have read a couple threads that talk about writting a Kernel module (Character?, Block?) that can interface with both userspace and the platform device driver, and use it as an intermediary.
3) I have read about the possibility of using mmap() to map the memory of my platform device into my virtual memory space. Is this possible?
4) It seems that when the EMIF driver is instantiated, it calls the probe() fucntion. What functions would a userpace application call in the driver?
It's not completely clear what you're needing to do (and I should caveat that I have no experience with EMIF or with "platform devices" specifically), but here's some overview to help you get started:
Yes, the usual way of providing access to a device is via a device node. Usually this access is provided by a character device driver unless there's some more specific way of providing it. Most of the time if an application is talking "directly" to your driver, it's a character device. Most other types of devices are used in interfacing with other kernel subsystems: for example, a block device is typically used to provide access from a file system driver (say) to an underlying disk drive; a network driver provides access to the network from the in-kernel TCP/IP stack, etc.
There are several char device methods or entry points that can be supported by your driver, but the most common are "read" (i.e. if a user-space program opens your device and does a read(2) from it), "write" (analogous for write(2)) and "ioctl" (often used for configuration/administrative tasks that don't fall naturally into either a read or write). Note that mknod(2) only creates the user-space side of the device. There needs to be a corresponding device driver in the kernel (the "major device number" given in the mknod call links the user-space node with the driver).
For actually creating the device node in the file system, this can be automated (i.e. the node will automatically show up in /dev) if you call the right kernel functions while setting up your device. There's a special daemon that gets notifications from the kernel and responds by executing the mknod(2) system call.
A kernel module is merely a dynamically loadable way of creating a driver or other kernel extension. It can create a character, block or network device (et al.), but then so can a statically linked module. There are some differences in capability mostly because not all kernel functions you might want to use are "exported" to (i.e. visible to) dynamically loaded modules.
It's possible to support mapping of the device memory into user virtual memory space. This would be implemented by yet another driver entry point (mmap). See struct file_operations for all the entry points a char driver can support.
This is pretty much up to you: it depends on what the application needs to be able to do. There are many drivers in the kernel that provide no direct function to user-space, only to other kernel code. As to "probe", there are many probe functions defined in various interfaces. In most cases, these are called by the kernel (or perhaps by a 'higher level "class" driver') to allow the specific driver to discover, identify and "claim" individual devices. They (probe functions) don't usually have anything directly to do with providing access from user-space but I might well be missing something in a particular interface.
You need to create a device node in order to access the device.
The probe function is called when the driver finds a matching device.
For information on platform device API, the following articles could be useful.
The platform device API
Platform devices and device trees
I am writing a serial driver for UART in windows just for learning purpose. More specifically in WDM.
I will write both the bus driver and function driver.
Currently i am writing the bus driver. So my question is from where i can come to know in my driver that how many serial ports i have in my system, so that i can expose that number of PDO's from my bus driver?? And resources allocated to each port. Do i have to check some kind of registry or windows will provide some kind of structure.
Please help me!! Thanks in advance
Assuming your UARTs are part of the PC, there's already a bus driver which will enumerate them. ACPI.SYS gets information from the platform BIOS, which includes the number and resource assignments for built-in components like UARTs.
If you're writing your driver for an add-in multi-port serial board, then you would need to look at the documentation for the board to determine how you find the number of UARTs. It might be as simple as looking at the PCI Product ID and having a hard-coded count for the type of board you have.
When ACPI enumerates the device, your driver's AddDevice routine will be called to load on it, and you'll receive the assigned resources when handling the PNP START message.
I am studying windows device drivers on my own and I find it's very difficult to differentiate between PDO and FDO. Let me tell you the flow that I have in my head correct me if I am wrong !!
when system boots it loads the root bus driver that will create a FDO. Now it will enumerates its child devices and i guess some hot plug method of the bus driver will be called, when a new child will be found and that method will notify the PNP manager. PNP manager will call the AddDevice() routine of the root bus driver and that will intern create PDOs for new buses like one for PCI and etc. Please explain the whole flow in detail, this is just my imagination. And then it is documented that system will load the functional driver for the PCI bus that will create the FDO ??
what is this FDO?? and why would i need that?? According to me PCI bus driver should also follow the same as done by the root bus, enumerate its child and create PDOs for them, or by this FDO they mean PDO only ?? I am so much confused :( !!
What are you actually doing, or are you just trying to learn? I am just wondering how you ended up this low down in the stack.
PDO = Physical Device Object
FDO = Functional Device Object
A PDO acts as a physical device, but it does not necessarily have to be physical. It is essentially the interface between a device on a bus, and the bus itself. This is pretty well covered on MSDN.
Here is an example that uses USB sticks and this illustrates the difference quite well.
Here is a more in depth explanation and the important quote
If your point of reference is the PCI bus, then Pci.sys is the function driver. But if your point of reference is the Proseware Gizmo device, then Pci.sys is the bus driver. This dual role is typical in the PnP device tree. A driver that serves as function driver for a bus also serves as bus driver for a child device of the bus.
You also have filter drivers which allow you to sit between PDO's and FDO's and start doing naughty stuff like hiding files, POC rootkits etc. At this stage you can add extra functionality, or completely prevent access to the PDO.
And here is all the MSDN links.
http://msdn.microsoft.com/en-us/library/windows/hardware/hh439632(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff554721(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/hh439643(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff554731(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff564859(v=vs.85).aspx
http://technet.microsoft.com/en-us/library/cc776371(v=ws.10).aspx
If that doesn't clear it up for you, feel free to post back.
Here is the excerpt form "Programming the Microsoft Windows Driver Model", 2nd edition, Walter One:
- PDO stands for physical device object. The bus driver uses this
object to represent the connection between the device and the bus.
- FDO stands for function device object. The function driver uses
this object to manage the functionality of the device.
- FiDO stands
for filter device object. A filter driver uses this object as a place
to store the information it needs to keep about the hardware and its
filtering activities. (The early beta releases of the Windows 2000
DDK used the term FiDO, and I adopted it then. The DDK no longer
uses this term because, I guess, it was considered too frivolous.)
Hope this helps you out.
According to me PCI bus driver should also follow the same as done by the root bus, enumerate its child and create PDOs for them --WRONG!.
If you are talking about WDM, PnP Manager creates PDOs. Earlier to that, YOU had to create it(after detection of device) in DriverEntry().