This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How use 8KB cache on CC2650 ?

Other Parts Discussed in Thread: CC2650, BLE-STACK

I use per-test project , then RAM free size is 8K~9KB.

But I need 15KB RAM size  .

I want to use CC2650 cache RAM.

Would you please tell me how to modify linked files??

Thank you.

  • Hi Abel,

    We don't provide any standalone examples of using the 8kB Flash Cache as system RAM since doing so deviates from the published Power & Performance KPIs. However, there is some SNV example code that does as such that can be used as a reference. Kindly refer to nvocop.c located in <SDK>\Components\services\nv\cc26xx. Start at the NV_compactNV() fxn. Additional details can be found in the TRM (SWCU117), Chapter 8 "Versatile Instruction Memory System (VIMS)".

    Best wishes
  • Hi JXS:
    I must be process sensor data, NV memory must be usually read/write . Flash can't always read/write , Right?
    And Flash size is almost full in my project.
    So I can't use this suggestion.

    Thank you very much.

  • Maybe you can consider to add an extra SPI serial flash for your application.
  • Abel,

    We do not recommend or support re-configuring the cache as RAM since code execution speed will be drastically reduced and current consumption will be much higher.

    I would suggest removing the menu driver and LCD driver from your application. This will reduce the RAM usage by several kB. You can also reduce the CSTACK size (2kB by default) in the linker file and reduce the task stack sizes. See the "BLE developers software guide" for information on using the TI RTOS plugin do watch the stack sizes.

    Attached is a script that will visualize the IAR map file and show flash and RAM usage for you which is really helpful when optimizing your application.

    Regards,

    Svend

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
    
    body {
      font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
      margin: auto;
      position: relative;
      width: 1200px;
    }
    
    /*form {
      position: absolute;
      right: 10px;
      top: 10px;
    }*/
    
    .node {
      border: solid 1px white;
      font: 11px sans-serif;
      line-height: 12px;
      overflow: hidden;
      position: absolute;
      text-indent: 2px;
    }
    
    .chart {
      display: block;
      margin: auto;
      margin-top: 0px;
    }
    
    text {
      font-size: 10px;
    }
    
    rect {
      fill: none;
    }
    
    .axis path,
    .axis line {
      fill: none;
      stroke: #000;
      shape-rendering: crispEdges;
    }
    
    .dot {
      stroke: #000;
    }
    
    #drop_zone {
      border: 2px dashed #bbb;
      -moz-border-radius: 5px;
      -webkit-border-radius: 5px;
      border-radius: 5px;
      padding: 25px;
      text-align: center;
      font: 20pt bold 'Vollkorn';
      color: #bbb;
    }
    
    .report { display: table; }
    .reportRow { display: table-row; }
    .reportCell { display: table-cell; }
    
    .reportRow:hover{
       background-color:#bababa;
    }
    
    .d3-tip {
      line-height: 110%;
      font-weight: bold;
      font-size: x-small;
      padding: 12px;
      background: rgba(0, 0, 0, 0.8);
      color: #fff;
      border-radius: 2px;
    }
    
    /* Creates a small triangle extender for the tooltip */
    .d3-tip:after {
      box-sizing: border-box;
      display: inline;
      font-size: 10px;
      width: 100%;
      line-height: 1;
      color: rgba(0, 0, 0, 0.8);
      content: "\25BC";
      position: absolute;
      text-align: center;
    }
    
    /* Style northward tooltips differently */
    .d3-tip.n:after {
      margin: -1px 0 0 0;
      top: 100%;
      left: 0;
    
    }
    </style>
    
    <div style="color: #999; margin-top: 10px;">Instructions for use (version 0.5):
    <li>Drop a .map file onto the drop-zone to analyze. Refresh page to do another file.</li>
    <li>Mouse-over will show details</li>
    <li>Click on scatter-plot will zoom in on RAM+Flash treemap</li>
    <li>Click on treemap-node will zoom in on module. Click again or outside to zoom out.</li>
    <li>Tested with EWARM 7.30.3/4</li>
    </div>
    
    <div id="drop_zone" style="width: 400px; margin-top: 20px;}">Drop .map-file here</div>
    <output id="list" style='{visibility: hidden;}'></output>
    
    
    <script>
    var modules = {"name": "Total", "children": []};
    var modulesRam = {"name": "Total", "children": []};
    var modulesFlash = {"name": "Total", "children": []};
    var modulesRom = {"name": "Total", "children": []};
    var modulesSpecial = {"name": "Total", "children": []};
    function displayContents(contents) {
    
      // For-now abandoned project of allowing a 2nd dropped file.
      modules = {"name": "Total", "children": []};
      modulesRam = {"name": "Total", "children": []};
      modulesFlash = {"name": "Total", "children": []};
      modulesRom = {"name": "Total", "children": []};
      modulesSpecial = {"name": "Total", "children": []};
      
      lines = contents.split('\n');
    
      var i = 0, l;
      var searchFor = '*** ENTRY LIST';
      var searchState = 0;
      for (i; l = lines[i]; i++) {
        //lines[i] = i + l
        if (searchState == 0 && l.indexOf(searchFor) >= 0)
          { searchState = 1; searchFor = '-----' }
        if (searchState == 1 && l.indexOf(searchFor) >= 0)
          { break; }
      }
      
      i += 1;
    
      var output = ''
    
      var ret = [];
    
    
      // i contains starting point for entry list.
      // Continuation line holder
      var cl = ''
      // Process each line
      for (i; l = lines[i]; i++) {
        // Terminate on empty-ish line
        if (l.length < 4) { break; }
    
        l = cl + l
        cl = ''
    
        items = l.match(/([.a-zA-Z\{\}\/\$0-9_-]((?=\s[^\s\[])\s)?)+/g)
        if (items.length < 2)
        {
          cl = l;
          continue;
        }
    
        if (items.length < 7)
        {
          items.splice(2, 0, "0x0");
        }
    
        // If it's one of the weird linker-created entries which are spread across entries.
        var weirdType = ''
    
        if (items[0].indexOf('$$') > -1 ) {
          items[0] = items[0].split('$$')
          weirdType =items[0][items[0].length-1]; // Base, Length, Limit
          items[0] = items[0].slice(0, -1).join('$$') // Remove qualifier
        }
    
        if (weirdType == 'Length') { continue; } // Ignore linker-created length entry.
    
        var entry = {"name": items[0], 
                     "address": items[1],
                     "size": parseInt(items[2]),
                     "type": items[3],
                     "gblc": items[4],
                     "object": items[5],
                     "objref": items[6],
                   };
    
        // Find memory type from address space
        if (entry.address.indexOf('0x2')>=0) {entry.memory = 'RAM';}
        else if (entry.address.indexOf('0x1')>=0) {entry.memory = 'ROM';}
        else if (entry.address.indexOf('0x0')>=0) {entry.memory = 'Flash';}
        else {entry.memory = 'Special';}
    
        // Save it in a global thing, why not.
        ret.push(entry);
    
        // Pre-filter by Flash and RAM here to save on run-time. Also this is easier, if more imperative in style.
        if (entry.memory == 'Flash') modules = modulesFlash;
        else if (entry.memory == 'RAM') modules = modulesRam;
        else if (entry.memory == 'ROM') modules = modulesRom;
        else modules = modulesSpecial;
    
        // Stupid way to bin the entries based on object-file. Check if bin exists.
        var moduleEntries = modules.children.filter(function( obj ) { 
          return obj.name == entry.object;
        });
    
        // If not, length of filtered array is > 0.
        if ( moduleEntries.length > 0 )
        {
          // For the weird entries like CSTACK we check if the item alerady exists
          var existingEntry = moduleEntries[0].children.filter( function(o) { return o.name == entry.name });
          if (existingEntry.length)
          {
            // Since all other entries are unique, parse the linker-created entries into one.
            // The first one is always base. So if this is Limit, calculate size of existing.
            if (weirdType == 'Limit') { existingEntry[0].size = parseInt(entry.address)-parseInt(existingEntry[0].address)};
          }
          else
          {
            moduleEntries[0].children.push(entry);
          }
        }
        else
        {
          // Add a parent item. This is e.g. main.o.
          modules.children.push( {"name": entry.object, "size":0, "children":[entry]} );
        }
      }
    
      if (items)
      {
       //output += items.join('| ::: |') + '\n';
       //output = JSON.stringify(modulesRam);
      }
    
      treeFile(modulesFlash, 'Flash');
      treeFile(modulesRam, 'RAM');
      
    
    
      var output = '<div class="report">'+ recurseSizeReport(modulesRam, 0) + '</div>';
      ramReport = document.getElementById("RamReport");
      ramReport.innerHTML = output;
    
      var output = '<div class="report">'+ recurseSizeReport(modulesFlash, 0) + '</div>';
      flashReport = document.getElementById("FlashReport");
      flashReport.innerHTML = output;
    
    
      // Scatter
      var hierarchy = d3.layout.hierarchy()
        .value(function(d) { return d.size; });
    
      var nodesRam = hierarchy(modulesRam) //Side-effects modulesRam as well
                    .filter(function(d) { return d.depth==1; })// Get only modules, not total or entries.
                    .map(function(d) { return {"name": d.name, "ramSize": d.value, "ramCount": d.children.length, "ramNode": d} });
      
      var nodesFlash = hierarchy(modulesFlash)
                       .filter(function(d) { return d.depth==1; })
                       .map(function(d) { return {"name": d.name, "flashSize": d.value, "flashCount": d.children.length, "flashNode": d} });
    
      // Merge ram and flash trees on d.name. O(m*n) but at least it's a one-liner.
      nodesRam.forEach(function(e,i,a){inFlash = nodesFlash.filter(function(d){return d.name == e.name}); if (inFlash.length) {inFlash[0].ramCount = e.ramCount; inFlash[0].ramSize = e.ramSize; inFlash[0].ramNode = e.ramNode;} else {nodesFlash.push(e)}})
    
      nodesCombined = nodesFlash;  
      
      // Fill in blanks for cleaner code later. Map without mapping. Could've used .forEach.
      nodesCombined.map(function(d) 
        {
          if (!d.ramCount) {d.ramCount=0;}
          if (!d.ramSize) {d.ramSize=0;}
          if (!d.flashSize) {d.flashSize=0;}
          if (!d.flashCount) {d.flashCount=0;}
          if (!d.flashNode) {d.flashNode=null;}
          if (!d.ramNode) {d.ramNode=null;}
          return d;
        })
    
      scatter(nodesCombined);
    
    
      return ret;
    }
    
    function recurseSizeReport(o, s)
    {
      var ret = '<div class="reportRow">'
      ret += '<div class="reportCell" style="font-size: '+ (14-2*s) +'pt; padding-left: '+ (10*s) +'px;">'
      if (o.name) ret += o.name + "";
      ret += '</div>'
      ret += '<div class="reportCell" style="font-size: '+ (14-2*s) +'pt;">'
      if (o.value) ret += o.value;
      ret += '</div>'
      ret += '</div>'
    
      if (o.children && o.children.length)
        for (var i = 0, c; c = o.children[i]; i++)
          ret += recurseSizeReport(c, s+1);
      
      return ret;
    }
    </script>
    
    
    <script>
      function handleFileSelect(evt) {
        evt.stopPropagation();
        evt.preventDefault();
    
        var files = evt.dataTransfer.files; // FileList object.
    
        // files is a FileList of File objects. List some properties.
        var output = [];
        for (var i = 0, f; f = files[i]; i++) {
          output.push('<strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
                      f.size, ' bytes, last modified: ',
                      f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
                      '');
    
          // Read each file
          var reader = new FileReader();
          reader.onload = function(e) {
            var contents = e.target.result;
            displayContents(contents);
    
            dropZone.remove();
            document.getElementById('list').style.visibility='visible';
          };
          reader.readAsText(f);
        }
        document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
      }
    
      function handleDragOver(evt) {
        evt.stopPropagation();
        evt.preventDefault();
        evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
      }
    
      // Setup the dnd listeners.
      var dropZone = document.getElementById('drop_zone');
      dropZone.addEventListener('dragover', handleDragOver, false);
      dropZone.addEventListener('drop', handleFileSelect, false);
    </script>
    
    <!--textarea id="rawfile" style='{visibility: hidden;}'>
      Hello!
    </textarea-->
    
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
      <body>
      
        <div id="body">
          <!--div id="footer">
            d3.layout.treemap
            <div class="hint">click or option-click to descend or ascend</div>
            <div><select>
              <option value="size">Size</option>
              <option value="count">Count</option>
            </select></div>
          </div>
        </div-->
        
        <div id="svgScatterTitle" style="display: block; margin-top: 20px; font: 2em sans-serif;">Ram vs Flash vs # elements in object (radius)</div>
        <div id="svgScatter"></div>
    
        <div id="svgRamTitle" style="display: block; margin-top: 20px; font: 2em sans-serif;">RAM</div>
        <div id="svgRam" class="chart"></div>
        <div id="selected_tooltip" class="selected_tooltip"></div>
        
        <div id="svgFlashTitle" style="display: block; margin-top: 20px; font: 2em sans-serif;">Flash</div>
        <div id="svgFlash"></div>
        <div id="selected_tooltipFlash" class="selected_tooltip"></div>
    
        <div style="display: block; margin-top: 20px; font: 2em sans-serif;">Report</div>
        <div style="display: table"></div>
          <div style="display: table-cell">
            <div style="display: block; margin-top: 10px; font: 1.5em sans-serif;">Ram</div>
            <div id="RamReport" style="display: block; margin-top: 5px; font: 1em sans-serif;">RamReport</div>
          </div>      
    
          <div style="display: table-cell; padding-left: 20px;">
            <div style="display: block; margin-top: 10px; font: 1.5em sans-serif;">Flash</div>
            <div id="FlashReport" style="display: block; margin-top: 5px; font: 1em sans-serif;">FlashReport</div>
          </div>      
    
        </div>
        <script type="text/javascript">
    var selected_tooltip = document.getElementsByClassName("selected_tooltip");
    
    var w = 1280 - 80,
        h = 800 - 180,
        x = d3.scale.linear().range([0, w]),
        y = d3.scale.linear().range([0, h]),
        color = d3.scale.category20c(),
        root,
        node;
    
    var treemapRam = d3.layout.treemap()
        .round(false)
        .size([w, h])
        .sticky(true)
        .value(function(d) { return d.size; });
    
    var tipMap = d3.tip()
      .attr('class', 'd3-tip')
      .offset(function(d) {return [-(25), -document.body.getBoundingClientRect().left]; })
      .html(function(d) {
        return "<span style='color:lightskyblue; font-size:larger; font-weight: bold;'>" +
                d.parent.name + " :: " + d.name + "</span>" +
                "<br>" + d.memory + ": " + d.size + " bytes";
      })
    
    var svgRam = d3.select("#svgRam") //d3.select("#body").append("div")
        .attr("class", "chart")
        .style("width", w + "px")
        .style("height", h + "px")
      .append("svg:svg")
        .attr("width", w)
        .attr("height", h)
      .append("svg:g")
        .attr("transform", "translate(.5,.5)");
    
    svgRam.call(tipMap);
    
    var treemapFlash = d3.layout.treemap()
        .round(false)
        .size([w, h])
        .sticky(true)
        .value(function(d) { return d.size; });
    
    var svgFlash = d3.select("#svgFlash") //d3.select("#body").append("div")
        .attr("class", "chart")
        .style("width", w + "px")
        .style("height", h + "px")
      .append("svg:svg")
        .attr("width", w)
        .attr("height", h)
      .append("svg:g")
        .attr("transform", "translate(.5,.5)");
    
    svgFlash.call(tipMap);
    
    var margin = {top: 20, right: 20, bottom: 30, left: 40},
        width = 960 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;
    
    var xS = d3.scale.linear()
        .range([0, width]);
    
    var yS = d3.scale.linear()
        .range([height, 0]);
    
    var rS = d3.scale.linear()
        .range([3.5, 20]);
    
    
    var colorS = d3.scale.category20c();
    
    var xAxis = d3.svg.axis()
        .scale(xS)
        .orient("bottom");
    
    var yAxis = d3.svg.axis()
        .scale(yS)
        .orient("left");
    
    var tipScatter = d3.tip()
      .attr('class', 'd3-tip')
      .offset(function(d) {return [-(25), -document.body.getBoundingClientRect().left]; })
      .html(function(d) {
        return "<span style='color:lightskyblue; font-size:larger; font-weight: bold;'>" + d.name + "</span>"+
                "<br>Flash: "+d.flashSize+" bytes / "+d.flashCount+" entries." +
                "<br>Ram: "+d.ramSize+" bytes / "+d.ramCount+" entries.";
      })
    
    
    
    var svgScatter = d3.select("#svgScatter").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
    svgScatter.call(tipScatter);
    
    function scatter(data) {
      // data.forEach(function(d) {
      //   d.sepalLength = +d.sepalLength;
      //   d.sepalWidth = +d.sepalWidth;
      // });
      
      svg = svgScatter;
    
    
      xS.domain(d3.extent(data, function(d) { return d.ramSize; })).nice();
      yS.domain(d3.extent(data, function(d) { return d.flashSize; })).nice();
      rS.domain(d3.extent(data, function(d) { return d.flashCount + d.ramCount; })).nice();
    
      svg.append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis)
        .append("text")
          .attr("class", "label")
          .attr("x", width)
          .attr("y", -6)
          .style("text-anchor", "end")
          .text("Ram usage (b)");
    
      svg.append("g")
          .attr("class", "y axis")
          .call(yAxis)
        .append("text")
          .attr("class", "label")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", ".71em")
          .style("text-anchor", "end")
          .text("Flash usage (b)")
    
      svg.selectAll(".dot")
          .data(data)
        .enter().append("circle")
          .attr("class", "dot")
          .attr("r", function(d) {return rS(d.ramCount + d.flashCount); })
          .attr("cx", function(d) { return xS(d.ramSize); })
          .attr("cy", function(d) { return yS(d.flashSize); })
          .style("fill", function(d) { return color(d.name); })
          .on('click', function(d) { if (d.ramNode) {zoom(d.ramNode)}; if (d.flashNode){zoom(d.flashNode)}; })
          .on('mouseover', tipScatter.show)
          .on('mouseout', tipScatter.hide);
    
      svg.selectAll(".dot").append("title")
          .text(function(d) { return d.name; });
    
      // var legend = svg.selectAll(".legend")
      //     .data(color.domain())
      //   .enter().append("g")
      //     .attr("class", "legend")
      //     .attr("transform", function(d, i) { return "translate(0," + i * 16 + ")"; });
    
      // legend.append("rect")
      //     .attr("x", width - 18)
      //     .attr("width", 14)
      //     .attr("height", 14)
      //     .style("fill", color);
    
      // legend.append("text")
      //     .attr("x", width - 24)
      //     .attr("y", 7)
      //     .attr("dy", ".35em")
      //     .style("text-anchor", "end")
      //     .text(function(d) { return d; });
    
    };
    
    var nodesFlash;
    var nodesRam;
    
    function treeFile(data, memory)
    {
      node = root = data;
    
      if (memory == 'RAM')
      {
        treemap = treemapRam;
        svg = svgRam;
        nodesRam = treemap.nodes(root)
          .filter(function(d) { return !d.children; });
        nodes = nodesRam;
      }
      else if (memory == 'Flash')
      {
        treemap = treemapFlash;
        svg = svgFlash;
        nodesFlash = treemap.nodes(root)
          .filter(function(d) { return !d.children; });
        nodes = nodesFlash;
      }
    
      var cell = svg.selectAll("g")
          .data(nodes)
        .enter().append("svg:g")
          .attr("class", "cell")
          .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
          .on("click", function(d) {if (d.memory=='RAM'){root=modulesRam} else {root=modulesFlash}; return zoom(node == d.parent ? root : d.parent); });
    
      cell.append("title")
          .text(function(d) { return d.name + ':  ' + ((d.size)?(d.size + ' bytes'):0); });
    
      cell.append("svg:rect")
          .attr("width", function(d) { return (d.dx - 1)<0?0:(d.dx - 1); })
          .attr("height", function(d) { return (d.dy - 1)<0?0:(d.dy - 1); })
          .style("fill", function(d) { return color(d.parent.name); })
          .on('mouseover', function(d) { 
              selected_tooltip[0].innerHTML = d.parent.name + "("+d.parent.value+") :: "+d.name+"("+d.value+")";
              selected_tooltip[1].innerHTML = d.parent.name + "("+d.parent.value+") :: "+d.name+"("+d.value+")";
              tipMap.show(d);
            })
            .on('mouseout', tipMap.hide);
    
    
      cell.append("svg:text")
          .attr("x", function(d) { return d.dx / 2; })
          .attr("y", function(d) { return d.dy / 2; })
          .attr("dy", ".25em")
          .attr("text-anchor", "middle")
          .text(function(d) { return d.name; })
          .style("visibility", "hidden"); /*function(d) { d.w = this.getComputedTextLength(); return d.dx > d.w ? 'visible' : 'hidden'; });*/
    
      d3.select(window).on("click", function() { zoom(modulesFlash); zoom(modulesRam); });
    
      d3.select("select").on("change", function() {
        treemap.value(this.value == "size" ? size : count).nodes(root);
        zoom(node);
      });
    };
    
    function size(d) {
      return d.size;
    }
    
    function count(d) {
      return 1;
    }
    
    function recurseAny(o, att, val)
    {
      if (o.hasOwnProperty(att) && o[att] == val) return true;
      else if (o.children && o.children.length)
        for (var i = 0, c; c = o.children[i]; i++)
          if (recurseAny(c, att, val)) return true;
      return false;
    }
    
    function zoom(d) {
      var kx = w / d.dx, ky = h / d.dy;
      x.domain([d.x, d.x + d.dx]);
      y.domain([d.y, d.y + d.dy]);
    
      //debugger;
    
      if (recurseAny(d, 'memory', 'RAM'))
      {
        treemap = treemapRam;
        svg = svgRam;
      }
      else if (recurseAny(d, 'memory', 'Flash'))
      {
        treemap = treemapFlash;
        svg = svgFlash;
      }
    
      var t = svg.selectAll("g.cell").transition()
          .duration(d3.event.altKey ? 750 : 300)
          .attr("transform", function(d) { return "translate(" + x(d.x) + "," + y(d.y) + ")"; });
    
      t.select("rect")
          .attr("width", function(d) { return (kx * d.dx - 1)>0?(kx * d.dx - 1):0; })
          .attr("height", function(d) { return (ky * d.dy - 1)>0?(ky * d.dy - 1):0; })
    
      t.select("text")
          .attr("x", function(d) { return kx * d.dx / 2; })
          .attr("y", function(d) { return ky * d.dy / 2; })
          .style("visibility", function(d) { return kx * d.dx > d.w ? 'visible' : 'hidden'; });
    
      node = d;
      d3.event.stopPropagation();
    }
    
        </script>
    
      </body>

  • Dear Svend:

    Thank you , but I see RAM 10~12KB in TI-RTOS.
    So I need non-OS sample project in CC2650.

    or other solution.

    1. use NV memory in Flash. (x)

    2. use SPI RAM                        (OK, but solution is costly and slowly)

    3. use cache memory to RAM (no way to do)

  • With the suggestions you got above you should be able to modify the program to have your required 15kB RAM available.
    Instead of starting out with a final example program with a lot of things that might be unecessary for you I would suggest building up your program with only the modules you need. A very small TI RTOS project can use as little as 3kB RAM.

    Regards,
    Svend
  • Dear Svend:

    Do you know how to remove the unnecessary RAM or modules in TI-RTOS ?

  • Hi Abel,

    You can remove drivers (if needed) as well as remove unnecessary services, such as the Simple Profile. In addition, profiling your heap & task stack usage is recommended. Refer to the SW Developer's Guide (SWRU393).

    Best wishes
  • Svendbt, Is there any more detaied information available on how the VIMS uses the cache between flash and the cpu? I'm curious how slow instruction of data fetch from flash is compared to average use with the cache, etc. Thanks.

  • Hi Mark,

    Sorry for the late response, I have been out for a while. When executing from flash there are 3 wait cycles for each instruction fetch compared to 1 when you have a cache hit so the performance impact is significant.

    Regards,
    Svend
  • ok.. i dont know if you already done this, but, i will tell you my trick to use 8kb VIMS CACHE as pure RAM:

    First:
    in your main.c file add the header:
    #include "driverlib/vims.h"

    and 
    #define CACHE_RAM_BASE          0x11000000  //address of VIMS GP-RAM

    then add:


    VIMSModeSet(VIMS_BASE, VIMS_MODE_DISABLED);

    before

    /* Start BIOS */
    BIOS_start();

    This will disable VIMS cache and will free you to read/write at the CACHE_RAM_BASE.

    To use, include a pointer like uint8_t *ptr = CACHE_RAM_BASE;

    And write/read your data from this pointer. after 4 hours looking for this specific information, it works here.

    I was needing 16kb (8kb+8kb) of RAM to log data and i use this addr to hold the half of the data for me. 

    Hope that this code will help you!

    PS: im not interested in low power now, so i use:

    Power_setConstraint(Power_SB_DISALLOW);
    Power_setConstraint(Power_IDLE_PD_DISALLOW);

    before the VIMSModeSet(); to let SensorController stay awake too.

  • Could you elaborate on how you write to the CACHE_RAM_BASE again?
  • Nick,

    There is a functional example in nvocop.c in the BLE-Stack SDK for using the cache as RAM.

    Best wishes
  • Hello,

    I'm interested in memory access times. When you say that there is 1 wait cycle for cache hits and 3 wait cycles for FLASH accesses; Is that read and write? Is a wait cycle a XOSC 48MHz high freequency CPU clock cycle or is it something longer?

    Thank you,

    Ken

    PS Is there a way to force something to stick in the cache so that it always hits. 

  • Kenneth,

    The cache RAM has no wait states, while the Flash has 3 (on SCLK_HF / 48 MHz). Memory/peripheral writes are buffered, so (nonblocking) write delay depends on the number of writes in the CPU pipeline and is thus not deterministic.

    There is unfortunately no supported way of ensuring that a certain piece of code/data is always cached.

    Regards,
    Svend