C Version of system_rtc_mem_read

Here are C versions of system_rtc_mem_write & system_rtc_mem_write. You don’t need these when your app is compiled against the SDK but if you are running bare-metal code you might find them handy. You could add this code to rBoot so you can communicate with it between boots, e.g. setting a flag from your app to alter the behaviour of rBoot on next boot.

Note: in the SDK version if you specify a length that is not a multiple of 4 the actual length read will be rounded up and so it may overflow the supplied buffer (although alignment/packing of memory may mean this isn’t a problem), my version requires a read in multiples of 4 bytes, but you can easily remove that check if you wish.

uint32 system_rtc_mem_read(int32 addr, void *buff, int32 length) {

	int32 blocks;
	
	// validate reading a user block
	//if (addr < 64) return 0;
	if (buff == 0) return 0;
	// validate 4 byte aligned
	if (((uint32)buff & 0x3) != 0) return 0;
	// validate length is multiple of 4
	if ((length & 0x3) != 0) return 0;
	
	// check valid length from specified starting point
	if (length > (0x300 - (addr * 4))) return 0;

	// copy the data
	for (blocks = (length >> 2) - 1; blocks >= 0; blocks--) {
		volatile uint32 *ram = ((uint32*)buff) + blocks;
		volatile uint32 *rtc = ((uint32*)0x60001100) + addr + blocks;
		*ram = *rtc;
	}

	return 1;
}

You’ll notice how similar these two functions are, if you need both you could easily combine them into a single function with a parameter to indicate read/write mode (which would save rom space).

uint32 system_rtc_mem_write(int32 addr, void *buff, int32 length) {

	int32 blocks;
	
	// validate reading a user block
	if (addr < 64) return 0;
	if (buff == 0) return 0;
	// validate 4 byte aligned
	if (((uint32)buff & 0x3) != 0) return 0;
	// validate length is multiple of 4
	if ((length & 0x3) != 0) return 0;
	
	// check valid length from specified starting point
	if (length > (0x300 - (addr * 4))) return 0;

	// copy the data
	for (blocks = (length >> 2) - 1; blocks >= 0; blocks--) {
		volatile uint32 *ram = ((uint32*)buff) + blocks;
		volatile uint32 *rtc = ((uint32*)0x60001100) + addr + blocks;
		*rtc = *ram;
	}

	return 1;
}

2 comments

  1. Untested because I don’t have one of these, but this ought to work and shave off a couple of bytes:

    uint32 system_rtc_mem_write(int32 addr, void *buff, int32 length) {
    register int32 blocks = (length >> 2);
    volatile uint32 *ram = ((uint32*)buff);
    volatile uint32 *rtc = ((uint32*)0x60001100) + addr;
    
    // validate reading a user block, 4 byte aligned, & valid length is multiple of 4
    if ((addr (0x300 – (addr * 4)))) return 0;
    
    // copy the data
    while (blocks– > 0) *rtc++ = *ram++;
    
    return 1;
    }
    
    1. Looks like the code was mangled by HTML because of< characters. Trying again… (if it still looks bad, I won’t post it a third time!)

      uint32 system_rtc_mem_write(int32 addr, void *buff, int32 length) {
       register int32 blocks = (length >> 2);
       volatile uint32 *ram = ((uint32*)buff);
       volatile uint32 *rtc = ((uint32*)0x60001100) + addr;
      
       // validate reading a user block, 4 byte aligned, & valid length is multiple of 4
       if ((addr < 64) |
        (buff == 0) |
        (((((uint32)buff)|length) & 0x3)) |
        (length > (0x300 – (addr * 4)))) return 0;
      
       // copy the data
        while (blocks–- > 0) *rtc++ = *ram++;
      
        return 1;
      }

Leave a comment