element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Raspberry Pi
  • Products
  • More
Raspberry Pi
Blog Add external SPI Flash Memory to Raspberry Pico - 4: STL containers to return byte arrays
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Raspberry Pi to participate - click to join for free!
Featured Articles
Announcing Pi
Technical Specifications
Raspberry Pi FAQs
Win a Pi
GPIO Pinout
Raspberry Pi Wishlist
Comparison Chart
Quiz
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 3 Dec 2022 12:47 PM Date Created
  • Views 1700 views
  • Likes 7 likes
  • Comments 11 comments
Related
Recommended
  • pico
  • pico_m25
  • pico_eurocard

Add external SPI Flash Memory to Raspberry Pico - 4: STL containers to return byte arrays

Jan Cumps
Jan Cumps
3 Dec 2022
Add external SPI Flash Memory to Raspberry Pico - 4: STL containers to return byte arrays

A projects to learn the SPI API of the RP2040 C SDK, and to use it to control an external Flash IC. In this post, I refine the m25 c++ class again. Return byte arrays as Standard Template Library (stl) containersimage

Arrays as return values instead of output parameters

Usually, when a function returns multiple values, we pass it a buffer as one of the parameters, and the function can fill it. There are other options, but this is often how we see it done.

In c++ you can return a container as a return value. You can construct it in the function - right size and value, then hand it over to the calling function. Here's a function that reads 3 bytes from the m25 IC over SPI, then hands over the results an stl vector:

std::vector<uint8_t> m25::rdid() {
    uint8_t buf[3];
    // command
    uint8_t cmdbuf[] = {
            RDID,
    };
    setDataBits(8);
    select();
    spi_write_blocking(spi, cmdbuf, 1);
    spi_read_blocking(spi, 0, buf, 1); // Manufacturer Identification
    spi_read_blocking(spi, 0, buf + sizeof buf[0], 2); // Device Identification (Memory Type || Memory Capacity)
    deselect();
    return std::vector<uint8_t> (buf, buf + (sizeof buf/sizeof buf[0]));
}

The calling program can use it like this:

   // get and print read identifier
    bytes = eeprom->rdid();
    std::cout << "read identifier: ";
    for ( auto bte: bytes ) std::cout << std::hex << static_cast<int>(bte) << " ";
    std::cout << std::endl;

Result:

read identifier: 20 20 15 

VSCode project attached: spi_flash_20221203.zip

link to all posts in this series

  • Sign in to reply

Top Comments

  • Jan Cumps
    Jan Cumps over 2 years ago +1
    For the latest language features, tell the compiler that you want to use standard c++ 20: project(spi_flash C CXX ASM) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 20)
  • Jan Cumps
    Jan Cumps over 2 years ago

    One of the things that bother me in my code, is that it initialises the SPI. In an MBED type of environment (and other OO controller frameworks), you'd link the Flash object to a SPI object. I may refactor this code to do the same.
    I don't want to go wild. My goal is not to build a Pico OO framework as a side effect of this blog. 
    If it gets built, I hope it's MBED :).

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 2 years ago

    I found some time to continue this project. I'll use it to create a flash write and read method.
    The goal is that, for a developer, the code will look like this:

        // test a read and write cycle
        uint32_t address = 0x12345678;         // random address
        bytes = {0x01, 0x02, 0x03, 0x04};      // random data vector
        size_t length = bytes.size();          // data size
        
        eeprom->write(address, bytes);         // write the data
        bytes = eeprom->read(address, length); // read the data back
        
        for ( auto bte: bytes ) std::cout << std::hex << static_cast<int>(bte) << " ";
        std::cout << std::endl;

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 2 years ago

    There's a good Arduino library for this IC: https://github.com/Marzogh/SPIMemory

    It's not restricted to the Flash memory that I'm using here. It supports several SPI Flash & FRAM Memory manufacturers.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 2 years ago

    The price for using STL vectors on the Pico is an almost 600 KB increase in program size, in release build mode. in debug build, it's 600KB. This is significant in a 2MB flash device. 
    I removed any other code line that used a  c++ dependency before measuring, like streaming to cout.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 2 years ago in reply to Jan Cumps

    (typed Arrow double up on a tablet and it shows :) )

    static cast does not cause a performance hit. It's evaluated at compile time and does not generate any code or increase/change variable sizes. 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube