Kithara »Hardware Toolkit«
The »Hardware Toolkit« replaces the complicated development of an own kernel driver and provides everything that is necessary for driver development.
The »Hardware Toolkit« has functions for delay-free access to the I/O register and physical memory of PC hardware. Additionally, it is possible to handle with hardware interrupts on application or kernel level. Furthermore, you can identify PCI configuration data and interface resources.
This toolkit provides necessary mechanisms to develop hardware drivers—especially PCI cards.
The whole development is based on the programming environment that you are used to, which means you don’t have to work in kernel.
- Access to all I/O register of PCs from applicaion or DLL
- I/O port access: 8 Bit, 16 Bit and 32 Bit
- Mapping external physical memory (Dual-Port-RAM)
- Internal memory for access to PC Plug-In cards (DMA Memory)
- Determination of PCI configuration data and resources
- Efficiently mechanisms for interrupt programming
- Interrupt handling on kernel and on application level
- Multiple handler per IRQ installable
- Supporting PIC and APIC hardware, multiprocessor PCs
- Generic WDM driver for Plug&Play installation inclusive
- 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 IoPort Module enables access to the I/O register of computers.
Get directly access to the I/O ports of the computer with the IoPort Module from the application!
Implemented hardware assemblies/mezzanine and PC cards can be controlled by controllers with a access to the I/O register. Therefore are functions for 8, 16 and 32 bit access available.
The IoPort Module is also required to trace the hardware resources (e.g. memory address or interrupt lines), which were dynamical allocated by Plug&Play-Manager from Windows.
The term "I/O Ports" does not mean COM ports or LPT ports, but rather the altogether 65536 I/O machine commands for all available I/O addresses of the system. Therewith you can control the I/O register of COM and LPT-controllers.
Add the Memory Module to your Custom Driver, if the hardware you want to use provides memory access.
- I/O port access
- Enable direct access to I/O ports
- I/O access from application program without context change possible
- Access protection for operating system, for all unenabled address still intact und active
- Only own application gets access to addresses
- No limitaions for the system
- Functions for direct and indirect I/O access
- 8, 16 and 32bit access, reading or writing
- Functions compatible to (under DOS) known C Makros
- Resource tracing
- Tracing of allocated rescoures from Plug&Play-Manager (Basis addresses, IRQs)
- Reading and writing of PCI configuration block
If you want to use direct I/O port access, you have to enable the I/O area for the direct access:
err = KS_enableIoRange(
myBaseAddress, // Basis addresses of hardware
8, // Number of I/O register
KSF_SIZE_8_BIT); // Flags, here byte-wise
Now, you can address the enabled hardware-register:
byte value = KS_inpb(
myBaseAddress + 2); // Address, 1 byte read
... // Byte analyse
KS_outpb(
myBaseAddress + 4, // Address, 1 byte write
value); // Byte write
If the I/O basis address of a PCI card is dynamical allocated from the Plug&Play-Manager, is it easy to trace by either all PCI assemblies will be browsed till the the vendor and device id is founded:
err = KS_getBusData(
&pciData, // Address of PCI-structure
busNumber, // Bus-number
slotNumber, // Device number and function
0); // Flags, here 0
if (pciData.vendorID == XXXX && pciData.deviceID == YYYY)
...
Or immediatly browsed by the desired id combination:
err = KS_getRessourceInfo(
"PCI\\VENxxxx&DEVyyyy", // ID combination
&resourceInfo); // Address of resource info
The received data structures containing all necessary information about interrupt lines and used I/O or memory basis addresses.
- How to trace the rescources, which were dynamical allocated by the PCI Plug&Play ?
- Either with 'KS_getBusData': Iterate all PCI devices in system until the searched parameter (vendor id, device id, etc.)is founded
- or with 'KS_getResourceInfoEx': Delivering parameter of the searched device and result of described data structure
- with 'KS_getResourceInfo' you can data from other interfaces like serical (COM) or parallel (LPT) or from network cards (NET) for the Packet Module and USB devices
There is no special hardware needed.
The Memory Module gives you access to the physical memory.
Get directly access to the external memory of integeration cards or provide internal RAM for the hardware access
The Memory Modul enables the usage of physical memory in your application and also for external hardware. There are two different kinds of memory areas:
- External memory areas of integration cards (also called Dual Port RAM) can be addressed by application
- Memory areas from internal main memory can be provided or external hardware (also called DMA memory)
The result of both cases is the same: The application (and also the kernel level) and the external hardware (e.g. PCI bus) get access to the memory. This will be shown in the address room of the application – that means, there will be no more needless copying operations, which causes the suitability of time critical applications.
This can be important for some applications, because access via I/O ports will be shortened to guarantee compatibility to older hardware components ( partly ? 1 µs!). Favoured applications are: measurement value logging, communication, framegrabber for image processing etc., therefore all applications, which have to transport big data amounts very fast.
The Memory Module is only used for memory access. For the addressing of I/O ports please note IoPort Module.
- External memory
- Blending exteral Dual Port RAM into the address room of application
- Different addresses for application and kernel level
- Direct access – no software emulation or copying operation
- Internal memory
- Providing internal main memory for external hardware on ISA or PCI bus
- Physical memory
- Physical address can be delivered to the external hardware in an own way
- For an enhancement of allocated block sizes is it possible to request the memory while booting
The blending of external memory areas (Dual Port RAM) of a PCI card into the address room of the application and kernels takes place like:
err = KS_mapPhysMem(
&pAppPtr, // Application address
&pSysPtr, // System address of memory
externalPhysAddr, // physical address
externalSize, // Length of memory area
KSF_PCI_BUS); // Flags, here PCI bus
The allocating of internal memory areas of the PC RAM for access by external hardware takes place like:
err = KS_allocPhysMem(
&pAppPtr, // Application address
&pSysPtr, // System addresss of memory
&externalPhysAddr, // physical address
externalSize, // Length of memory area
KSF_PCI_BUS); // Flags, here PCI-Bus
The physical address can be delivered to the hardware to get access to the memory via PCI bus.
Both methods come to the conclusion, that application, the kernel and the external hardware are able to get directly access (withput emulation or copying operations) to the same memory.
- How big is the maximal .. area for external memory?
- Basically, its as big as the external memory; there shall be no limitations
- How big is the maximal allocating area for internal memory?
- The memory has to be physical continuous, therefore it is even more less, so long the system is running. Therefore, the memory should be requested as soon as possible after the boot. The system memory will be fragmented very fast from the operating system.
- Memory Module contains mechanisms to allcate memory areas while booting, which can be requested from the application.
- Additionally, it is possible to allocate multiple little than one big area. Its recommend to use the "scatter/gather" management of the memory.
There is no special hardware needed.
The Interrupt Module provides the handling of hardware interrupts.
Realize handler for hardware interrupts of ISA and PCI bus assemblies in the application programming!
In the hardware dependent programming, e.g. developing of device driver, it is frequently necessary to analyse the events of hardware assemblies. The Interrupt Module allows the announcing of interrupt handler for integration cards on ISA and PCI bus and for their internal assemblies.
The Interrupt handling can be on kernel or application level. But you have to quit PCI interrupts on kernel level. You can register more than one handler for an Interrupt. E.g. a short function for the quitting of IRQs on kernel level and additionally a further function on application level for the essentially analysis of the interrupt.
If you want to call USB hardware, please note theUSB Module.
Requieres the Kernel Module.
- Announcing interrupt handler for ISA and PCI interrupts
- Handling on application or kernel level (Quitting of PCI IRQs only in kernel)
- Supporting all PCI bus types including PCI-Express
- Calling kernel function immediately in context of Interrupt Service Routine (ISR)
- Supporting ACPI, PIC, APIC and Multiprocessor computer (Dual Core, Quad Core etc.)
- Temporary locking of interrupt handling possible
- Kernel driver of »RealTime Suite« is even able to be configured as WDM driver for PCI Plug&Play
Assuming, the following callback function configurated as interrupt handler:
int __stdcall myInterruptHandler(
void* pArgs, // Address of reference data
void* pContext); // Address of context data
If you want to create callback objects with the flag KSF_DIRECT_EXEC , please note Kernel Module.
If you want to announce an interrupt handler, you have to detect the resource information at first :
KSResourceInfoEx info;
err = KS_getResourceInfoEx(
"PCI\\VEN_10ec&DEV_8139",// Hardware-ID of PCI card
&info); // To filling info structure
Therewith you can announce the Interrupt handler:
err = KS_createDeviceInterrupt(
&hInterrupt, // Address of handle
&info, // Info structure
hCallBack, // Callback handle
KSF_ACCEPT_PENDING |
KSF_PCI_INTERRUPT); // Flags, here PCI
You can announce multiple handler for the same IRQ, e.g. a callback function for the kernel level and one further within the application context.
- How is the support of Plug&Play mechanisms working?
- The particular driver of the »RealTime Suite« is usable as Plug&Play driver. For this purpose you have to extend your installation text file (*.INF) with one entry. This entry contains the specifications of PCI card or USB device.
- How to detect the used interrupt line(Plug&Play)?
- It is easy to detect the dynamically allocated resource information from the PCI Plug&Play manager. Please note IoPort Module.
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!


