Notify Module Overview
From Texas Instruments Embedded Processors Wiki
Contents |
Overview
The NOTIFY module abstracts physical interrupts into multiple logical events. It provides a simple and quick method of sending 32-bit message.
Availability
The NOTIFY module is available in DSPLink releases from 1.40.03 onwards.
Features
- Multiple clients can register for same event
- Clients may be processes or threads/tasks
- Callback function can be registered with an associated parameter to receive events from remote processor
- All clients get notified when an event is received
- Multiple clients can send notifications to the same event
- Events are sent across to the remote processor
- 32-bit payload value can be sent alongwith the event
- Multiple different events can be sent at the same time to the other processor
- If the same event number is to be sent again, the
NOTIFY_send ()function internally spins till the other processor has read and cleared the previous event for the same event number. In caes of ARM->DSP, the number of times that theNOTIFY_sendpolls for event to be cleared by the other side is configurable in order to support error scenarios where DSP may have crashed without clearing the event.
- Event IDs are prioritized.
- 0 -> Highest priority
- 31 -> Lowest priority
- If multiple events are set, highest priority event is always signaled first
- Notification can be unregistered when no longer required
Usage
Header files
The header file to be included for using NOTIFY module on both GPP and DSP-side is notify.h
#include <notify.h>Dependencies
- Apart from PROC, NOTIFY module has no dependencies on any other modules in DSPLink. The PROC module is expected to be initialized through calls to
PROC_setupandPROC_attach. Since DSP will be used,PROC_loadandPROC_startare also needed.
- Notably, the NOTIFY module is the only module in DSPLink that has no dependency on POOL buffers or POOL configuration.
- For DSP->GPP event notification, NOTIFY APIs must be used only after
DSPLINK_init()is called so that the modules have been initialized on DSP-side. Usually DSPLink will get initialized before main (e.g. if POOL is used, through DSPLink POOL initialization function plugged into DSP/BIOS). But if POOL, CHNL and MSGQ are all scaled out in the build, theDSPLINK_init()inmain()is the one that actually initializes these modules on DSP-side. - If POOL, CHNL and MSGQ are all included in the build, the very first init (i.e.
POOL_init()) initializes the modules, soNOTIFY_notify()can be called anytime after this. This enables usage of NOTIFY very early in the DSP/BIOSTM boot process.
Configuration
The NOTIFY module is configured through the DSPLink dynamic configuration file $(DSPLINK)/config/all/CFG_<PLATFORM>.c
Example
NOTIFY module configuration in file $(DSPLINK)/config/all/CFG_Davinci_DM6446.c from DSPLink 1.51 release is given below.
/** ============================================================================ * @name LINKCFG_ipsTable_00 * * @desc IPS table ID 0. * ============================================================================ */ STATIC LINKCFG_Ips LINKCFG_ipsTable_00 [] = { { "IPS", /* NAME : Name of the Inter-Processor-Signaling component */ (Uint32) 32, /* NUMIPSEVENTS : Number of IPS events to be supported */ (Uint32) 0, /* MEMENTRY : Memory entry ID (-1 if not needed) */ (Uint32) 46, /* GPPINTID : Interrupt no. to used by the IPS on GPP-side. (-1 if uni-directional to DSP) */ (Uint32) 16, /* DSPINTID : Interrupt no. to used by the IPS on DSP-side. (-1 if uni-directional to GPP) */ (Uint32) 4, /* DSPINTVECTORID : Interrupt vector no. to used by the IPS on DSP-side. (-1 if uni-directional to GPP) */ (Uint32) 50000000, /* ARGUMENT1 : Poll value for which IPS waits while sending event (-1 if infinite) */ 0 /* ARGUMENT2 : Second IPS-specific argument */ }, { "IPS", /* NAME : Name of the Inter-Processor-Signaling component */ (Uint32) 32, /* MAXIPSEVENTS : Number of IPS events to be supported */ (Uint32) 1, /* MEMENTRY : Memory entry ID (-1 if not needed) */ (Uint32) 47, /* GPPINTID : Interrupt no. to used by the IPS on GPP-side. (-1 if uni-directional to DSP) */ (Uint32) 17, /* DSPINTID : Interrupt no. to used by the IPS on DSP-side. (-1 if uni-directional to GPP) */ (Uint32) 5, /* DSPINTVECTORID : Interrupt vector no. to used by the IPS on DSP-side. (-1 if uni-directional to GPP) */ (Uint32) 50000000, /* ARGUMENT1 : Poll value for which IPS waits while sending event (-1 if infinite) */ 0 /* ARGUMENT2 : Second IPS-specific argument */ } } ;
Explanation
Each IPS instance provides information and configuration for one ARM<->DSP interrupt pair (in both directions).
The notable fields that may be modified by the user are:
-
DSPINTVECTORID: This indicates the DSP/BIOS HWI interrupt vector ID on the DSP-side. In case the system integrator wishes to use a different interrupt vector ID for the ARM->DSP interrupt, this can be configured in theDSPINTVECTORIDfield. -
ARGUMENT1: This field indicates the timeout value for the IPS. TheNOTIFY_sendimplementation internally spins for the number of time as configured in this field, for the previous event to be cleared by the other processor, before returning with an error indicating timeout. This can be used for error handling to indicate that the DSP has crashed. The ideal value of this field depends on system behavior. For example, if interrupt latencies can be very high, this field should be kept to a high value. If error handling must be done without a visible impact to the user and interrupt latencies will not be very high, then a lower value is to be used. If it is desired (for debugging purposes) to never return with error, -1 can be specified here. In that case, this API will always spin and never timeout.
The index of the IPS instance indicates its ID. This ID needs to be used for the ipsId parameter when using the NOTIFY APIs.
Usage
For sending events from DSP->GPP
- Register notification on the GPP-side for a callback function. For example:
status = NOTIFY_register (ID_PROCESSOR, /* Processor ID to talk with. */ 0, /* IPS ID to be used */ 5, /* IPS event number. Choose any unused number */ myFxn, /* Callback function for debugging */ myArg) ; /* Parameter (if any) for callback function */
- Define the callback function on GPP-side:
Void myFxn (Uint32 eventNo, Pvoid arg, Pvoid info) { /* Print that callback is received. */ printf ("In notify callback eventNo [%d], arg [%d], info [%d]\n", eventNo, arg, info) ; /* Do some processing */ }
- Send notification from DSP-side:
status = NOTIFY_notify (ID_GPP, /* Processor ID to send notification to. */ 0, /* IPS ID to be used */ 5, /* IPS event number. Choose any unused number. */ info) ; /* 32-bit information to be sent across */
- If
NOTIFY_notifyreturns with errorSYS_ENODEV, it indicates that the GPP has not yet registered for this event.
For sending events from GPP->DSP
- Register notification on the DSP-side for a callback function. For example:
status = NOTIFY_register (ID_GPP, /* Processor ID to talk with. */ 0, /* IPS ID to be used */ 5, /* IPS event number. Choose any unused number */ myFxn, /* Callback function for debugging */ myArg) ; /* Parameter (if any) for callback function */) ;
- Define the callback function on DSP-side:
Void myFxn (Uint32 eventNo, Void * arg, Void * info) { /* Do some processing */ }
- Send notification from GPP-side:
status = NOTIFY_notify (ID_PROCESSOR, /* Processor ID to send notification to. */ 0, /* IPS ID to be used */ 5, /* IPS event number. Choose any unused number. */ info) ; /* 32-bit information to be sent across */
- If
NOTIFY_notifyreturns with errorDSP_ENOTREADY, it indicates that the DSP has not yet registered for this event.

