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

Further improve of SD-card performance

Hi everybody,

i've got an issue i want to discuss here. I'm building a webserver using the nRF9160DK with ethernet-shield from PHYTEC and an SD-card which holds the frontend with a size of over 3MB. So far i got everything up and running using the nrf-connect-sdk v1.5.1.

With the default configurations, the SPI-Interface to the SD-card is running at a very low frequency (250kHz), which already was discussed in other issues here. In this configuration, serving the frontend takes about 2 minutes. I saw that in the next release of the nrf-connect-sdk, it should be possible to configure the SPI-frequency over the devicetree, which at the time is not working. I even tried to run my project under the master-branch of the nrf-connect-sdk, but then i had various access violations, related to the Ethernet PHY, which i could not resolve. With the releases v1.5.0 and v1.5.1 everything works fine... But i was able to do a patch which improves the SPI-interface to the maximum possible frequency of 8MHz of the nRF9160 under v1.5.1. ImprovedSdCardSpeed.patch

Now it takes about 16 seconds to serve the frontend which is still too long for my needs, possible due to file system overhead (FAT32). I observed that the disk-access-driver uses fixed sector-sizes of 512 Bytes when reading files from the SD-card. I was wondering if i could improve my performance even more, if i would be able to increase these sector-sizes to a higher value. Unfortunately, i wasn't able to do this by myself.

Is there something in planning to make the sector-sizes configurable?

Would the use of another file system have an impact on my performance? Which would be best?

Has somebody any other suggestions how i could improve the performance?

Thanks in advance for any help! Slight smile

Parents
  • Are you able to attach a logic analyzer to the lines to see what's actually going on and what the speed is.

    Best regards,

    Simon

  • Hey Simon, thanks for your reply.

    I hooked up up my scope to measure the SPI-lines. This raised question about SPI-pin configuration. As you can see in the image below, the clock frequency is about 8MHz.

    The datasheet of the nRF9160 states, that the pins need to be configured as "High Drive" at high bit rates (footnote 10). 

      

    Since i'm using the highest possible clock-frequency on the nRF9160, i tried to find out how to configure this option, but i wasn't able to find out how. Can you give me a hint on this one? On the other side the data-line looks well. I think it is possible that this is due to other input-capacitance on this line (SCK --> P0.19 / MISO --> P0.18) of the nRF9160DK Rev. 1.0.0.

    When reading a file in chunks of 1024 bytes, we can see the reading-command followed by two blocks of 512 byte data.

    Each of these blocks contain eight 64-bytes subs.

    Each of these subs contain eight 64-bit bitfields.

    Each bitfiled contains 64-bit data.

    To ensure the reading sequence isn't blocked by network-threads, i tested the reading-command also with the networking and webserver disabled, both the same. From the timing perspective there seems to be quiet some potential to save time.

    Thanks for any help.

  • I'm sorry for the late reply.

    flge said:
    Since i'm using the highest possible clock-frequency on the nRF9160, i tried to find out how to configure this option, but i wasn't able to find out how. Can you give me a hint on this one?

    Check out this answer for how to do this: https://devzone.nordicsemi.com/f/nordic-q-a/64647/spi-not-operating-correctly-at-high-speeds/264121#264121 

    You can use the Nordic nrf functions (#include <hal/nrf_gpio.h>) directly and set it using nrf_gpio_cfg() like in the link above.

    You can also achieve this using the Zephyr layer, just make sure the following gets triggered: https://github.com/nrfconnect/sdk-zephyr/blob/v2.4.99-ncs2/drivers/gpio/gpio_nrfx.c#L155. I think you can do that by running gpio_config() (#include <drivers/gpio.h>) with flags = GPIO_DS_ALT_LOW | GPIO_DS_ALT_HIGH.

    flge said:
    To ensure the reading sequence isn't blocked by network-threads, i tested the reading-command also with the networking and webserver disabled, both the same. From the timing perspective there seems to be quiet some potential to save time.

     Have you gotten any progress on this?

    Maybe a solution would be to increase the priority of the thread responsible for the SPI transfer?

  • Thank you very much for the answer. I will try out your tips and give a feedback when i'm done.

  • Hi Simon,

    the nrf_gpio_cfg() function worked very well. I was able to increase the waveform performance dramatically. I've done this with all the pins controlled by the nRF9160. Following the results of the spi-clk pin for example before and after the configuration.

    About the SD-protocol. I rerun the zephyr sample for SDHC access (fat_fs in subsys) with the same results in my post above. I've included the thread-analyzer to have an overview about the running threads. Afterwards i increased the main-thread priority, where i'm reading a testfile from the SDHC, always with the same result. It seems that in the driver for the SDHC, the data gets readed in batches (sdhc_spi_rx_block()), so this approach goes nowhere. Is there something in planning to improve the SD-driver? Otherwise i have to try this myself.

    Best regards,

Reply
  • Hi Simon,

    the nrf_gpio_cfg() function worked very well. I was able to increase the waveform performance dramatically. I've done this with all the pins controlled by the nRF9160. Following the results of the spi-clk pin for example before and after the configuration.

    About the SD-protocol. I rerun the zephyr sample for SDHC access (fat_fs in subsys) with the same results in my post above. I've included the thread-analyzer to have an overview about the running threads. Afterwards i increased the main-thread priority, where i'm reading a testfile from the SDHC, always with the same result. It seems that in the driver for the SDHC, the data gets readed in batches (sdhc_spi_rx_block()), so this approach goes nowhere. Is there something in planning to improve the SD-driver? Otherwise i have to try this myself.

    Best regards,

Children
Related