Compact 2013 Ebook

24.5 Ex1. Global String buffer
Created by djones on 6/17/2013 10:24:48 PM

Driver Context

The string buffer can be implemented in one of three modes:

  • Global Context
  • Device Context
  • Open Context

This example will implement the buffer in a Global context.
Our book covers Device Context in Chapter 32. (See also the chapter download). The Open Context can be inferred from Device Context methodology.
See also the Whitepapers on the Windows Embedded Site:

Global Context

With this method, the buffer is statically implemented in the shared memory that is the same for all instances of the driver DLL. That way all instances of the driver use the same DLL. That is, is STR1: , STR2: STR3: are all loaded for a stream driver, any read or write with any stream would use the same buffer. This would not normally be a desirable feature. But in reality where the driver is communicating directly with hardware registers, they are effectively in shared memory. The same registers would be addressable by all instances of a driver. The driver instances would make sure they refer to their assigned registers only. For example, a serial driver, COM1 would write to its transmit buffer whereas COM2, using the same NS16C2552 Dual UART would write to the other transmit buffer on the IC. The UART transmit and receive buffers are effectively write-only and read-only buffers in global memory.

Device Context

A stream driver would typically instantiate data buffers in device context. That way each instance would have its own buffers. They would be instantiated on the heap in the stream XXX_Init() function and disposed of in the stream XXX_Deinit() function.

Open Context

When a driver is opened (XXX_Open() )by an application Open Context buffers would be instantiated (not when the driver is loaded) and disposed of when the stream is being closed (XX_Close()) (not when the driver is unloaded). Open context could be used to buffer data for a a thread where asynchronous IO is being used but an aspect of asynchronous IO is to provide application buffers to the driver to use, so perhaps not.

Strings Buffer IO

An application would open a stream, then call write() to write to a buffer and read() to read from it. This I/O is reflected in the driver as XXX_Write() and XXX_Read().Regardless of whichever context is used for the buffer, the write and read is performed in the same manner. The buffer is a fixed memory allocation and is implemented as a simple in/out system.  It is not a FIFO, LIFO or Ring buffer. The write is placed from the start of the buffer and the read also is from the start of the buffer.

Activity:

(A) Run CEDriverWiz to generate the steam driver and test applications:

  • Call the stream Mystream, prefix STR
  • Select Shared Memory and Shared Memory Buffer
  • No IOCTLs
  • RETAILMSG macros for driver and application
  • User Mode Driver
  • Select all test apps available
  • Generate the stream and add as Existing Subproject

(B) Build and test the driver

  • Save MyStream.cpp
  • Configure the subprojects to not be included in the OS image and to be built in debug mode.
  • Build all of the subprojects
  • Run the OS on the target
  • Run the Stream Load app.
  • Run the Stream Test App
  • Note the messages saying the buffer hasn’t been implemented yet.
  • Run the Unload App (Need to do this before rebuilding the stream driver, post modifications.)

(C) Modify the code

Open MyStream.cpp in the Stream Driver subproject.

1. The Buffer

In global space at the top of the file

Replace:

   1: #pragma data_seg(".MYSEG")
   2:  
   3:     //Shared Memory devCount Global Declaration code not yet implemented
   4:  
   5:     //Shared Memory Buffer Global Declaration(Initialisation) code not yet implemented
   6:  
   7: #pragma data_seg()

with:

   1: #pragma data_seg(".MYSEG")
   2:  
   3: static DWORD devCount=0;
   4:  
   5: static LPWSTR Buffer[BUFFER_SIZE/sizeof(WCHAR)];
   6:  
   7: #pragma data_seg()

 

2. devCount Init

In MyStreamInit() 
Replace
   1: //Shared Memory code to initialise devCount not yet implemented

with:

   1: DWORD max_devices = MAX_DEVICES;
   2: if (devCount >=  max_devices)
   3: {
   4:     RETAILMSG(1,(TEXT("MyStream: STR_Init()  Max devices has already been reached %d\n"),devCount));
   5:     return NULL;
   6: }
   7:  
   8: //Increment the device count
   9: devCount++;
  10: RETAILMSG(1,(TEXT("MyStream: STR_Init() Init No. devices: %d\n"),devCount));

 

3. devCount Deinit

In MyStream_Deinit()

Replace:

   1: //Report on device count as start of function' code not yet implemented
   2:  
   3: //Decrement the devCount
   4: //Shared Memory code to decrement devCount not yet implemented

with:

   1: RETAILMSG(1,(TEXT("MyStream: STR_Deinit() IN devCount = %d\n"),devCount));
   2:  
   3: //Decrement the devCount
   4: devCount--;
   5: RETAILMSG(1,(TEXT("MyStream: STR_Deinit() OUT devCount = %d \n"),devCount));

 

5. Write to Buffer

In MyStream_Wrtite()

Replace:

   1: //Copy from pSourceBytes to the buffer
   2:  
   3: //Shared Memory Buffer code  'To copy from pSourceBytes to the Shared Memory Buffer' not yet implemented
   4: RETAILMSG(1,(TEXT("MyStream: STR_Write() Copy from pSourceBytes to the Shared Memory Buffer not yet implemented.\n")));

with:

   1: //Copy from pSourceBytes to the buffer
   2:  
   3: // Copy the smaller of buffer size or number of bytes they send us.
   4: DWORD numToWrite  min(BUFFER_SIZE, NumberOfBytes);
   5: //Note: numToWrite gets corrupted ??
   6: dwRet = numToWrite;
   7:  
   8: memcpy((void *)Buffer, (void *)pSourceBytes, numToWrite);
   9:  
  10: RETAILMSG(1,(TEXT("MyStream: STR_Write() Wrote %d pSourceBytes to the Open Context Buffer.\n"),dwRet));

6. Read from Buffer

In MyStream_Read()

Replace:

   1: //Copy from Buffer to pDestinationBytes
   2:  
   3: //Shared Memory Buffer code  to copy from Shared Memory Buffer to pDestinationBytes not yet implemented
   4: RETAILMSG(1,(TEXT("MyStream:  STR_Read() Copy from Shared Memory Buffer to pDestinationBytes not yet implemented.\n")));

with:

   1: //Copy from Buffer to pDestinationBytes
   2:  
   3: // Copy the smaller of buffer size or number of bytes they send us.
   4: DWORD numToRead  min(BUFFER_SIZE, NumberOfBytes);
   5: //Note: numToWrite gets corrupted ??
   6: dwRet = numToRead;
   7:  
   8: memcpy((void *)pDestinationBytes,(void *)Buffer, numToRead);
   9:  
  10: RETAILMSG(1,(TEXT("MyStream: STR_Read() Wrote %d bytes from Open Context to pDestinationBytes.\n"),dwRet));

(D) Build and test the driver

  • Save MyStream.cpp
  • Rebuild the stream driver project
  • Run the OS on the target if it was shutdown. (No need to though.)
  • Run the Stream Load app.
  • Run the Stream Test App

Typical Debug Outputs:

Running MyStreamTestApp before modifications:

203394 PID:15a0076 TID:109000a MyStream: STR_Open() BEGIN
203394 PID:15a0076 TID:109000a MyStream: STR_Open() END
203394 PID:107000a TID:109000a MyStreamTestApp: Openned STR1:
203394 PID:15a0076 TID:109000a MyStream: STR_Write() BEGIN
203394 PID:15a0076 TID:109000a MyStream: STR_Write() Copy from pSourceBytes to the Shared Memory Buffer not yet implemented.
203394 PID:15a0076 TID:109000a MyStream: STR_Write() END
203395 PID:107000a TID:109000a MyStreamTestApp: Wrote to buffer: "This is a test of the MyStream Driver. This is only a test."
203395 PID:107000a TID:109000a MyStreamTestApp: Wrote to buffer 1 bytes
203395 PID:15a0076 TID:109000a MyStream: STR_Read() BEGIN
203395 PID:15a0076 TID:109000a MyStream:  STR_Read() Copy from Shared Memory Buffer to pDestinationBytes not yet implemented.
203395 PID:15a0076 TID:109000a MyStream: STR_Read() END
203395 PID:107000a TID:109000a MyStreamApp: Read from buffer 1 bytes
203395 PID:107000a TID:109000a MyStreamTestApp: Read OK
203395 PID:107000a TID:109000a MyStreamTestApp: (OK) Num bytes read = num written. 1
203395 PID:107000a TID:109000a MyStreamTestApp: Read from buffer: ""
203396 PID:15a0076 TID:109000a MyStream: STR_PreClose() BEGIN
203396 PID:15a0076 TID:109000a MyStream: STR_PreClose() END
203396 PID:15a0076 TID:109000a MyStream: STR_Close() BEGIN
203396 PID:15a0076 TID:109000a MyStream: STR_Close() END

Note that the buffer is not yet implemented and reports one byte copied.
It isn’t really one byte. The return value from XXX_Read() and XXX_Write() has to be non zero (error otherwise) so for unimplemented buffer it is set to one.

Running MyStreamTestApp after modifications:

35107 PID:400002 TID:23a016a RELFSD: Opening file MyStreamTestApp.exe from desktop
35223 PID:2fe00b2 TID:23a016a MyStream: STR_Open() BEGIN
35223 PID:2fe00b2 TID:23a016a MyStream: STR_Open() END
35224 PID:204017a TID:23a016a MyStreamTestApp: Openned STR1:
35224 PID:2fe00b2 TID:23a016a MyStream: STR_Write() BEGIN
35224 PID:2fe00b2 TID:23a016a MyStream: STR_Write() Wrote 118 pSourceBytes to the Open Context Buffer.
35224 PID:2fe00b2 TID:23a016a MyStream: STR_Write() END
35224 PID:204017a TID:23a016a MyStreamTestApp: Wrote to buffer: "This is a test of the MyStream Driver. This is only a test."
35224 PID:204017a TID:23a016a MyStreamTestApp: Wrote to buffer 118 bytes
35225 PID:2fe00b2 TID:23a016a MyStream: STR_Read() BEGIN
35225 PID:2fe00b2 TID:23a016a MyStream: STR_Read() Wrote 118 bytes from Open Context to pDestinationBytes.
35225 PID:2fe00b2 TID:23a016a MyStream: STR_Read() END
35225 PID:204017a TID:23a016a MyStreamApp: Read from buffer 118 bytes
35225 PID:204017a TID:23a016a MyStreamTestApp: Read OK
35225 PID:204017a TID:23a016a MyStreamTestApp: (OK) Num bytes read = num written. 118
35225 PID:204017a TID:23a016a MyStreamTestApp: Read from buffer: "This is a test of the MyStream Driver. This is only a test."
35225 PID:2fe00b2 TID:23a016a MyStream: STR_Close() BEGIN
35225 PID:2fe00b2 TID:23a016a MyStream: STR_Close() END

Note that the buffer is now implemented and it reports 118 bytes transferred in both directions. Wala!

Loading the driver:

31160 PID:4d60002 TID:4d80002 Registry key created OK
31160 PID:4d60002 TID:4d80002 Registry key DLL written OK
31161 PID:4d60002 TID:4d80002 Registry key prefix written OK
31161 PID:4d60002 TID:4d80002 Registry Flag (UserMode Load=16) Drivers\MyStream set OK
31161 PID:4d60002 TID:4d80002 Registry key closed OK
31270 PID:5d20006 TID:4d80002 MyStream: STR_Init() BEGIN
31270 PID:5d20006 TID:4d80002 MyStream: STR_Init() Active Registry Key= Drivers\Active\48 
31270 PID:5d20006 TID:4d80002 MyStream: STR_Init() DEVICE CONTEXT BEGIN
31271 PID:5d20006 TID:4d80002 MyStream: STR_Init() Device Context ptr is: 30B50
31271 PID:5d20006 TID:4d80002 MyStream: STR_Init() DEVICE CONTEXT END
31271 PID:5d20006 TID:4d80002 MyStream: STR_Init() END
31271 PID:4d60002 TID:4d80002 MyStreamLoadApp: Device HANDLE  is CEE93364 
31271 PID:4d60002 TID:4d80002 MyStreamLoadApp STRx: Loaded OK

Running Unload app:

297219 PID:400002 TID:107000e RELFSD: Opening file MyStreamUnloadApp.exe from desktop
297335 PID:15a0076 TID:107000e MyStream: STR_Open() BEGIN
297335 PID:15a0076 TID:107000e MyStream: STR_Open() END
297336 PID:10a000e TID:107000e MyStreamUnloadApp: Device HANDLE  is CC555FF4 
297336 PID:15a0076 TID:107000e MyStream: STR_PreClose() BEGIN
297336 PID:15a0076 TID:107000e MyStream: STR_PreClose() END
297336 PID:15a0076 TID:107000e MyStream: STR_Close() BEGIN
297336 PID:15a0076 TID:107000e MyStream: STR_Close() END
297337 PID:15a0076 TID:107000e MyStream: STR_PreDeinit() BEGIN
297337 PID:15a0076 TID:107000e MyStream: STR_PreDeinit() END
297337 PID:15a0076 TID:107000e MyStream: STR_Deinit() BEGIN
297337 PID:15a0076 TID:107000e MyStream: STR_Deinit() Device Context ptr is: 30B50
297337 PID:15a0076 TID:107000e MyStream: STR_Deinit() END
297339 PID:10a000e TID:107000e MyStreamUnloadApp: Unloaded driver instance: STR1: 

Next: (Watch this space)

  • Ex 2 – String Buffer in Device Context
  • Ex 3 – String Buffer in Open Context
  • Ex 4 – Power Management
print

Click here to provide feedback and input

  Comments

There is no comment.

Turkish porno izle video site in rokettubeporno izle