📄 sma_priority_driver.c
字号:
{
not_masked = ~mask & i;
if (not_masked != 0 )
{
/*
choose the position with the
highest priority (lowest priority number)
*/
for (j = 0; j < nsources0; j++)
{
if (not_masked & (_BIT(j)) )
{
if (prio->priority_encode0[i] > prio->priorities[j])
prio->priority_encode0[i] = prio->priorities[j];
}
}
}
}
}
}
for (i = 1; i < _BIT(nsources1); i++)
{
for (source = 0; source < nsources1; source ++)
{
mask = 1 << source;
prio->priority_encode1[mask] = prio->priorities[source + 8];
if ( (mask & i) == mask)
{
not_masked = ~mask & i;
if (not_masked != 0 )
{
/*
choose the position with the
highest priority (lowest priority number)
*/
for (j = 0; j < nsources1; j++)
{
if (not_masked & (_BIT(j)) )
{
if (prio->priority_encode1[i] > prio->priorities[j + 8])
prio->priority_encode1[i] = prio->priorities[j + 8];
}
}
}
}
}
}
for (i = 1; i < _BIT(nsources2); i++)
{
for (source = 0; source < nsources2; source ++)
{
mask = 1 << source;
prio->priority_encode2[mask] = prio->priorities[source + 16];
if ( (mask & i) == mask)
{
not_masked = ~mask & i;
if (not_masked != 0 )
{
/*
choose the position with the
highest priority (lowest priority number)
*/
for (j = 0; j < nsources2; j++)
{
if (not_masked & (_BIT(j)) )
{
if (prio->priority_encode2[i] > prio->priorities[j + 16])
prio->priority_encode2[i] = prio->priorities[j + 16];
}
}
}
}
}
}
for (i = 1; i < _BIT(nsources3); i++)
{
for (source = 0; source < nsources3; source ++)
{
mask = 1 << source;
prio->priority_encode3[mask] = prio->priorities[source + 24];
if ( (mask & i) == mask)
{
not_masked = ~mask & i;
if (not_masked != 0 )
{
/*
choose the position with the
highest priority (lowest priority number)
*/
for (j = 0; j < nsources3; j++)
{
if (not_masked & (_BIT(j)) )
{
if (prio->priority_encode3[i] > prio->priorities[j + 24])
prio->priority_encode3[i] = prio->priorities[j + 24];
}
}
}
}
}
}
}
/**********************************************************************
*
* Function: priority_install_handler
*
* Purpose:
* This function installs the handler for a particular
* source. The priority of the handler can be defined, with 0 being
* highest priority and prio-nsources-1 being the lowest.
*
* Processing:
* If the handler function is NULL, if the requested priority is out
* of range, if the source is out of range return prio->nsources.
* Otherwise, install the handler function in the handler array at
* the priority index. If the old priority for the source is the same
* as the new priority, then we are just changing the handler function.
* Otherwise, we have to clear the handler for the source that previously
* had this priority from the priority encoder arrays and reassign the
* priority to the new source.
*
* Parameters:
* prio: a constant pointer to the PRIORITY_DATA structure containing
* the priority encode arrays.
* souce: the bit number of the source.
* priority: a number between 0 and prio->nsources.
* hp: a pointer to a function that handles the source condition
* dhp: a pointer to the unhandled source default handler function
*
* Outputs:
* arrays in the prio structure set up to reflect the handler
* function and the priority
*
* Returns:
* The function returns the priority of the handler if the installation
* is successful, otherwise it returns ILLEGAL_PRIORITY.
*
* Notes:
* It is important that the
* application ensures that every handler is assigned a unique priority.
* Otherwise, the most recently installed handler will be associated
* with the given priority and the previous handler will be lost,
* and may result in the interrupt for the corresponding source not
* being serviced.
*
* (*hp)() must clear the interrupt before it exits.
*
**********************************************************************/
INT_8 priority_install_handler(PRIORITY_DATA * const prio,
INT_8 source,
INT_8 priority,
void (*hp)(void),
void (*dhp)(void))
{
INT_32 old_priority;
if (hp == 0)
return prio->nsources;
if ((INT_32)source < 0 || source >= prio->nsources)
return prio->nsources;
if ((INT_32)priority < 0 || priority >= prio->nsources)
return prio->nsources;
old_priority = prio->priorities[source];
/*
if priority that is already allocated to a different source, remove
the handling for that source.
*/
if (old_priority != priority && prio->handlers[old_priority] != 0)
priority_remove_handler(prio,priority,dhp);
prio->handlers[priority] = hp;
if (old_priority == priority)
return priority; /* just changing the handler */
/* new priority assignment; rebuild tables */
prio->priorities[source] = priority;
rebuild_priority_encode(prio);
return priority;
}
/**********************************************************************
*
* Function: priority_remove_handler
*
* Purpose:
* Remove the assoication between a priority and a source
*
* Processing:
* Set the handler function pointer to 0. Set the
* source priority to prio->nsources and rebuild the priority
* encode tables.
*
* Parameters:
* prio: a constant pointer to the PRIORITY_DATA structure containing
* the priority encode arrays.
* priority: the priority of the source to have its handler removed.
* hp: a pointer to the default handler for unhandled sources.
*
* Outputs:
* prio arrays reflect no handler associated with the source
* that previously had the given priority.
*
* Returns:
* The priority that was removed or prio->nsources if the priority
* was never installed
*
* Notes:
* Use priority_get_priority(source_bit_number) if you don't know
* the priority of the source you wish to remove.
*
**********************************************************************/
INT_8 priority_remove_handler(PRIORITY_DATA * const prio,
INT_8 priority,
void (*hp)(void) )
{
INT_8 source = priority_get_source(prio, priority);
if (source == prio->nsources)
return prio->nsources; // source was not found
prio->handlers[source] = hp;
prio->priorities[source] = prio->nsources;
rebuild_priority_encode(prio);
return priority;
}
/**********************************************************************
*
* Function: priority_get_priority
*
* Purpose:
* Return the priority number associated with a given source
*
* Processing:
* If the source number is in range, return the priority. Otherwise
* return prio->nsources
*
* Parameters:
* prio: a constant pointer to the PRIORITY_DATA structure containing
* the priority encode arrays.
* source: the bit number of the source whose priority is desired
*
* Outputs: nothing
*
* Returns:
* The priority associated with the source or prio->nsources if the
* source is out of range.
*
* Notes: None
*
**********************************************************************/
INT_8 priority_get_priority(PRIORITY_DATA * const prio,
INT_8 source)
{
if (source < 0 || source >= prio->nsources)
return prio->nsources;
return prio->priorities[source];
}
/**********************************************************************
*
* Function: priority_get_handler
*
* Purpose:
* Return the function pointer associated with a given source
*
* Processing:
* Since priority_get_priority() returns a valid index into the
* prio->handlers[] array, return
* prio->handlers[priority_get_priority(prio,source)]
*
* Parameters:
* prio: a constant pointer to the PRIORITY_DATA structure containing
* the priority encode arrays.
* source: the bit number of the source whose priority is desired
*
* Outputs: nothing
*
* Returns:
* A pointer to the handler assoicated with the source
*
* Notes: None
*
**********************************************************************/
void (*priority_get_handler(PRIORITY_DATA * const prio,
INT_8 source))(void)
{
return prio->handlers[priority_get_priority(prio,source)];
}
/**********************************************************************
*
* Function: priority_get_source
*
* Purpose:
* Return the source number associated with a given priority
*
* Processing:
* If the priority is in range, use a sentinel search algorithm to
* determine the source from the priority. If the priority is out of
* range, return prio->nsources. Otherwise, return the source.
*
* Parameters:
* prio: a constant pointer to the PRIORITY_DATA structure containing
* the priority encode arrays.
* priority: the priority number of the source
*
* Outputs: nothing
*
* Returns:
* The source associated with the priority or prio->nsources if the
* priority is out of range.
*
* Notes: None
*
**********************************************************************/
INT_8 priority_get_source(PRIORITY_DATA * const prio,
INT_8 priority)
{
INT_8 source = 0;
if (source < 0 || source >= prio->nsources)
return prio->nsources;
/* sentinel search to match source to priority */
prio->priorities[prio->nsources] = priority;
while (prio->priorities[source] != priority)
source++;
/* restore illegal priority to the last priorities[] element */
prio->priorities[prio->nsources] = prio->nsources;
/* note: if the search failed, source == prio->nsources */
return prio->priorities[source];
}
/**********************************************************************
*
* Function: priority_next_available
*
* Purpose:
* Return the lowest availabe priority number in the range specified.
*
* Processing:
*
* Parameters:
* prio: a constant pointer to the PRIORITY_DATA structure
* containing the priority encode arrays.
* min_prio: the lowest priority number searched
* max_prio: the highest priority number searched
* hp: a pointer to the default handler
*
* Outputs: nothing
*
* Returns:
* The prioriy number or prio->nsources if no priorities are avialble
*
* Notes: None
*
**********************************************************************/
INT_8 priority_next_available(PRIORITY_DATA * const prio,
INT_8 min_prio,
INT_8 max_prio,
void (*hp)(void))
{
INT_8 next_prio;
for (next_prio = min_prio; next_prio <= max_prio; next_prio++)
{
if (prio->handlers[next_prio] == hp)
return next_prio;
}
return prio->nsources;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -