Harap, sebelum mengirimkan permintaan dukungan, baca dengan cermat readme ini dan periksa apakah jawaban sudah ada di antara pertanyaan yang dijawab sebelumnya: Jangan menyalahgunakan pelacak masalah GitHub.
Perpustakaan itu sendiri memiliki konsumsi memori implisit sekitar 0,5kB : 580 byte (maks) kode dan 8 byte memori, menurut perhitungan saya. Itu tidak mempertimbangkan ruang yang digunakan untuk menyimpan barang -barang itu sendiri.
Saat mendeklarasikan buffer Anda, Anda harus menentukan tipe data yang harus ditangani dan kapasitas buffer: kedua parameter tersebut akan mempengaruhi memori yang dikonsumsi oleh buffer.
# include < CircularBuffer.hpp >
CircularBuffer<byte, 100 > bytes; // uses 538 bytes
CircularBuffer< int , 100 > ints; // uses 638 bytes
CircularBuffer< long , 100 > longs; // uses 838 bytes
CircularBuffer< float , 100 > floats; // uses 988 bytes
CircularBuffer< double , 100 > doubles; // uses 988 bytes
CircularBuffer< char , 100 > chars; // uses 538 bytes
CircularBuffer< void *, 100 > pointers; // uses 638 bytes
Harap dicatat : Penggunaan memori yang dilaporkan di atas mencakup memori program yang digunakan oleh kode perpustakaan, memori heap jauh lebih sedikit dan sebanding dengan array dengan ukuran dan jenis buffer yang sama.
Mari kita mulai memperjelas: Perpustakaan tidak mendukung memasukkan data di tengah buffer. Anda dapat menambahkan data ke buffer baik sebelum elemen pertama melalui operasi unshift()
atau setelah elemen terakhir melalui operasi push()
. Anda dapat terus menambahkan data di luar kapasitas maksimum buffer, tetapi Anda akan kehilangan informasi yang paling tidak signifikan:
unshift()
menambah kepala , menambah kapasitas di luar kapasitas menyebabkan elemen pada ekor ditimpa dan hilangpush()
menambah ekor , menambah kapasitas di luar kapasitas menyebabkan elemen di kepala ditimpa dan hilang Baik unshift()
dan push()
mengembalikan true
jika penambahan tidak menyebabkan kerugian informasi, false
jika terjadi overwrite:
CircularBuffer< int , 5 > buffer; // buffer capacity is 5
// all of the following return true
buffer.unshift( 1 ); // [1]
buffer.unshift( 2 ); // [2,1]
buffer.unshift( 3 ); // [3,2,1]
buffer.push( 0 ); // [3,2,1,0]
buffer.push( 5 ); // [3,2,1,0,5]
// buffer is now at full capacity, from now on any addition returns false
buffer.unshift( 2 ); // [2,3,2,1,0] returns false
buffer.unshift( 10 ); // [10,2,3,2,1] returns false
buffer.push(- 5 ); // [2,3,2,1,-5] returns false
Demikian pula dengan penambahan data, pengambilan data dapat dilakukan pada ekor melalui operasi pop()
atau dari kepala melalui operasi shift()
: keduanya menyebabkan elemen dibaca dihapus dari buffer.
Membaca data di luar ukuran buffer aktual memiliki perilaku yang tidak ditentukan dan merupakan tanggung jawab pengguna untuk mencegah pelanggaran batas seperti itu menggunakan operasi tambahan yang tercantum di bagian selanjutnya. Perpustakaan akan berperilaku berbeda tergantung pada tipe data dan metode alokasi, tetapi Anda dapat dengan aman mengasumsikan program Anda akan macet jika Anda tidak menonton langkah Anda.
Operasi baca yang tidak merusak juga tersedia:
first()
mengembalikan elemen di kepalalast()
mengembalikan elemen di ekor[]
CircularBuffer< char , 50 > buffer; // ['a','b','c','d','e','f','g']
buffer.first(); // ['a','b','c','d','e','f','g'] returns 'a'
buffer.last(); // ['a','b','c','d','e','f','g'] returns 'g'
buffer.pop(); // ['a','b','c','d','e','f'] returns 'g'
buffer.pop(); // ['a','b','c','d','e'] returns 'f'
buffer.shift(); // ['b','c','d','e'] returns 'a'
buffer.shift(); // ['c','d','e'] returns 'b'
buffer[ 0 ]; // ['c','d','e'] returns 'c'
buffer[ 1 ]; // ['c','d','e'] returns 'd'
buffer[ 2 ]; // ['c','d','e'] returns 'e'
buffer[ 10 ]; // ['c','d','e'] returned value is unpredictable
buffer[ 15 ]; // ['c','d','e'] returned value is unpredictable
isEmpty()
mengembalikan true
hanya jika tidak ada data yang disimpan dalam bufferisFull()
Mengembalikan true
jika tidak ada data yang dapat ditambahkan lebih lanjut ke buffer tanpa menyebabkan overwrites/kehilangan datasize()
mengembalikan jumlah elemen yang saat ini disimpan dalam buffer; Ini harus digunakan bersama dengan operator []
untuk menghindari pelanggaran batas: indeks elemen pertama selalu 0
(jika buffer tidak kosong), indeks elemen terakhir selalu size() - 1
available()
mengembalikan jumlah elemen yang dapat ditambahkan sebelum memenuhi buffercapacity()
Mengembalikan jumlah elemen yang dapat disimpan buffer, untuk kelengkapan hanya seperti yang ditentukan pengguna dan tidak pernah berubah dari 1.3.0
digantikan oleh capacity
variabel anggota hanya bacaclear()
me -reset seluruh buffer ke keadaan awalnya (perhatikan, jika Anda telah mengalokasikan objek secara dinamis dalam buffer Anda, memori yang digunakan oleh objek tersebut tidak dirilis: iterate di atas konten buffer dan melepaskan objek yang sesuai dengan metode alokasi mereka)copyToArray(array)
menyalin konten buffer ke array
array standar. Array harus cukup besar untuk menahan semua elemen saat ini dalam buffer.copyToArray(conversionFn, array)
menyalin konten buffer ke array
array standar yang menjalankan fungsi pada setiap elemen, biasanya konversi jenis. Array harus cukup besar untuk menahan semua elemen saat ini dalam buffer. Mulai dari versi 1.3.0
Perpustakaan mampu secara otomatis mendeteksi tipe data mana yang harus digunakan untuk indeks berdasarkan kapasitas buffer:
65535
maka indeks Anda akan menjadi unsigned long
unsigned int
untuk buffer dengan kapasitas yang dinyatakan lebih besar dari 255
byte
akan cukupSelain itu, Anda dapat mencampur dalam buffer kode yang sama dengan indeks kecil dan buffer dengan indeks normal: sebelumnya ini tidak dimungkinkan.
CircularBuffer< char , 100 > optimizedBuffer; // reduced memory footprint, index type is uint8_t (a.k.a. byte)
CircularBuffer< long , 500 > normalBuffer; // standard memory footprint, index type is unit16_t (a.k.a. unsigned int)
CircularBuffer< int , 66000 > hugeBuffer; // extended memory footprint, index type is unit32_t (a.k.a. unsigned long)
Untuk mendapatkan keuntungan maksimum dari optimasi di atas, kapan saja Anda perlu merujuk ke indeks buffer, Anda harus menggunakan jenis yang paling tepat: ini dapat dengan mudah dicapai dengan menggunakan spesifikasi decltype
, seperti dalam contoh berikut:
// the iterator variable i is of the correct type, even if
// we don't know what's the buffer declared capacity
for (decltype(buffer):: index_t i = 0 ; i < buffer.size(); i++) {
avg += buffer[i] / buffer. size ();
}
Jika lebih suka, Anda dapat alias jenis indeks dan merujuk ke alias tersebut:
using index_t = decltype(buffer):: index_t ;
for ( index_t i = 0 ; i < buffer.size(); i++) {
avg += buffer[i] / buffer. size ();
}
Berikut ini hanya berlaku untuk versi sebelum 1.3.0
.
Secara default perpustakaan menggunakan indeks unsigned int
, memungkinkan untuk maksimum 65535
item, tetapi Anda jarang membutuhkan toko yang begitu besar.
Anda dapat mengganti indeks perpustakaan ke jenis byte
yang mendefinisikan makro CIRCULAR_BUFFER_XS
sebelum arahan #include
: ini mengurangi memori yang digunakan oleh perpustakaan itu sendiri hanya dengan 36
byte, tetapi memungkinkan Anda untuk berpotensi memeras lebih banyak kapan pun Anda melakukan akses yang diindeks, jika Anda, jika Anda melakukan akses yang diindeks, jika Anda melakukan akses, jika Anda melakukan akses yang diindeks, jika Anda melakukan akses, jika Anda melakukan akses yang diindeks, jika Anda melakukan akses, jika Anda melakukan akses setiap kali Anda melakukan akses, jika Anda melakukan akses, jika Anda melakukan akses, jika Anda melakukan akses setiap kali Anda melakukan akses, jika Anda melakukan akses setiap kali Anda melakukan akses, Anda melakukan apa saja, dengan menggunakan tipe data yang lebih kecil.
# define CIRCULAR_BUFFER_XS
# include < CircularBuffer.h >
CircularBuffer< short , 100 > buffer;
void setup () { }
void loop () {
// here i should be declared of type byte rather than unsigned int
// in order to maximize the effects of the optimization
for (byte i = 0 ; i < buffer. size () - 1 ; i++) {
Serial. print (buffer[i]);
}
}
Harap dicatat : sakelar makro ini memaksa buffer untuk menggunakan tipe data 8 bit sebagai indeks internal, dengan demikian semua buffer Anda akan terbatas pada kapasitas maksimum 255
.
Perpustakaan memang membantu bekerja dengan interupsi mendefinisikan sakelar makro CIRCULAR_BUFFER_INT_SAFE
, yang memperkenalkan pengubah volatile
ke variabel count
, membuat seluruh perpustakaan lebih ramah interupsi dengan harga menonaktifkan beberapa optimasi kompiler. Pernyataan #define
perlu diletakkan di suatu tempat sebelum pernyataan #include
:
# define CIRCULAR_BUFFER_INT_SAFE
# include < CircularBuffer.h >
CircularBuffer< unsigned long , 10 > timings;
void count () {
timings. push ( millis ());
}
void setup () {
attachInterrupt ( digitalPinToInterrupt ( 2 ), count, RISING);
}
void loop () {
Serial. print ( " buffer size is " ); Serial. println (timings. size ());
delay ( 250 );
}
Harap dicatat ini tidak membuat perpustakaan interupsi aman , tetapi itu membantu penggunaannya di perusahaan yang digerakkan interupsi.
Beberapa contoh tersedia di folder examples
Perpustakaan:
copyToArray()
. Jika Anda menggunakan pustaka ini untuk menyimpan objek yang dialokasikan secara dinamis, jangan menggunakan metode clear()
karena itu tidak akan melakukan dealokasi memori: Anda perlu mengulangi konten buffer Anda dan melepaskan memori yang sesuai dengan metode alokasi yang digunakan, baik melalui delete
(jika jika Anda telah menggunakan new
) atau free
(dalam kasus malloc
):
while (!buffer.isEmpty()) {
// pick the correct one
delete buffer. pop ();
free (buffer. pop ());
}
Yang sama berlaku untuk operasi pop()
dan shift()
karena objek yang dialokasikan secara dinamis hanya terlepas dari buffer, tetapi memori yang digunakannya tidak dirilis secara otomatis (lihat contoh Object.ino)
Record* record = new Record(millis(), sample); // a dynamically allocated object
buffer.push(record);
// somewhere else
if (!buffer.isEmpty()) {
Record* current = buffer. pop ();
Serial. println (current. value ());
delete current; // if you don't do this the object memory is lost!!!
}
copyToArray(array)
dan copyToArray(array, convertFn)
.h
ke .hpp
shift()
dan pop()
Operasi penyalahgunaan untuk mengacaukan buffer[]
abort()
adalah AVR khususSebagian besar perbaikan utama di bawah ini telah disumbangkan oleh Erlkoenig90: Terima kasih Niklas!
capacity()
mendukung capacity
atribut instan konstanEventLogging
dan Interrupts
CIRCULAT_BUFFER_XS
mendukung identifikasi jenis indeks otomatisUINT32_MAX
)CIRCULAR_BUFFER_INT_SAFE
memset
saat membersihkanclear()
pop()
tetappop()
dan shift()
capacity()
debug()
, dinonaktifkan oleh pra-prosesor secara default