# Callbacks This section describes the prototypes and expected functionality of the various callback functions used for event notification from the simulator. All of these functions are expected to have a C-callable interface. All of these functions require a handle as their first argument. The simulator treats this handle as the identifier for the entity (co-simulation or system simulation application). The simulator never dereferences this handle; the requesting entity is to have a placeholder for any context that might be required. A typical usage is to allocate and populate a context structure for a co-simulation. ## Co-simulation required functions For a co-simulation library, the following functions must be defined: - [GetCosimVersion()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#getcosimversion) - [UnRegisterCosim()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#unregistercosim) - Either [RegisterCosim()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#registercosim) or [RegisterCosimArgs()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#registercosimargs) The short form, RegisterCosim(), is for cosims that do not require arguments. For example, a monitor that collects profiling information. The long form, RegisterCosimArgs(), is for cosims that can be configured. For example, a secondary interrupt controller whose configuration parameters might be its size (the number of interrupts it can service), base address of its memory-mapped registers, and primary Hexagon interrupt to which it is attached. The RegisterCosim() and GetCosimVersion() functions are the first functions called by the simulator; these calls allow the cosim to initialize itself. - The simulator first calls GetCosimVersion() to determine the API version compatibility. - Then the simulator calls either RegisterCosimArgs() or RegisterCosim(): - The simulator looks first for RegisterCosimArgs() and, if present, calls it and does not look for RegisterCosim(). - If RegisterCosimArgs() does not exist, the simulator calls RegisterCosim(). - The simulator calls UnRegisterCosim() during its shutdown procedure. During the cosim initialization, the cosim can register to receive event notifications from the simulator. Typically, a cosim registers a function to be called when any of its memory-mapped registers are read or written, or it registers a function to be periodically called based on elapsed simulator-time. During the cosim shutdown procedure, the cosim is expected to clean up any resources that it used (including removing callbacks, freeing memory, and so on) and prepare for shutdown. ### GetCosimVersion() Used by the simulator to determine the version of HexagonWrapper.h that was used to build the cosim. This function is required for determining API compatibility. - **Prototype** - char * GetCosimVersion (void); Copy to clipboard - **Detailed description** - This global function is called by the simulator library before it calls [RegisterCosim()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#registercosim) or [RegisterCosimArgs()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#registercosimargs). The value that the cosim must return is defined in HexagonWrapper.h as HEXAGON\_WRAPPER\_VERSION. This is a required function that must be implemented in every cosim. - **Returns** - Version number of the cosim from [HexagonWrapper.h](https://docs.qualcomm.com/doc/80-N3040-23/topic/system-interface.html#simulator-constructor-hexagonwrapper)) ### RegisterCosim() Used by the simulator to allow a cosim to self-identify and register for callbacks. - **Prototype** - void * RegisterCosim(char **name, HexagonWrapper *simPtr); Copy to clipboard - **Parameters** - | out | *name* | Double pointer to the name of the cosim.


This value is allocated and filled in by the cosim and passed
to the simulator. | | --- | --- | --- | | in | *simPtr* | Pointer to the Hexagon simulator. | - **Detailed description** - This function is called by the simulator after the call to [GetCosimVersion()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#getcosimversion). The HexagonWrapper pointer argument provides a handle to the API interface, which can be used by the cosim to register for callbacks. Before returning from the function call, the cosim must assign itself a unique name using the **name** argument. This is a required function that must be implemented in every cosim, unless RegisterCosim() is used instead. - **Returns** - Arbitrary pointer used to identify this cosim. ### RegisterCosimArgs() Used by the simulator to allow a cosim to self-identify, register for callbacks, and parse arguments passed to the cosim. - **Prototype** - void * RegisterCosimArgs(char **name, HexagonWrapper *simPtr, char *args); Copy to clipboard - **Parameters** - | out | *name* | Double pointer to the name of the cosim.


This value is allocated and filled in by the cosim and passed
to the simulator. | | --- | --- | --- | | in | *simPtr* | Pointer to the Hexagon simulator. | | in | *args* | Argument string to the cosim. | - **Detailed description** - This function is called by the simulator after the call to [GetCosimVersion()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#getcosimversion). The HexagonWrapper pointer argument provides a handle to the API interface, which can be used by the cosim to register for callbacks. Before returning from the function call, the cosim must assign itself a unique name using the **name** argument. The args string can be parsed to process command line arguments passed to the cosim. This is a required function that must be implemented in every cosim, unless [RegisterCosim()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#registercosim)is used instead. - **Returns** - Arbitrary pointer used to identify this cosim. ### UnRegisterCosim() Used by the simulator to allow a cosim to prepare for termination. - **Prototype** - void UnRegisterCosim(void *handle); Copy to clipboard - **Parameters** - | in | *handle* | Pointer to the handle given to the simulator when the cosim was
registered. | | --- | --- | --- | - **Detailed description** - This global function is called by the simulator library. The installed cosim is requested to clean up and prepare for termination. The handle passed in is the same handle returned from [RegisterCosim()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#registercosim) or [RegisterCosimArgs()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#registercosimargs). This function is required and must be implemented in every cosim. - **Returns** - None. ## Callback functions All callback functions are expected to be C-callable. The handle passed to the callback function is the same handle provided when the callback was registered with the simulator. Note The callback function names are for illustration purposes only; they can be renamed. ### [BusTransactionRequestCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#contents) Called by the simulator library to initiate a bus transaction. - **Prototype** - HEXAPI_TransactionStatus BusTransactionRequestCallback(void *handle, HEX_PA_t addr, HEX_4u_t lengthInBytes, HEX_1u_t *data, HEX_4u_t requestID, HEXAPI_BusAccessType batype, HEX_4u_t threadNum, HEXAPI_BusBurstType bt); Copy to clipboard - **Parameters** - | in | *handle* | The handle given to the simulator when the callback request was
added. | | --- | --- | --- | | in | *addr* | Address of the write or read that corresponds to the
transaction. | | in | *lengthInBytes* | Size of data in bytes. | | in | *data* | Pointer to the data returned by external bus. | | in | *requestID* | ID used to identify this bus transaction. This ID must be
provided to the [BusTransactionFinished()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#bustransactionfinished) call to
complete this bus request. | | in | *batype* | Type of bus access.
| | in | *threadNum* | The hardware thread number of the thread making the request. | | in | *bt* | Type of bus burst.
| - **Detailed description** - This interface allows the external bus model to model data as well as timing behavior. To indicate the end of the transaction, the external device calls [BusTransactionFinished()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#bustransactionfinished) A batype value of HEX\_DEBUG\_READ, HEX\_DEBUG\_WRITE, HEX\_DEBUG\_READ\_LOCKED, or HEX\_DEBUG\_WRITE\_LOCKED indicates a debug-related transaction. In this case the cosim should perform the requested action and immediately complete the request by calling BusTransactionFinished()*.* If the transaction cannot be completed, an error is returned. Note Debug read and write transactions are also designated with a requestID of 0xFFFFFFFF. - **Returns** - - TRANSACTION\_SUCCESS - TRANSACTION\_REPLAY - Reissue the transaction. - TRANSACTION\_FAIL - Transaction failure. - TRANSACTION\_LOCKED - Memory is locked. ### [TimedCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#contents) Called by the simulator library at certain intervals, provided the cosim registered to be called using [AddTimedCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#addtimedcallback). - **Prototype** - void TimedCallback(void *handle); Copy to clipboard - **Parameters** - | in | *handle* | Pointer to the handle given to the simulator when the callback
request was added. | | --- | --- | --- | - **Returns** - None. ### [MemoryWasWrittenCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#contents) Called by the simulator library when data is written to system memory (inclusive of cache, TCM, and bus transactions), provided the cosim registered to be called using [AddMemWasWrittenCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#addmemwaswrittencallback). - **Prototype** - void MemoryWasWrittenCallback(void *handle, HEX_PA_t addr, HEX_8u_t value, HEX_4u_t sizeInBytes); Copy to clipboard - **Parameters** - | in | *handle* | Pointer to the handle given to the simulator when the callback
request was added. | | --- | --- | --- | | in | *addr* | Address of the memory write. | | in | *value* | Value written to memory. | | in | *sizeInBytes* | Size of the data (1, 2, 4, or 8 bytes). | - **Returns** - None. ### [MemoryWasReadCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#contents) Called by the simulator library when data is read from system memory (inclusive of cache, TCM, and bus transactions), provided the cosim registered to be called using [AddMemWasReadCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#addmemwasreadcallback). - **Prototype** - void MemoryWasReadCallback(void *handle, HEX_PA_t addr, HEX_8u_t value, HEX_4u_t sizeInBytes); Copy to clipboard - **Parameters** - | in | *handle* | Pointer to the handle given to the simulator when the callback
request was added. | | --- | --- | --- | | in | *addr* | Address of the memory read. | | in | *value* | Value read from memory. | | in | *sizeInBytes* | Size of the data (1, 2, 4, or 8 bytes). | - **Returns** - None. ### [FrequencyChangeCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#contents) Called by the simulator library when the Hexagon core frequency is changed by an external agent, provided the cosim registered to be called using [AddFrequencyChangeCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#addfrequencychangecallback). - **Prototype** - void FrequencyChangeCallback(void *handle, HEX_8u_t coreFrequency); Copy to clipboard - **Parameters** - | in | *handle* | Pointer to the handle given to the simulator when the callback
request was added. | | --- | --- | --- | | in | *coreFrequency* | New frequency of the Hexagon core. | - **Returns** - None. ### [PCCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#contents) Called by the simulator library when the Hexagon processor is ready to commit the instruction at the PC specified with the [AddPCCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#addpccallback) function. - **Prototype** - void PCCallback(void *handle); Copy to clipboard - **Parameters** - | in | *handle* | Pointer to the handle given to the simulator when the callback
request was added. | | --- | --- | --- | - **Returns** - None. ### [CoreReadyCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#contents) Called by the simulator library when the core’s CORE\_READY signal changes state, provided the cosim registered to be called using [AddCoreReadyCallback()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#addcorereadycallback). This function indicates whether the core is ready to accept second-level interrupts. - **Prototype** - void CoreReadyCallback(void *handle, HEXAPI_CoreReadyState polarity); Copy to clipboard - **Parameters** - | in | *handle* | Pointer to the handle given to the simulator when the callback
request was added. | | --- | --- | --- | | in | *polarity* | State of polarity.
| - **Returns** - None. ## Cosim example The following example implements a simple cosim using the system simulation APIs. This cosim merely prints a message after a specified time period has elapsed. #include "HexagonWrapper.h" typedef struct { // Simple context structure int interval; HexagonWrapper *simPtr; } TimerContext; void timed_callback(void *handle); // Routine to be called int parseAndValidateArgs(char *args, TimerContext *c); extern "C" { void INTERFACE *RegisterCosimArgs(char *name, HexagonWrapper *simPtr, char *args) { int cerror; TimerContext *pTimer = (TimerContext *) calloc(1, sizeof(TimerContext); pTimer->simPtr = simPtr; // Save pointer // Parse options for cosim - sets callback interval cerror = parseAndValidateArgs(args, pTimer); if (cerror == 0) { printArgUsage(cerror); exit(0); } // Get called back every ns simPtr->AddTimedCallback(pTimer, pTimer->interval, HEX_NANOSEC, timed_callback); return (void *) pTimer; } } void timed_callback(void *handle) { TimerContext c = (TimerContext *) handle; printf("Called back, interval=%dns\n", c->interval); c->simPtr->RemoveTimedCallback((void *) c); } int parseAndValidateArgs(char *args, TimerContext *c) { return (c->interval = atoi(args)) != 0); } extern "C" { void INTERFACE UnRegisterCosim(void *handle) { TimerContext c = (TimerContext *) handle; // Free resources allocated. Should also remove callback, but that was done above. free(c); } char * INTERFACE GetCosimVersion(void) { // Required vor version checking by the simulator return HEXAGON_WRAPPER_VERSION; } } Copy to clipboard ### Build this cosim 1. Compile the cosim and link it into a shared library. 2. Build a cosim configuration file that contains the pathname to the shared library followed by an argument specifying the interval after which the message is printed. For example: //cosim.so 200 Copy to clipboard Note This command specifies that the cosim should be loaded and the string, 200, passed to the cosim initialization routine ([RegisterCosimArgs()](https://docs.qualcomm.com/doc/80-N3040-23/topic/callbacks.html#registercosimargs)). 3. Specify the cosim configuration file to the simulator either by command-line option or API function (see [co-simulation](https://docs.qualcomm.com/doc/80-N3040-23/topic/system-interface.html#simulator-co-simulation) for details). ### Output When the cosim executes, it prints out the message after 200 ns of elapsed simulation time. Last Published: Oct 06, 2026 [Previous Topic PostMessageToSimulator()](https://docs.qualcomm.com/bundle/publicresource/80-N3040-23/topics/system-interface.md) [Next Topic Statistics](https://docs.qualcomm.com/bundle/publicresource/80-N3040-23/topics/statistics.md)