TAPS
The AMX Prototyping System


 Contents

 Overview
 Getting Started with the AMX Sample Program
 Comparison of AMX and TAPS Development
 Creating a TAPS Project using the Visual C++ 2005 IDE
 Debugging with KwikLook for TAPS
 Editing the Application Interface Module
 TAPS API Functions

Note:
This manual describes how to use TAPS with Visual C++ 2005.
Instructions for using TAPS with Visual C++ 6.0 are provided in a separate manual.
Instructions for using TAPS with Visual C++.NET are provided in a separate manual.



 Overview

The AMX Prototyping System (TAPSTM) is a prototyping system that you can use to develop and debug AMX applications on a Windows workstation, without any real target hardware.

 Requirements

CPU   Pentium (or better) at 100 MHz (or greater) with
32 Mb of RAM
OS   Any Windows 32-bit OS including:
Windows Vista, XP, 2000 and Server 2003
Tools    Microsoft Visual C++ 2005

 Multitasking Model

A TAPS application runs as a single thread within a Win32 application. TAPS includes a fully functional AMX implementation which does not use Win32 services to simulate multitasking operation.

Instead, TAPS provides a complete AMX multitasking environment which operates within the single TAPS Win32 thread. The TAPS version of AMX executes in a non-preemptive manner without support for interrupts.

As with any AMX implementation, the current task will always be the highest priority task which is ready for execution. However, under TAPS, the current task cannot be preempted by an external event such as an interrupt. The current task will only be suspended if it calls some AMX function which forces the task to wait for some event.

When used with TAPS, your application tasks must not be compute bound. Any compute bound task will prevent TAPS from generating its simulated AMX clock ticks, thereby precluding the use of AMX timing services. If your task must "spin", be sure to call AMX function cjtkdelay(1) from time to time.

 External Event Simulation

External events are simulated by the TAPS Event Generator, a function which is called by the TAPS Control Task, the built-in task that runs at the lowest AMX priority. The TAPS Event Generator simulates "hardware" clock ticks at the frequency specified in your application User Parameter File.

Device I/O operations can be simulated if your application uses the cjcfinXX/cjcfinpXX and cjcfoutXX/cjcfoutpXX functions provided by AMX. These low-level I/O operations are all funneled through the TAPS I/O Access Procedure which can be modified to mimic the results of I/O operations on your hardware.

All of the functions which can be adapted by you to test your AMX application are provided in source file CJ302AIF.C.

 Simulated Hardware Devices

The TAPS AMX Library provides support for two simulated hardware devices: a clock and a UART.

The simulated clock device provides timing based on the Windows Performance Counters. These counters provide a very accurate timing source. Since TAPS does not support interrupts, the clock ticks are generated by calls from the TAPS Event Generator to the TAPS function taps_clocktick().

The simulated serial I/O device is a polled (not interrupt driven) device that is accessed via the simple AMX chuart() interface provided with the AMX Sample Program. Character input is read from the stdin data stream and written to the stdout data stream that is available to Win32 console applications.

 



 Getting Started with the AMX Sample Program

TAPS includes a copy of the AMX Sample Program ready for use on a Windows workstation using the Visual C++ 2005 IDE. For more detailed information about the AMX Sample Program for TAPS, read Chapter 2.4 of the AMX Getting Started manual.

To build and run the sample program, start the Visual C++ 2005 IDE and follow these simple steps:

  1. Open the project file
    C:\TAPS302\SAMPLE\SAMPLE.DSP
    via the File ==> Open Project... dialog using
    Files of type: Visual C++ Projects.
     
    The SAMPLE.DSP project will be automatically
    converted to the new "solution" format used by
    the Visual C++ 2005 tools.
     
  2. Build the AMX Sample Program using the
    Build ==> Build SAMPLE directive.
     
  3. Run the AMX Sample Program using the
    Debug ==> Start Debugging directive.
     

The AMX Sample Program will run in its own console window.
New messages will appear in the window periodically.
After one minute, the sample program will stop.

 



 Comparison of AMX and TAPS Development

  Target Specific AMX Application TAPS Application
A. Create a MAKE file to compile, assemble and link your AMX application modules, following the compilation, assembly and linking instructions described in the AMX Tool Guide.

Create a new TAPS project using the Visual C++ 2005 IDE. In the project's settings, set the appropriate compilation options for all C/C++ modules.

B. Select the AMX Clock Driver which most closely matches your target hardware. Compile the driver. TAPS provides its own built-in clock driver.
C. Use the AMX Configuration Manager to create a User Parameter File describing your AMX application requirements. Use the Manager to generate your System Configuration Module. Compile the module. Use the TAPS version of the AMX Configuration Manager to create your User Parameter File and to generate your System Configuration Module from it.
 
You can add commands to your Visual C++ project to generate the System Configuration Module from your User Parameter File by following these instructions.
D. Use the AMX Configuration Manager to create a Target Parameter File defining your target hardware. Use the Manager to generate your Target Configuration Module. Assemble the module. Skip this step. TAPS does not use a Target Configuration Module.
E. Review the AMX startup module CJnnnUF.C and, if your needs warrant, add enhancements to the default error handling procedures. Compile the module. Review the TAPS Application Interface Module CJ302AIF.C and, if necessary, add enhancements to the TAPS Event Generator, the TAPS I/O function and the AMX error handling procedures. Compile the module.
F. Compile your main() C program and AMX application modules. Add your application modules to the TAPS Visual C++ project.
G. Link the modules from the previous steps with the AMX Library and the C Library to create your AMX application load module. Link the modules from the previous steps with the TAPS Library (CJ302.LIB) to create your TAPS application executable file.
H. Using a debugger, load your application into your target hardware and then execute it. Using the Visual C++ debugger, run your application executable. Set breakpoints on functions cjksbreak() and taps_notavail() if you want to trap these events. Use the built-in TAPS version of KwikLook to help you with your testing.

 



 Creating a TAPS Project using the Visual C++ 2005 IDE

It will be assumed that TAPS has been installed in directory C:\TAPS302. It is assumed that your AMX User Parameter File is named SAMPLSCF.UP. For purposes of illustration, a project named SAMPLE will be created in directory C:\SAMPLE. Be sure to change all strings marked as blue text to match your particular TAPS installation directory and file names.

 

Step 1: Create a new Visual C++ Project

From the Visual C++ 2005 IDE, select the File ==> New ==> Project... menu option and create a new Win32 Console Application. In the New Project dialog that appears, enter the properties as shown. For the purposes of this sample, please note that the option Create directory for solution is not selected.

In the Win32 Application Wizard dialog that appears next, set the Application Settings to create a Console Application as an Empty Project.

 

Step 2: Add the System Configuration Module to the Visual C++ Project

Step 2.1: Create the User Parameter File

Use the TAPS version of the AMX Configuration Manager to create your User Parameter File. Note that the TAPS version of the manager does not permit editing of an AMX Target Parameter File.

If you wish, you can use the Configuration Manager to generate the System Configuration Module. If you choose to do so, skip forward to Step 2.5. Be aware that the downside of this method is that every time you change your User Parameter File, you will have to remember to regenerate your System Configuration Module as well.

It is recommended that you follow Steps 2.2 through 2.5 so that your project will automatically regenerate and compile your System Configuration Module if your User Parameter File is edited.

 

Step 2.2: Add the User Parameter File to the Visual C++ Project

From the main menu, select the Project ==> Add Existing Item... command to bring up the Add Existing Item dialog box. In this dialog box, select your User Parameter File (SAMPLSCF.UP). You may need to set the Files of type: selection to "All Files (*.*)" to make your User Parameter File visible in the file list.

The following dialog should then appear. Click No.

 

Step 2.3: Set the Build Options for the User Parameter File

Go to the solution pane of your project and open the tree branch for your project.

Right click on the icon for your User Parameter File (SAMPLSCF.UP) and select the Properties command from the popup menu to bring up the file's Property Pages dialog box.

In the Property Pages dialog, go to the Configuration drop-down list box and select the "All Configurations" option.

Next, select the General category under Custom Build Step and enter the following strings in the specified fields:

Command Line c:\taps302\cfgbldw\cj302cg.exe $(InputPath)
      c:\taps302\cfgbldw\cj302cg.ct .\$(InputName).C
Description Generating $(InputName).C
Outputs .\$(InputName).C

 

Step 2.4: Generate the System Configuration Module

Go back to the TAPS project solution pane.

Right click on the icon for your User Parameter File (SAMPLSCF.UP) and select the Compile SAMPLSCF.UP command from the popup menu to generate your System Configuration Module (SAMPLSCF.C).

 

Step 2.5: Add the System Configuration Module to the Project

From the main menu, select the Project ==> Add Existing Item... command to bring up the Add Existing Item dialog box again. Select the newly generated System Configuration Module (SAMPLSCF.C).

Your Visual C++ project is now setup to generate and compile your System Configuration Module.

 

Step 3: Add the TAPS Application Interface Module

Copy the TAPS Application Interface Module (C:\TAPS302\SAMPLE\CJ302AIF.C) to your TAPS project directory. If necessary, edit the file to provide the event and I/O simulation services required to meet the needs of your AMX application.

Next, from the Visual Studio main menu, select the Project ==> Add Existing Item... command to bring up the Add Existing Item dialog box. In this dialog box, select the CJ302AIF.C module.

 

Step 4: Add your AMX Application Modules

From the main menu, select the Project ==> Add Existing Item... command to bring up the Add Existing Item dialog box. In this dialog box, select all of the C and C++ files which make up your AMX application.

 

Step 5: Set the project options

There are three options that must be set to compile a TAPS application correctly. From the main menu select the Project ==> Properties menu option to invoke the project's Property Pages dialog.

Begin by adding the directory containing the TAPS header files to the list of include directories to be searched. In the C/C++ folder, select the General category and append the text C:\TAPS302\DEF to the Additional Include Directories field. If you specify multiple include directories, each must be separated from its predecessors by a semicolon.

Next, the application must be set to use the Multi-threaded runtime library. This option is located in the Code Generation category of the C/C++ folder. The TAPS AMX Library was compiled for use with the Multi-threaded runtime library.

If you wish, you may compile your application with the Multi-threaded Debug runtime library. In this case, you must tell the linker to ignore the default runtime library requested by the TAPS AMX Library. To do so, go to the Linker folder, select the Input category and tell the linker to ignore the LIBCMT library.

Additionally, in the Input category of the Linker folder, you must include the WINMM.LIB library in the link. This library is needed by the TAPS Application Interface Module. Unfortunately, the library is not automatically included when Visual C++ generates a project.

 

Step 6: Link with the TAPS AMX Library

From the main menu, select the Project ==> Add Existing Item... command to bring up the Add Existing Item dialog box. In this dialog box, select the CJ302.LIB library from the C:\TAPS302\LIB directory.

The following dialog should then appear. Click No.

 



 Debugging with KwikLook for TAPS

TAPS includes its own version of the KwikLook Fault Finder integrated with the Visual C++ 2005 IDE. KwikLook gives you quick fingertip access to everything controlled by AMX and its managers.

When TAPS is installed, it automatically integrates KwikLook with your Visual C++ 2005 IDE. When you open the Visual C++ 2005 IDE, you will find a new KwikLook item at the top of the Tools menu which can be used to invoke KwikLook. You will also find a new button on the Debug toolbar which can also be used to invoke KwikLook. The Debug toolbar is normally hidden and becomes visible when the debugger is started.

To use KwikLook, start your AMX application with the Microsoft debugger and begin debugging your system. When the debugger stops at a breakpoint, you can activate KwikLook by clicking its menu item or toolbar button.

 



 Editing the Application Interface Module

The TAPS Application Interface Module, CJ302AIF.C, contains fragments of code that can be modified to simulate external events and target hardware. There are two types of code: device I/O functions and error handlers.

Device I/O functions are used to simulate access to hardware devices and to generate the events that would normally be caused by device interrupts.

Error handlers are procedures that are called by AMX when abnormal conditions are detected. By default, these functions provide basic error reporting. If you wish, you can modify them to provide more extensive error handling and/or recovery features.


  Device I/O Functions

 Function:    chbrdinit - Board Initialization Function
Prototype:   void CJ_CCPP chbrdinit(void);
Description:   This function is usually called by your main() program before AMX is launched. In most target systems, this function initializes the target hardware. You may modify this function to simulate your target hardware.
By default:  

Does nothing.

     
 Function:   taps_events - TAPS Event Generator
Prototype:   void taps_events(void);
Description:  

This function is called by the TAPS Control Task. It is responsible for generating "external" events such as clock ticks. It must not return until the event object identified by taps_quitid() has been signaled. Typically, this function consists of a WaitForMultipleObjects() loop.

You may modify this function to simulate events that are normally generated by your target hardware. Events can often be simulated by calling AMX functions such as cjtkwake(), cjmbsend() or cjsmsignal() to force a blocked task to resume execution.

Important: Since this function executes in the context of the low priority TAPS Control Task, it will be blocked by any compute bound tasks in your AMX application. Therefore, any compute bound task will prevent simulated external events from being generated.

Warning: If this function calls an AMX procedure (such as cjtkwait()) which blocks the calling task, all TAPS activity will cease. Your application will appear to be hung.
 

By default:  

Calls WaitForMultipleObjects() repeatedly. If the event object identified by taps_clockid() is signaled, function taps_clocktick() is called to simulate a clock hardware tick. If the event object identified by taps_quitid() is signaled, the function returns to the TAPS Control Task.

     
 Function:   taps_iop - Device I/O Access Procedure
Prototype:   CJ_T32 taps_iop(unsigned long port, int bytes, int dir);
Description:  

All AMX I/O operations (cjcfinXX/cjcfinpXX, cjcfoutXX/cjcfoutpXX) funnel through this function. You may modify this function to simulate your target hardware.

Port  is the I/O port or I/O memory address to read/write
Bytes is the number of bytes to read/write (1, 2 or 4)
Dir   is the direction of the I/O operation (0 = read, 1 = write)
 

Return:  

For input operations (dir=0) - value read from the simulated hardware register
For output operations (dir=1) - undefined

By default:  

Logs the I/O operation to the Windows debugger.
Always returns the value zero.

     

  Error Handlers

 Function:   cjksfatal - Fatal Exit Procedure
Prototype:   void CJ_CCPP cjksfatal(int error, CJ_ID taskid);
Description:  

This function is called by AMX whenever it detects a fatal error condition in which to proceed would invite disaster. For more information, see Chapter 14.1 of the AMX User's Guide.

By default:  

Logs the fatal error code and taskid to the Windows debugger.
Calls the Win32 DebugBreak() function to force the debugger to pause execution.

If execution is allowed to continue from the breakpoint, this function terminates the TAPS AMX application by calling the Win32 FatalExit() function.

     
 Function:   cjkserror - Application Error Procedure
Prototype:   int CJ_CCPP cjkserror(int error, CJ_ID taskid);
Description:   This function is called by AMX whenever an AMX procedure detects an error condition. For more information, see Chapter 14.2 of the AMX User's Guide.
By default:  

AMX warnings are ignored and the system is allowed to proceed. All other AMX errors are trapped to function cjksbreak() on which a breakpoint can be set. Some errors and warnings that occur during AMX launch will cause a fatal exit via cjksfatal().

     
 Function:   cjksbreak - Debugger Breakpoint Procedure
Prototype:   void CJ_CCPP cjksbreak(void);
Description:   This function is called by the Application Error Procedure, cjkserror(). You may use the Windows debugger to set a breakpoint on this function to halt execution whenever an application error occurs. For more information, see Chapter 14.2 of the AMX User's Guide.
By default:   Does nothing.
     
 Function:   taps_notavail - Unimplemented Function Procedure
Prototype:   void CJ_CCPP taps_notavail(const char *fnname);
Description:   This function is called by AMX functions such as interrupt vector and cache management functions which are not implemented by TAPS. The fnname parameter references a string containing the name of the unimplemented function.
By default:   Logs the name of the unimplemented function to the Windows debugger.

 



 TAPS API Functions

TAPS provides a number of functions to aid in hardware simulation and debugging.

 Function:    taps_priority - Get the priority of the TAPS Control Task
Prototype:    int CJ_CCPP taps_priority(void);
Description:    Call this function to determine the current execution priority of the TAPS Control Task. The priority, normally the lowest allowed by AMX, will be raised during TAPS shutdown processing.
Return:    Current priority of the TAPS Control Task.
      
 Function:    taps_clocktick - Simulate a Hardware Clock Tick
Prototype:    void CJ_CCPP taps_clocktick(void);
Description:   

Since TAPS does not support interrupts, a hardware clock must be simulated to provide a source of AMX ticks. The TAPS Event Generator normally calls this function to simulate hardware clock ticks. However, you are free to call this function at any time to generate a clock tick.

When called, this function generates zero or more simulated "hardware" clock ticks depending upon the actual time which has elapsed since the last call to the function. The Windows Performance Counters are used to determine the elapsed interval.

The frequency with which this function is called does not affect the simulated clock frequency. Over a long period, the clock frequency will appear correct even though the actual tick generation is erratic since clock ticks can only occur when this function is called.

Note: Calling this function may cause an immediate AMX task switch.

      
 Function:    taps_clockid - Get the TAPS Timer event object handle
Prototype:    void * CJ_CCPP taps_clockid(void);
Description:    The TAPS simulated clock is driven by a timer that periodically signals a Win32 event object created using the Win32 CreateEvent() function. If your application needs access to this event object, call taps_clockid() to retrieve the Win32 object handle.
      
 Function:    taps_printf - Format and log a string on the Win32 debugger console
Prototype:    void taps_printf(const char *fmt, ...);
Description:   

This function calls the Win32 wsvprintf() function to format a string. It then writes the string to the Win32 debugger console using the OutputDebugString() function. The length of the formatted string must be less than 1024 characters. If the string is longer than this limit, an AMX fatal error will be generated.

Warning: This function is not reentrant. The string is formatted into a static buffer for presentation to function OutputDebugString(). If your application calls this function from different tasks, the calls must be mutually exclusive.

     
 Function:    taps_quitid - Get the TAPS Shutdown event object handle
Prototype:    void * CJ_CCPP taps_quitid(void);
Description:    When a TAPS application is ready to shutdown, it signals a Win32 event object, created using the Win32 CreateEvent() function. If your application needs access to this event object, call taps_quitid() to retrieve the Win32 object handle.

 


Top of page



Copyright © 2000-2007
KADAK Products Ltd.
All rights reserved.
 
Last updated: November 1, 2007