D-Scope Functions

 These functions were used by me in real development on an real project. So I know they work(ed) however they come with no guarantee. Please feel free to down load, use, amend etc. The use of test scripts is covered in Advanced Painfree Embedded Testing For Fun

Time and Date in test harnesses, D-Scope scripts & log files.
Embedding File Names and Version Numbers in D-Scope Test results

Formatted memory dump to log file function for D-Scope
D-Scope Universal print to log functions
Universal log Serial output to File

D-Scope Memset that takes variables as parameters


 

Time and Date in test harnesses, D-Scope scripts & log files.

One question often asked is how to get the time and date into D-scope test scripts, logs and test harnesses. This is to time stamp tests. Something that is often required by QA people.

The easiest answer is to use the built in time and date functions supplied by Keil as part of D-Scope. (Hint to Keil) However as the version you have does not have these functions, because they have not released the version with the time and date functions(ANOTHER hint to Keil!) there are some work arounds.

Here is a working system I have used in unit test on a project conforming to ISO9000. Unit test involves testing just one C file or function using a C test harness and a D-Scope script to control things. The system works by having a "main" function in the C test harness that calls the C function under test. I use the standard ISO C compiler macro's, __TIME__ & __DATE__ to embed the time and date as strings in the test harness. I then have a standard D-Scope function script that I include in to my main test script. The time and date function takes as parameters pointers to the strings in the test harness and prints them to the log file.

For this system to work I set up the Micro-Vision project to run D-Scope after a build with the test script. I build the test harness and file under test as a project and, if there are no errors, it automatically starts D-Scope and runs the test script (that includes the time and date function). Thus the time and date printed out are the time and date of the compilation of the test harness and by implication the whole build. (It also gives all the version numbers) Clearly there are ways of getting round this but I never claimed the system was fool proof.

The only other way of doing it is to put the time and date strings in the function under test enclosed in IFDEF's that only work in a test phase. However this is not satisfactory as in many cases it is not permitted to change the function under test.

The zip-file timedt.zip. contains the time and date D-Scope function and an example C test harness and D-Scope script. There are NO executable files in the zip file.


Top


 Embedding File Names and Version Numbers in D-Scope Test results

Many test systems call for the version of the test scripts, harness and file under test to be recorded. In many ways this is a similar problem to the time and date problem. The same project contained in timedt.zip also shows how to get file name and versions into the test log. The example used PVCS but the method used should work on other systems as far as I know.


Top


 

Formatted memory dump to log file function for D-Scope

Some while ago I needed to dump out a block of memory to a log file for a unit test. It was to prove that something actually had been written to the memory. The function given a start address, end address and the number of columns you want will print it out complete with the start address of each line. Several examples, cut from an actual log file, are shown below. It also handles the instances where more columns are asked for than there are memory locations. (See last example) The function can be down loaded in memdump.zip . The zip file does NOT contain any executable files. NOTE, This version now prints out in blocks of x lines. Each block separated by a line and a row of offset numbers. Both are included in the zip file. The lines have also been adjusted to match the width of the block.

=======================================
Memory Contents between 0x4770 and 0x4780
Offset   :  0  1  2  3  4  5  6  7  8  9
X:0x4770 : 00 00 00 00 00 00 00 00 00 00 
X:0x477a : 00 00 00 00 00 00
 =======================================
Exec log off
 =======================================
Memory Contents between 0x4770 and 0x4780
Offset   :  0  1  2  3  4  5  6
X:0x4770 : 00 00 00 00 00 00 00 
X:0x4777 : 00 00 00 00 00 00 00 
X:0x477e : 00 00
 =======================================
Exec log off
 =======================================
Memory Contents between 0x4770 and 0x4780
Offset   :  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  10  11
X:0x4770 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 =======================================
Exec log off


Top


 Universal print to log functions

One of the headaches I used to have was editing test script templates to print to a specific log file. i.e. test1.log, test35.log etc. I looked for a way round this. Some way of only having to change the name once. Originally I thought of something like "DEFINE LOGFILE filename.log" and using "log >> LOGFILE" This sort of thing will not work in D-Scope. Then I came across the following (it is not an original idea) which I adapted into two functions.

func void start_log(void){                              
       exec("log > e:\\projects\\Testlog.log");                      
} 

func void append_log(void){                              
       exec("log >> e:\\projects\\Testlog.log");                      
}

There are two functions that are almost identical. the difference is in the > and >>. The first one clears any log of the same name. The second just appends. I use the first one "start_log" at the start of a script to clear any old results lying around and then the "append_log" throughout the test. Thus I onlyhave to change the name of the log file in two places. All the scripts make one call to start_log() multiple calls to append_log(); Of course the log off command is universal as there can only be one log file open at a time.


Top


 Universal log Serial output to File

func void start_Serial_log(void){                              
       exec("SLOG> e:\\projects\\Testlog.log");                      
} 

func void append_Serial_log(void){                              
       exec("SLOG >> e:\\projects\\Testlog.log");                      
}

See Chapter 5 of the uVision "Getting Started" manual, or the Debug Commands online Help

There are two functions that are almost identical. the difference is in the > and >>. The first one clears any log of the same name. The second just appends. I use the first one "start_serial_log" at the start of a script to clear any old results lying around and then the "append_lserial_og" throughout the test. Thus I only have to change the name of the log file in two places. All the scripts make one call to start_serial_log() multiple calls to append_serial_log(); Of course the slog off command is universal as there can only be one slog file open at a time.

Top


 

Universal D-Scope memset that takes variables as parameters

The memset routine provided in C takes variables as parameters. The D-Scope memset does not in the same way. This can be a problem. What I wanted to do, as in C, was memset(Start_Addr, End_Addr, Fill_Value). D-Scope needs to know the memory space as in X:0x4770. I could see no way of getting the X: in to the variable. So I consulted the Keil Discussion Forum where Jon Ward of Keil came to the rescue. This is how it is done memset (0x010000 | Start_Addr, 0x010000 | End_Addr, Fill_Value);. Jon explained that: The prefix (or segment) is the upper byte of the 24-bit addresses. This is also known as the memory type byte in C51 lingo.


0xFF is CODE,
0xFE is PDATA
0x01 is XDATA,
0x00 is DATA, Idata, Bdata


The memset shown above is for XDATA.
This is fine however it meant I still did not have a universal memset I could call. So I simply wrote a wrapper containing all four (Code, Pdata, Xdata and Data) memsets and a switch that would switch on an additional parameter giving memory type.


unimemset(Start_addr, End_Addr, Fill_Value, Type)
In addition the unimemset prints out confirmation of the start address, end address, fill value and memory type. (This is useful for log files). It will complain at an incorrect memory type and if the start address is higher than the end address. It is conceivable that you might want the start and end addresses the same to set only one byte. (Sillier things have happened!). The function does not range check. That is up to the user.
The function is available in
Memset.zip.


Top

 
       
 Last updated 25-Jan-2003 and still under construction!
Copyright Chris A Hills 2002
The right of Chris A Hills to be identified as the author of this work has been asserted by him in accordance with the Copyright, Designs and Patents Act 1988