Forum Rule: Always post complete source code & details to reproduce any issue!
Page 8 of 8 FirstFirst ... 6 7 8
Results 176 to 187 of 187

Thread: Circular_Buffer

  1. #176
    Senior Member
    Join Date
    Jun 2017
    Posts
    114
    Tonton81,

    OK, thanks. Maybe functions that only operate on circular arrays could have a '_array' appended to their name, like 'remove_array'?

    Frank

  2. #177
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,445
    Some features are specific to arrays, some to buffers, most work on both. It wouldn't be ideal to have seaparate names when there are alot of features to be handled would increase the function list, as long as it is, and future support for alternate buffer/array would require deprecating functions in terms of dual buffering support in a single function rather than by two different ones

  3. #178
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    117
    Hello,

    I try to use CB in my project to replace a "running average" but I have trouble to declare the circular buffer. I have several buffer that *may* have several size. The size in know at the init and belong to a structure. So doing this :

    Code:
      for (int i = 0; i < nbTK; i++) {
        Circular_Buffer<float, infoTK[i].echantillonnage> coldJunction_CB[i];
        Circular_Buffer<float, infoTK[i].echantillonnage> compensedTemp_CB[i];
      }
    I guess I have to create CB with a static size (ie : 32) THEN change the size with the relevant value ?

    Thank you.

  4. #179
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,445
    Yes the constructors must be defined at compile time, not during runtime, only the objects should be in your *for loop*

  5. #180
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    117
    Thank you.
    But is there a possibility to change the size "on the fly" ?

  6. #181
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,445
    No, templates are created during compile time, size is set as is.
    Is there a reason you want dynamic size?

    For the for loop you posted, since you want to make it dynamic, you can probably just use a normal array for that. If you plan to hold values to use the circular buffer features it can't be dynamic sized

  7. #182
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    117
    I intend to use circular_buffer as a moving average, and this average is something that the users may change to meet is needs. The number of sample to average the value is stored in EEPROM and is read at startup. This value can be changed using a serial command.
    Not a big problem, I'll use another way to do this ;-)
    Thank you

  8. #183
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,445
    A function could be added if thats the case, but you need to set a max value for the size of the buffer, and a function made to read only the average of the X last values of it. It's a little tedious to make but it is possible.

  9. #184
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    117
    Thank you Tony,
    Don't waste your time with this, I'll use a custom way to do this.

  10. #185
    Senior Member
    Join Date
    Aug 2017
    Posts
    309
    @tonton81 - I have started experimenting with your circular_buffer library. I spent the day learning how to use it with MSC using your FlexCAN_t4 library as a guide for implementing it. There is a lot to learn I have MSC working with EventResponder now thanks to @KutrE. Will probably be asking questions here and there. What I am shooting for is to minimize the blocking effects of MSC and be able to queue up sector reads and writes to be processed in some way in the background queueing multi sector reads and writes only.

    Each read or write transfer is comprised of three stages.

    1) First stage is queuing and sending a CBW (Control Block Wrapper) for a multi sector read or write to a USB drive.

    2) Second stage is queuing and sending a read or write data command to the USB drive.

    3) The last stage is is the status stage. This is where the transfer is complete.

    At first I was triggering the event for every stage of the transfer. But that was completely wrong. Really all I needed was to to trigger an event on completion of the transfer (Status Stage). I want to be able to queue each transfer and return to the test sketch and let the EventResponder dispatch any unsent queued transfers. I am still not sure if this is possible with the EventResponder. My test sketch is only doing sector reads and writes to a USB Mass Storage device. Keeping it low level and with the writes destroying any formatting on the drive

    After some more experimenting with the EventResponder and circular_buffer libraries I hope to submit this version of MSC with just the driver for testing.
    Am I going in the right direction?

    Thanks

  11. #186
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,445
    I havn't played with SD or USB utils so I wouldn't be of much help on that part, but a circular queue you could assign 512 bytes and when it is full via size() you can write that block to the SD or usb I guess. you are limited by the memory obviously and buffers are in powers of 2. You could also manage it with a fixed array in code, if its just appending bytes to an index, but you'll have to manage the indice counter whereas push or popping the queue shifts it in or out, a little less work for you.

  12. #187
    Senior Member
    Join Date
    Aug 2017
    Posts
    309
    Quote Originally Posted by tonton81 View Post
    I havn't played with SD or USB utils so I wouldn't be of much help on that part, but a circular queue you could assign 512 bytes and when it is full via size() you can write that block to the SD or usb I guess. you are limited by the memory obviously and buffers are in powers of 2. You could also manage it with a fixed array in code, if its just appending bytes to an index, but you'll have to manage the indice counter whereas push or popping the queue shifts it in or out, a little less work for you.
    Thanks for the response. I actually have it working with one transfer just to test. I am using this structure for each data read or write.
    Code:
    	typedef struct {
    		uint8_t type = NO_RD_WR; // Used for CMD_RD_10 or CMD_WR_10 only, else 0.
    		bool completed;
    		void *buffer;
    		msCommandBlockWrapper_t *CBW;
    	} MSC_transfer_t;
    In the msReadSector() function:
    Code:
    // ---------------------------------------------------------------------------------------------------------
    // Read Sectors using queued reads
    // ---------------------------------------------------------------------------------------------------------
    uint8_t msController::msReadSectors(void *sectorBuffer, const uint32_t BlockAddress, const uint16_t Blocks) {
    	uint8_t msResult = 0;
    #ifdef DBGprint
    	Serial.printf("msReadSectors()\n");
    #endif
    
    	uint8_t BlockHi = (Blocks >> 8) & 0xFF;
    	uint8_t BlockLo = Blocks & 0xFF;
    	msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t)
    	{
    	
    		.Signature          = CBW_SIGNATURE,
    		.Tag                = ++CBWTag,
    		.TransferLength     = (uint32_t)(Blocks * (uint16_t)512),
    		.Flags              = CMD_DIR_DATA_IN,
    		.LUN                = currentLUN,
    		.CommandLength      = 10,
    		.CommandData        = {CMD_RD_10, 0x00,
    							  (uint8_t)(BlockAddress >> 24),
    							  (uint8_t)(BlockAddress >> 16),
    							  (uint8_t)(BlockAddress >> 8),
    							  (uint8_t)(BlockAddress & 0xFF),
    							   0x00, BlockHi, BlockLo, 0x00}
    	};
    	mscTransfer.CBW = &CommandBlockWrapper;
    	mscTransfer.buffer = sectorBuffer;
    	mscTransfer.type = CMD_RD_10;	
    	uint8_t buf[sizeof(MSC_transfer_t)];
    	memmove(buf, &mscTransfer, sizeof(mscTransfer));
    	cbamsc.push_back(buf, sizeof(MSC_transfer_t));
    cbamsc.list();
    	Serial.printf("cbamsc.size() = %d\n", cbamsc.size());
    	cbamsc.pop_front(buf, sizeof(MSC_transfer_t));
    	memmove(&mscTransfer, buf, sizeof(mscTransfer));
    	Serial.printf("cbamsc.size() = %d\n", cbamsc.size());
    //	msResult = msDispatchTransfer(mscXferEvent);
    	msResult = msDoCommand(mscTransfer.CBW, mscTransfer.buffer);
    //#ifdef DBGprint
    	Serial.printf("transferIndex = %d\n",transferIndex);
    	Serial.printf("mscTransfer.completed = %d\n"
    					,mscTransfer.completed);
    //#endif
    	return msResult;
    }
    I zeroed out the mscTransfer stuct after I performed the push_back() function. I checked all of the elements in the mscTransfer to make sure they were zeroed out and then performed the pop_front() function and sent the struct to msDoCommand(). It read back 131072 bytes at 14Mb/s which was a 65536 byte 8bit buffer with two reads. So I think I am on the right track initially with your circular_buffer library.

    Here is the instance of CB I used:
    Code:
    Circular_Buffer<uint8_t, MAX_TRANSFERS,sizeof(msController::MSC_transfer_t)> cbamsc;
    After testing with just reading from the USB drive (thumb drive) I will create two instances of CB, one for sector reads and one sector write.

    Nice work Tony

    Edit: Output was:
    Code:
    Teensy USB MSD testing
    
    Checking for msDrive1
    msDrive1 init: OK
    
    msDrive1 is NOT Mounted
    
       connected 1
       initialized 1
       USB Vendor ID: 0951
      USB Product ID: 1666
          HUB Number: 0
            HUB Port: 0
      Device Address: 1
    Removable Device: YES
            VendorID: Kingston
           ProductID: DataTraveler 3.0
          RevisionID:     
             Version: 6
        Sector Count: 30218841
         Sector size: 512
       Disk Capacity: 15472046592 Bytes
    
    
    Select:
       1) Test Sector Read Speed Drive 1
       3) Test Sector Write Speed Drive 1 ******** CAUTION!!! DESTROY'S FORMATTING OF DRIVE!! *********
    Reading From USB Drive 1
    
    Circular Array Buffer Queue Size: 1 / 10
    
    First Entry: 40    0    0    0    32    0    0    0    144    255    5    32    (12 entries.)
    Last Entry:  40    0    0    0    32    0    0    0    144    255    5    32    (12 entries.)
    
    [Indice]      [Entries]
    
        0		40	0	0	0	32	0	0	0	144	255	5	32	(12 entries.)
    cbamsc.size() = 1
    cbamsc.size() = 0
    transferIndex = 0
    mscTransfer.completed = 1
    
    Circular Array Buffer Queue Size: 1 / 10
    
    First Entry: 40    1    0    0    32    0    0    0    144    255    5    32    (12 entries.)
    Last Entry:  40    1    0    0    32    0    0    0    144    255    5    32    (12 entries.)
    
    [Indice]      [Entries]
    
        1		40	1	0	0	32	0	0	0	144	255	5	32	(12 entries.)
    cbamsc.size() = 1
    cbamsc.size() = 0
    transferIndex = 0
    mscTransfer.completed = 1
    
    Read 131072 bytes in 0.009599 seconds. Speed: 13.654756 MB/s
    sizeof(SecBuf[0]) = 1
    SecBufSize = 65536
    ----------------------------------------------------------
    Last edited by wwatson; 09-05-2020 at 12:26 AM. Reason: Show results.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •