Peripheral devices are usually mapped to fall into a specific region of the memory map and each peripheral is allotted an address space that ranges from a start address to an end address. Consider the memory map shown for a processor on the left where peripherals have an address range from 0xE7B0_0000 to 0xE7BF_0000. This means that the processor has to send out bus transactions with an address that falls within this range to access the peripherals.


Let's say that SPI has 20 internal registers from which we will pick two :

  • Control Register 1 (CTRL1) at location 0x40
  • Status Register (STAT) at location 0x1A
In-order to access the Control register, the processor will have to send out an address (0xE7B0_0000 + 0x0002_0000 + 0x0000_0040) which adds upto 0xE7B2_0040. Similarly, to access status register, the calculated address becomes 0xE7B2_001A. From the design specifications, you would see that not all the addresses within the peripheral space are used, some will be kept reserved for future additions. It is always good to verify that these reserved spaces are actually empty and does not contain any unintentional registers.

By verifying the reserved spaces, you'll know whether

  • your version of the design does not keep any unintentional legacy registers that are not documented.
  • the reserved space does not have any buffer area with different access permissions.

The simplest way to do this is to perform a read-write operation to the reserved spaces, and because these address spaces don't exist, it will result in a processor exception. Capture the exception, call the exception-handler routine and increment a counter. In the main task where you have the code to access the reserved space, keep another counter variable to hold the expected value. After an exception occurs, the exception counter will increment and in your main task, the expected value should also be incremented. Then check the actual vs expected values to know if the exception occurred or not. If it failed, that means the access to the address was successful and its not a reserved space. Then you'll have to pull up your favorite debug tool and find out why you didn't get any error.

int exc_count = 0;

void exc_handler () {
  exc_count ++;

void check_address (uint32_t min_addr, uint32_t max_addr) {
	int exp_counter = 0;
	// Install the exception handler

	for (uint32_t myAddr = min_addr; myAddr < max_addr; myAddr+= 4) {
		exp_counter ++;
		// Perform a write operation to myAddr
		// Check if exception occured, then compare exp_counter with exc_counter
		if (exp_counter == exc_counter) {
			// Pass : Exception occured, was captured by handler and counter incremented
		} else {
			// Fail : Exception did not occur !