Scrubbing - Scrubbing - 2026.1 English - UG984

MicroBlaze Processor Reference Guide (UG984)

Document ID
UG984
Release Date
2026-06-23
Version
2026.1 English

To ensure that bit errors are not accumulated in block RAMs, they must be periodically scrubbed.

The standalone BSP provides the function microblaze_scrub() to perform scrubbing of the entire LMB block RAM and all MicroBlaze internal block RAMs used in a particular configuration. This function is intended to be called periodically from a timer interrupt routine. One location of each block RAM is scrubbed every time it is called, using persistent data to track the current locations.

The following example code illustrates how this can be done.

#include "xparameters.h"
#include "xtmrctr.h"
#include "xintc.h"
#include "mb_interface.h"

#define SCRUB_PERIOD ...

XIntc InterruptController; /* The Interrupt Controller instance */
XTmrCtr TimerCounterInst;   /* The Timer Counter instance */

void MicroBlazeScrubHandler(void *CallBackRef, u8 TmrCtrNumber)
{
   /* Perform other timer interrupt processing here */
   microblaze_scrub();
}
 
int main (void)
{
   int Status;
   /*
    * Initialize the timer counter so that it's ready to use,
    * specify the device ID that is generated in xparameters.h
    */
   Status = XTmrCtr_Initialize(&TimerCounterInst, TMRCTR_DEVICE_ID);
   if (Status != XST_SUCCESS) {
      return XST_FAILURE;
   }

   /*
    * Connect the timer counter to the interrupt subsystem such that
    * interrupts can occur.
    */
   Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
   if (Status != XST_SUCCESS) {
      return XST_FAILURE;
   }

   /*
    * Connect a device driver handler that will be called when an
    * interrupt for the device occurs, the device driver handler performs
    * the specific interrupt processing for the device
    */
   Status = XIntc_Connect(&InterruptController, TMRCTR_DEVICE_ID,
            (XInterruptHandler)XTmrCtr_InterruptHandler,
            (void *) &TimerCounterInst);
   if (Status != XST_SUCCESS) {
      return XST_FAILURE;
   }

   /*
    * Start the interrupt controller such that interrupts are enabled for
    * all devices that cause interrupts, specifying real mode so that the
    * timer counter can cause interrupts thru the interrupt controller.
    */
   Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
   if (Status != XST_SUCCESS) {
      return XST_FAILURE;
   }

   /*
    * Setup the handler for the timer counter that will be called from the
    * interrupt context when the timer expires, specify a pointer to the
    * timer counter driver instance as the callback reference so the
    * handler is able to access the instance data
    */
   XTmrCtr_SetHandler(&TimerCounterInst, MicroBlazeScrubHandler,
                  &TimerCounterInst);

   /*
    * Enable the interrupt of the timer counter so interrupts will occur
    * and use auto reload mode such that the timer counter will reload
    * itself automatically and continue repeatedly, without this option
    * it would expire once only
    */
   XTmrCtr_SetOptions(&TimerCounterInst, TIMER_CNTR_0,

            XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION);

   /*
    * Set a reset value for the timer counter such that it will expire
    * earlier than letting it roll over from 0, the reset value is loaded
    * into the timer counter when it is started
    */
   XTmrCtr_SetResetValue(TmrCtrInstancePtr,TmrCtrNumber,SCRUB_PERIOD);

   /*
    * Start the timer counter such that it's incrementing by default,
    * then wait for it to timeout a number of times
    */
   XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_0);

   ...
}

See Scrubbing for further details on how scrubbing is implemented, including how to calculate the scrubbing rate.