This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to designate one ram block exclusively for radio use?

Hi Devzone:

Is there a way to designate one ram block exclusively for radio use? The reason I'd like to know is the following:

Under nRF52833 AHB multilayer section, there is one statement:

"Some peripherals, such as RADIO, do not have a safe stalling mechanism (no internal data buffering, or opportunity to pause incoming data). Being a low priority bus master might cause loss of data for such peripherals upon bus contention. To avoid AHB bus contention when using multiple bus masters, follow these guidelines:

  • Avoid situations where more than one bus master is accessing the same slave.
  • If more than one bus master is accessing the same slave, make sure that the bus bandwidth is not exhausted."

So is there a way to designate one ram block exclusively for radio use to avoid such bus contention? Right now the pointer to radio data is arbitrarily assigned by the compiler.

Is there an example project that does that?

Thanks.

  • Hi

    It is possible to create a dedicated RAM section that covers one of the RAM blocks, so that you can control exactly which variables go into that block of the RAM. 

    Then if you only put the radio buffers into this section you are guaranteed that there won't be any conflict on the DMA slave.

    Please look here for an overview of the RAM blocks in the nRF52833. 

    It shouldn't really be necessary for the radio, since it doesn't access the bus very often (the radio is a relatively low bandwidth peripheral), but I can try to find an example if you are interested. 

    Which compiler/IDE are you using?

    Best regards
    Torbjørn

  • Hi Mr. ovrebekk, 

    we are using segger. We are troubleshooting a radio reception problem so we want to segregate the RAM for radio even, as you have said, it's probably not necessary.

    Some code example would be highly appreciated.

  • Hi 

    First off you have to create a segment in your flash_placement.xml file, such as this:

    <ProgramSection alignment="4" keep="Yes" load="No" name=".radio_RAM_section" start="0x20006000" size="0x2000" />

    This has to be kept somewhere within the MemorySegment named RAM, starting with this line:

    <MemorySegment name="RAM" start="$(RAM_PH_START)" size="$(RAM_PH_SIZE)">

    Then you can put variables into this section by using the __attribute__ keyword, like this:

    uint8_t test_buffer[256] __attribute__((section(".radio_RAM_section")));

    You will find the flash_placement.xml file I used myself to test this attached, based on one of the ESB examples in the SDK:

    <!DOCTYPE Linker_Placement_File>
    <Root name="Flash Section Placement">
      <MemorySegment name="FLASH" start="$(FLASH_PH_START)" size="$(FLASH_PH_SIZE)">
        <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START)" />
        <ProgramSection alignment="4" load="Yes" name=".init" />
        <ProgramSection alignment="4" load="Yes" name=".init_rodata" />
        <ProgramSection alignment="4" load="Yes" name=".text" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_const_data" inputsections="*(SORT(.log_const_data*))" address_symbol="__start_log_const_data" end_symbol="__stop_log_const_data" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_backends" inputsections="*(SORT(.log_backends*))" address_symbol="__start_log_backends" end_symbol="__stop_log_backends" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".nrf_balloc" inputsections="*(.nrf_balloc*)" address_symbol="__start_nrf_balloc" end_symbol="__stop_nrf_balloc" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections" address_symbol="__start_nrf_sections" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_dynamic_data"  inputsections="*(SORT(.log_dynamic_data*))" runin=".log_dynamic_data_run"/>
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_filter_data"  inputsections="*(SORT(.log_filter_data*))" runin=".log_filter_data_run"/>
        <ProgramSection alignment="4" load="Yes" name=".dtors" />
        <ProgramSection alignment="4" load="Yes" name=".ctors" />
        <ProgramSection alignment="4" load="Yes" name=".rodata" />
        <ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
        <ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
        <ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
        <ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
      </MemorySegment>
      <MemorySegment name="RAM" start="$(RAM_PH_START)" size="$(RAM_PH_SIZE)">
        <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START)" address_symbol="__app_ram_start__"/>
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run" address_symbol="__start_nrf_sections_run" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".log_dynamic_data_run" address_symbol="__start_log_dynamic_data" end_symbol="__stop_log_dynamic_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".log_filter_data_run" address_symbol="__start_log_filter_data" end_symbol="__stop_log_filter_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run_end" address_symbol="__end_nrf_sections_run" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".radio_RAM_section" start="0x20006000" size="0x2000" />
        <ProgramSection alignment="4" load="No" name=".fast_run" />
        <ProgramSection alignment="4" load="No" name=".data_run" />
        <ProgramSection alignment="4" load="No" name=".tdata_run" />
        <ProgramSection alignment="4" load="No" name=".bss" />
        <ProgramSection alignment="4" load="No" name=".tbss" />
        <ProgramSection alignment="4" load="No" name=".non_init" />
        <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
        <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack"  address_symbol="__StackLimit" end_symbol="__StackTop"/>
        <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
      </MemorySegment>
    </Root>
    

    Best regards
    Torbjørn

Related