Kithara »USB Toolkit«
The »USB Toolkit« is a tool, which is used for developing a known USB driver for Windows or to get in contact with unknown USB hardware without working in kernel programming.
The developer works in their customary programming environment, supported programming languages are C/C++, Delphi or C#. The »USB Toolkit« provides a generic driver for USB-devices. It is quite easy to configure, the developer must edit a textfile and gets a comfortable access.
- Communication with USB devices via USB 1.1 and USB 2.0 from application or kernel level
- Low, Full, High speed
- Control, bulk, interrupt, isochron transfer
- Supports devices with multiple interfaces and configurations
- Reactions to all Plug&Play and power management events
- Reactions to incoming data direct on kernel level
- Sending and receiving routines can be called directly from a real-time context
- Providing Windows programmable interfaces for device communication (ReadFile, WriteFile, DeviceIoControl)
- Individual device names, e.g. for virtual interfaces
- C/C++ or Delphi (Win32 native) are supporting usage on kernel level
- Supports the following operating systems: Windows 7, Vista, Server 2003, XP, 2000 and NT
- Description
- Features
- Examples
- FAQ
- Hardware
The Base Module is the foundation of the whole »RealTime Suite«.
Create all needed resources, that enable for example the communication between application and kernel level!
The Base Module provides functions to administer the kernel driver. Therefore »RealTime Suite« can be used by several programs at the same time.
The Base Module contains functions to create and administer the following resources:
- Shared Memory
- Data and message pipes for quick data exchange
- Event objects
- CallBack functions
- Threads
- Fast mutex objects
Furthermore, the Base Module contains additional functions to deliver information to the »Kernel Tracer«. This allows to make debugging and problem-solving more comfortable.
Pay attention to the Kernel Module, that provides more universal functions and is essential to access the kernel level.
The Base Module is always required.
- General functions
- Open/close the kernel
- Version control, driver configuration
- Threads
- Creating threads
- Determine/set desired values of absolute thread priority
- Shared memory
- Shared memory especially for data exchange
- Protected from swapping to hard disk (memory will be fixed in memory)
- Multiple memory blocks with up to 60 MByte each
- Pipes
- Lock-free and fast data pipes and message pipes
- Enables comfortable and synchronized data exchange in desired direction between kernel and application
- Needs no additional synchronisation (supports multi-core CPUs)
- Signalizing
- Event objects: set, reset and pulse to activate an application thread
- Callback execution of user code on kernel or application level
- Sending Windows messages
- Fast mutex objects
- Fast synchronisation ("Mutex" = Mutual Exclusion)
- Multi-processor suitable
- Device information
- Detection of device information of PCI-, USB-, COM-, HID-Devices etc.
- Debug support
- Sending formatted text messages from kernel level
- Compatible to »Kernel Tracer« for profiling and debugging
The Base Module provides multiple functions, e.g. shared memory for data exchange between application and kernel:
err = KS_createSharedMem(
&pAppPtr, // Application address
&pSysPtr, // System address of memory
"MySharedMem", // Globally valid name
40 * MegaBytes, // Length in bytes
0); // Flags, here 0
For the simplification of periodical data exchange is it ideal to use a data pipe, which is also based on shared memory:
err = KS_createPipe(
&hPipe, // Address of pipe handle
"MyValuePipe", // Name of pipe
2, // Data size (e.g. measurement values)
1000000, // max. number of data elements
NULL, // reserved
0); // Flags, here 0
Now you can deposit the measured values in the pipe:
err = KS_putPipe(
hPipe, // Pipe handle
valueBuffer, // Pointer to data buffer
valueCount, // Number of values
NULL, // Not used here
0); // Flags, here 0
Application can read measured values from the pipe:
err = KS_getPipe(
hPipe, // Pipe handle
buffer, // Pointer to data buffer
bufferSize, // max. number of values
&filledSize, // How many values read?
0); // Flags, here 0
Variable-length data (e.g. messages) can be best handled with a message pipe. The usage is similar to the above mentioned way.
- Required qualifications
- Support of single or dual-core, multi-core CPUs, Hyperthreading, SMP etc.
- Support of standard PIC or APIC, ACPI
- Best platform would be a dual-/quad-core PC (with APIC + ACPI)
- Support of Windows Vista (x86), Windows Server 2003, Windows XP (Embedded), Windows 2000, Windows 7
- Programming on kernel level in C/C++ and Delphi (Win32)
- What are the special characteristics of shared memory?
- No hard-disk storage, thats means it is always available (also in real-time settings)
- Accessible from application and also from kernel level
- It exists exactly once, thats means it can also be used for data exchange between different applications (but in each program KS_createSharedMem has to be called)
- The memory is initialized with 0—a counter is checking, if the the memory is used from an other program
- Access to memory is not automatically synchonized (for synchonized access we recommend data pipes and message pipes)
There is no special hardware needed.
Real-time capability can only be achieved on the kernel level.
Bring your application code to the kernel level and gain access to the real-time world under Windows!
C/C++ compilers or the development environment Delphi (Win32) is required to generate native x86 code. Please consider that the .NET environment with C# is generally also supported, while only a native C++ or Delphi DLL can be used for kernel execution. Appropriate projects which are immediately compileable are provided in every software delivery.
There are two different ways to bring your source code to the kernel level:
- Instruction-wise relocation of a callback function and its sub-routines into the kernel address space
- Loading a DLL directly to the kernel level
Whereas the first method can have more advantages for short projects, the second option provides even more opportunities and allows for instance a simple creation of debug messages, which can be used in the »Kernel Tracer« for a solving problems.
Furthermore, you can realize complex control applications with a graphical interface which was created in e.g. Java or C#.NET, while only the time critical code parts are running in kernel mode.
The Kernel Module is required to execute application code on the kernel level.
- Tracing callback functions and their sub routines
- Direct loading of a DLL on the kernel level
- DLL can be created with C/C++ or Delphi (Win32)
- Callback functions will be directly executed in the interrupt service routine (ISR) or in real-time timer context
- All important functions of the »RealTime Suite« are also executable on kernel level, e.g.:
- I/O port access
- Access to physical memory
- Measuring system time and precise short-time delays
- Data communication over data- and message-pipes
- Sending and receiving over serial interfaces
- Sending and receiving over Ethernet network connections
- EtherCAT process data exchange in automation solutions
- Setting events (also reset, pulse)
- Events from kernel level: events and Windows messages
- Faster data-exchange between application and kernel via shared memory or lock-free data and message pipes
Assuming that your callback-function for the real-time timer looks like that:
int __stdcall myTimerCallback(
void* pArgs, // Address of reference data
void* pContext); // Address of context data
There are two ways to get the user code to the kernel level:
err = KS_createCallBack(
&hCallBack, // Address of handle
myTimerCallback, // Address of function
pSysAddrOfMyData, // Reference parameter
KSF_KERNEL_EXEC, // on the kernel level!
0); // Application priority, here 0
This way a function is loaded into the kernel memory.
Alternativly, you load a whole DDL into the kernel:
err = KS_loadKernel(
&hKernel, // Address of handle
"mykernel.dll", // File name of kernel DLL
"myInitFunction", // Name of init routine
pArgs, // Reference parameter
KSF_KERNEL_EXEC); // Flags, load into kernel
If it is once loaded in the kernel, you can create a kernel callback:
err = KS_createKernelCallBack(
&hCallBack, // Address of handle
hKernel, // Kernel Handle
"myTimerCallback", // Name of function
pSysAddrOfMyData, // Reference parameter
KSF_KERNEL_EXEC, // on the kernel level!
0); // Application priority, here 0
The callback handles can now be used as timer or interrupt handlers or to a real-time signalization for incoming Ethernet frames.
Hint:Complete Projects, for applications in languages like C++, C# or Delphi and also DDLs, which are loaded into kernel in C++ or Delphi, are components of every software delivery.
- How can kernel communicate with the application?
- Shared memory areas for not synchronizied data exchange
- Data and message pipes based on shared memory (lock-free, therefore are the reading and the writing site synchronizied against each other)
- Kernel can set event objects to activate application threads
- The application level can trigger a execution of function in kernel
- Windows messages
- How to debug code for the kernel level?
- User code can be debuged in the developing area:
- Callback function will be executed on the application level by a special flag
- Kernel DLL will be loaded on the application level by a special flag
- Shared memory, events, access to I/O ports and physical memory etc. are available for both contexts
There is no special hardware needed.
The Clock Module makes precise time measurement possible.
Detect the exact system time in different formats or realize exact short time delays!
In hardware dependent applications an exact system time has to be detected for different aims. The Clock Module provides functions to deliver the exact system time in different formats. You can choose between relative and absolute time specifications, or define a format yourself for specific requirements.
The time measuring is based on different and selectable time emitter (e.g. Time Stamp Counter (TSC), PC Timer, PM Timer, APIC Timer, HPET Timer), which are included in every system. Internal differences for the conversion are impossible for years, by reason of the 64 and 96 bit calculations.
Exact time delays are necessary for the hardware dependent programming. But the Clock Module is providing it.
The Clock Module is a qualification for the RealTime Module and it is always a valuable addition for different jobs.
- Time measuning
- System time is based on different internal time emiter
- Internal calculations with high precision 64 and 96 bit algorithms
- Relative time formats since system start
- Absolute time formats in common formats:
- Tenths microseconds since 1.1.1601 (Windows system time)
- Microseconds since 1.1.1970 (Unix system time)
- Milliseconds since 1.1.1980 (DOS system time)
- Absolute time data for local time zone or UTC
- All time emitter are calibrated against each other at system start
- Customized time formats are easy to define
- 2 phases time measuring (1. compilation, 2. subsequent conversion) for extreme time critical applications
- Short-time delay
- High precision short-time delays in tenths microseconds programmable
- Complex calibration at system start enables accuracy in nanosecond resolution (on kernel level)
The Clock Module provides two mechanisms – time measuring and short-time delay.
The most used function to time measuring delivers 100 ns units since system start:
UInt64 time;
err = KS_getClock(
&time, // Address of variable
KS_CLOCK_MACHINE_TIME); // 100 ns since system start
For processing , converting into 64-bit-values:
__int64 time64 = time.hi;
time64 <<= 32;
time64 += time.lo;
printf("%Ld Mikrosekunden seit dem Systemstart.\n", time64 / 10);
You also can get the absolute point of time since 1.1.1601 :
err = KS_getClock(
&time, // Address of variable
KS_CLOCK_ABSOLUTE_TIME); // 100-ns seit 1.1.1601
If you want to process with the received value you can easily use Windows functions.
The short-time delay realizes high precision delays, programmable in 100 ns steps with a difference in a few nanoseconds (on kernel level):
err = KS_microDelay(
38); // here 3,8 microseconds
Thats frequently usefull for access to hardware, if you have to keep in time conditions.
- Required qualifications
- Support of Single or Dual Core, Multi Core CPUs, Hyperthreading, SMP etc.
There is no special hardware needed.
The Device Module provides the Windows device API.
Enable available ("Legacy") application to access via Windows interfaces for devices, including "virtual COM ports"!
The Device Modules anncounces callback functions, which will be executed on kernel level, if an unknown application opens or closes device interfaces or reads/writes data or changes configuration. The used Windows functions are CreateFile, CloseHandle, ReadFile, WriteFile and DeviceIoControl. These five functions are altogehter the device API, which is also used in other operating systems for the device controlling.
Get everything to know about all happening events on kernel level and realize your own driver implementation for USB or PCI assemblies. You can also realize "virtual COM ports" with the Device Module in a simply way. The unknown application gets a serial interface, which can not be differenced to a physical interface.
For manipulation of serial data flow and more options for "virtual COM ports", please not the the Filter Module.
Requires the Kernel Module.
- Interception of function calls of CreateFile, CloseHandle, ReadFile, WriteFile and DeviceIoControl
- Reaction on kernel level allows an immedialtely reaction
- For data exchange with application it is recommend to use e.g. the comfortable data or message pipes
- Set any name for device interface
- "Virtual COM ports" can be easily created
For the realization of a "virtual COM port" you can create different callback rountines for the following events CREATE, CLOSE, READ, WRITE and CONTROL. E.g. for CONTROL:
int __stdcall myControlCallback(
void* pArgs, // Address of reference data
void* pContext) // Address of context data
{ ...
if (pContext->controlCode == SERIAL_SET_BAUD_RATE)
...
Callback objekts will be created for all routines:
err = KS_createCallBack(
&functions.hOnControl, // Address of handle
myControlCallback, // Address of function
pSysAddrOfMyData, // Reference parameter
KSF_DIRECT_EXEC, // on kernel level!
0); // Application priority , here 0
Afterwards, "virtual COM ports" can be created:
err = KS_createDevice(
&pAppPtr->hDevice_, // Address of handle
"COM77", // Device name
&functions, // Structure with callback handle
KSF_SERIAL_PORT); // Flags, "virtual COM port"
Therewith are other applications for another serial interfaces under the name "COM77" available, which can not be differenced to "real" interfaces. You also can operate with existing application and you dont have to programm they new.
- What applications can be realized with the Device Module?
- The Device Module provides a granting for a programmable interface for other application developer, e.g. for your USB- or PCI- driver. You can provide an interfaces, which can be easily called by functions of Win32 API. Thats why the documentation of API is quite simpler.
- It is also possible to provide so-called "virutal COM interfaces", which can be opened and handled from application programs like it would be a real COM port.
There is no special hardware needed.
The USB Module allows developing of USB device driver.
Create USB driver for Windows in a comfortable way, without working in complex kernel programming!
The USB Module allows to create USB driver for Windows and also to call existing USB devices to realize spceial controllings
The USB Module contains a generic driver for USB devices, which can be easily configured with an entry in the delivered INF file. This will activate the driver, as soon as the Windows Plug&Play manager recognises the connecting to the USB device.
Combine the USB Module with the Device Module to provide other application the USB device as a "virtual COM port".
Requiers the Kernel Module.
- Communication with USB devices via USB 1.1 and USB 2.0 from application or kernel level
- Supporting Low, Full, High Speed
- Control, Bulk, Interrupt, Isochron transfer
- Supporting devices with muliple interfaces and configurations
- Reaction to all Plug&Play and power management events
- Reaction to incoming data directly on kernel level is possible
- Send and receive routines can be directly called from the real-time context.
- Listing up all USB devices in PC
Use the following function to list up all USB devices:
err = KS_enumDevices(
"USB", // Searching USB devices
i, // Counter, starting with 0
deviceNameBuf, // Puffer for device name
0); // Flags, here 0
The received name allows you yo detect the config descriptor to e.g. search for a special HID device type:
err = KS_execUsbCommand(
deviceNameBuf, // Device name
KS_USB_GET_CONFIG_DESCRIPTOR,
0, // Index of descriptors
pBuf, // Puffer
64000, // Puffer size
KSF_ALTERNATIVE); // Flags
An existing driver can be replaced:
strcpy(infPath+GetSystemDirectory(infPath,256),"\\Kdemo.inf");
err = KS_updateDriver(
deviceNameBuf, // Device name
infPath, // INF-file
0); // Flags, here 0
The founded device can be openend. If it is known, you can directly declare it as the device name:
err = KS_openUsbDevice(
&hDevice, // Address of handle
"USB\\VID_10CF&PID_5500",// Device name
0); // Flags, here 0
The essentially communication takes place via so-called Endpoints. There are up to 15 send and 15 receive endpoints for every device:
err = KS_getUsbPort(
hDevice, // Device handle
&hPort, // Address of handle
endpointAddress, // Number of Endpoints
KSF_INTERRUPT_TRANSFER); // Flags: transfer mode
The communication takes place like the serial communication in the Serial Module.
- Can USB function also be used on kernel level?
- Yes. Although the USB docking is not able to work in real-time you can trigger e.g. send or receive tasks from a real-time timer function.
- How to guarantee a continuous data flow in utilization of available bandwidth?
- Multiple jobs simultaneous to utilise bandwidth
- Maximal number of simultaneous jobs configurable
There is no special hardware needed.
Platforms
Real-time capability can only be achieved on the kernel level. Therefore C/C++ or Delphi (Win32) is needed. Nevertheless the »RealTime Suite« supports different platforms, like e.g. the .NET environment:
- C++Builder 2007 (CodeGear) with VCL interface
- C++Builder 5 (Borland) with VCL interface
- Microsoft Visual C++ 6 with MFC interface
- Visual Studio 2005/2008 C++ with MFC interface
- Delphi (Object Pascal) Win32 with VCL interface
- Visual Studio 2005 C# with WPF interface
The solution is reached by storing time-critical code in DLL with all functions of the »RealTime Suite« and loading directly on the kernel level to get in real-time context.
Immediately, you can use program frames for the mentioned platforms and they are integrated in every software delivery.
System Requirements
The products of the »RealTime Suite« support a broad range of hardware and software combinations:
- CPU: AMD (Athlon and above) or Intel (Pentium 2 and above)
- Single or multi-core, Hyperthreading, SMP with altogether up to 8 CPU cores (more on request)
- ACPI (Advanced Control and Power Interface) supported, (A)PIC (Advanced Programmable Interrupt Controller) supported (some of the functions require APIC PC)
- Operating system: Windows 2000 (up to SP4), Windows XP (up to SP3), Windows Server 2003 (up to SP1), Windows Vista (x86, up to SP1), no guarantee for the usage together with newer service packs
- Compiler for the kernel level: Microsoft: Visual C++/Visual Studio, CodeGear (Borland): C++Builder, Delphi Win32
If you have questions about the support of your system, please contact us!


