Disabling system clock to use external clock driver card
Gedare Bloom
gedare at rtems.org
Fri Mar 4 20:56:17 UTC 2016
On Fri, Mar 4, 2016 at 9:46 AM, Michael Westfall <mwestfal at gemini.edu> wrote:
> Hello,
>
> We have a vxWorks driver for a VME IRIG-B time provider card (Bancomm
> bc635/bc637) which we want to port to RTEMS.
>
> The ISR of the current vxWorks driver disables the system clock via
> sysClkDisable() in order to take over providing ticks to the kernel via
> tickAnnounce().
>
> rtems_clock_tick() seems to be a direct replacement for the tickAnnounce()
> function, but what is the strategy for disabling/reenabling the system
> clock?
>
> Surely someone else has implemented something similar.
>
You should be able to provide a custom clock source for the clock
driver at the BSP level. Most (all?) BSPs use the framework in
c/src/lib/libbsp/shared/clockdrv_shell.h to drive the system clock
ticks by implementing the necessary "hook" functions. You can
replace/modify the BSP's ckinit.c to use the bc635 card instead. See
for example c/src/lib/libbsp/i386/pc386/clock/ckinit.c for how the x86
currently has two options for the clock timer.
This would relieve you from having to track quite so much "state".
However, I suppose if you wanted to just port your code below, you
would replace the Clock_isr with this code, and undo the
Clock_driver_support_initialize_hardware() that your BSP has done.
>
> Here is our vxWorks ISR:
>
> void isr_bc635
> (
> void *parg
> )
> {
> register short intnum;
> register unsigned short tmask, bcistatus, bcimask;
>
> bcistatus = pbc635->intstat; /* Save copy of status register */
> bcimask = pbc635->mask; /* Save copy of interrupt mask */
> /* First check for periodic interrupt */
> if ( ((bcistatus & 0x02) & bcimask) != 0)
> {
> if (bcUseper) /* Using BC periodics for system clock? */
> {
> if (!HadPerint) /* First Periodic Interrupt? */
> {
> HadPerint = TRUE;
> sysClkDisable(); /* Turn off system clock interrupts */
> sysClkRateSet(tickFrequency); /* set clock rate */
> }
> bcIntCounter++; /* Increment interrupt count */
> if (bcUsrClock != NULL) (*bcUsrClock)(bcIntCounter); /* Call user
> routine */
> if (bcIntCounter%bcIntPerTick == 0) /* If right number of ticks */
> tickAnnounce(); /* Announce system clock tick */
> }
> pbc635->intstat = pbc635->intstat | 0x02; /* Clear interrupt status
> bit */
> }
> /* Other interrupts - not periodic pulse */
> for (intnum = 1; intnum < 5; intnum++)
> {
> if (intnum != 2)
> {
> tmask = 0x01 << (intnum - 1); /* Test value for interrupt */
> /* Check for interrupt bit set - request I/O scan, but only if
> ioscanpvt is valid */
> if ( ((bcistatus & tmask) & bcimask) != 0)
> {
> if (ioscanpvt[intnum-1] != NULL)
> scanIoRequest(ioscanpvt[intnum-1]);
> pbc635->intstat = pbc635->intstat | tmask; /* Clear interrupt
> status bit */
> }
> }
> }
> }
>
>
> --
> Mike Westfall
> Gemini Observatory
>
> _______________________________________________
> users mailing list
> users at rtems.org
> http://lists.rtems.org/mailman/listinfo/users
More information about the users
mailing list