Mengukur beban cpu dari rutin interupsi

8

Saya memiliki isr yang memperbarui tampilan pada frekuensi tetap. Saya ingin menyesuaikan rutinitas saya untuk meminimalkan overhead dan menjaga waktu cpu sebanyak mungkin terbuka untuk pemrosesan lainnya, tetapi saya tidak memiliki cara yang baik untuk mengumpulkan metrik untuk menentukan beban cpu saya.

Saya bisa melihat perakitan dan menganalisis rutinitas, tetapi saya tidak memiliki kesabaran atau kemampuan untuk melakukan itu secara akurat. Saya tidak merasa seperti saya perlu hasil yang sangat halus juga, hanya persentase sederhana dari waktu cpu ditempati oleh isr.

Saya bisa menetapkan pin tinggi hanya ketika isr aktif dan mengukurnya secara eksternal. Itu memiliki minimum overhead dalam kode, tetapi saya tidak tahu harus mengukurnya dengan apa. Saya tidak punya osiloskop atau semacamnya. Apakah ada ic sederhana atau cara mudah untuk menggunakan mikro lain untuk mengukur siklus tugas? Saya telah mendengar tentang chip penghitung frekuensi khusus, tetapi apakah ada sesuatu untuk siklus kerja?

captncraig
sumber

Jawaban:

8

Hanya ide setengah matang, Anda mungkin dapat menggunakan timer seperti itu (kode semu):

int main(void)
{

    /* ... init timers and uart here, enable your interrupts ... */

    start_timer0();
    while (!timer1Started()){}
    stop_timer1();

    uart_puts("Idle ticks: %d, ISR ticks: %d", timer0_value, timer1_value);

}

dan di layar ISR Anda ...

ISR_display()
{
    stop_timer0();
    start_timer1();

    /* ... your ISR routine ... */
}

Saya sudah membuat beberapa asumsi di sini. 1 - bahwa Anda tidak menggunakan timer Anda untuk hal lain, dan bahwa, 2 - overhead memulai dan menghentikan timer adalah minimal (biasanya dilakukan dengan register register tunggal). EDIT: dan asumsi ke-3, Anda dapat menangkap semua ini sebelum waktu meluap, tetapi mungkin Anda bisa menjelaskannya juga.

Akan ada beberapa overhead peralihan konteks yang tidak dapat Anda tangkap, dan ini juga menambahkan dua operasi tambahan dalam ISR Anda (pastikan untuk menggunakan makro untuk start_timer / stop_timer Anda untuk menghilangkan overhead panggilan fungsi). Jika Anda bisa mendapatkan jumlah total siklus yang digunakan untuk makro start + stop timer, maka Anda dapat mengurangi centang-centang itu dari timer1_value untuk mendapatkan nilai ticks ISR sedikit lebih akurat. Perhitungan akhir Anda untuk% waktu CPU yang digunakan adalah:

Usagecpu=(TicksisrTicksisr+Ticksidle)100
Jon L
sumber
1
+1 untuk solusi yang tidak memerlukan perangkat keras eksternal. Mungkin cara yang lebih rumit untuk melakukannya, tetapi cocok dengan kendala saya. Saya hanya perlu belajar tentang timer sekarang. Terima kasih.
captncraig
Saya menggunakan ini pada AVR untuk proyek serupa. Ini bekerja dengan sangat baik.
drxzcl
11

Tetapkan pin output saat Anda memasukkan ISR dan menghapusnya sebelum kembali dari itu. Saring output dengan filter RC. Tegangan melintasi kapasitor akan memberi Anda siklus tugas ISR.
Misalnya, jika catu daya Anda 3.3V dan Anda mengukur 33mV, maka Anda menghabiskan 1% dari waktu di ISR.

stevenvh
sumber
2
Ini persis apa yang kami lakukan, kecuali untuk bagian filter RC. Kami menetapkan pin keluaran saat memasuki ISR, lalu menghapusnya saat kembali. Melihat ini pada o-scope akan memberikan segala macam info yang berguna.
3
@ David - Saya juga hanya menonton pulsa pada lingkup, tetapi OP mengatakan dia tidak memilikinya.
stevenvh
1
Sepertinya saya harus mulai menabung untuk cakupan yang bagus.
captncraig
@stevenvh, persis apa yang akan saya sarankan ketika saya melihat tidak adanya ruang lingkup. Inilah sebabnya mengapa orang-orang yang disematkan itu menyukai beberapa pin digital tambahan.
Kortuk
Memfilter ke meteran tanpa ruang lingkup ide yang bagus. Nyalakan / matikan LED dan ukur kecerahan yang efektif: -) (Sangat sulit untuk melihat bahkan variasi yang cukup besar - tapi lucu.)
Russell McMahon
7

Cara termudah untuk melakukan ini adalah menjalankan kode dalam simulator dan mengukur siklus yang diambil oleh rutin interupsi. Simulator Microchip MPLAB, misalnya, memiliki fitur stopwatch praktis yang sangat berguna untuk tujuan ini.

Gagal, menaikkan pin di awal interupsi dan menurunkannya di akhir bisa membantu. Cara termudah untuk melihatnya adalah dengan osiloskop. Jika Anda melakukan proyek mikrokontroler dan elektronik, Anda tetap harus mendapatkannya.

Tanpa ruang lingkup, Anda dapat dengan mudah menyaring tegangan pin rendah, kemudian mengukurnya dengan voltmeter. Tegangan yang dibagi dengan tegangan daya prosesor akan memberi Anda fraksi waktu pin tinggi. Misalnya, jika prosesor berjalan pada 3.3V dan tegangan pin yang disaring low pass adalah 800mV, maka pin tersebut tinggi 800mV / 3.3V = 24% dari waktu.

Karena Anda tampaknya menggunakan kompiler, Anda perlu menurunkan jawaban ini. Kompiler kemungkinan menambahkan beberapa kode entri interupsi sebelum kode Anda berjalan dan interupsi kode keluar setelah kode Anda berjalan. Waktu interupsi yang sebenarnya akan memperpanjang beberapa siklus di kedua sisi pulsa. Tentu saja jika Anda peduli dengan waktu interupsi, Anda seharusnya tidak menggunakan kompiler.

Olin Lathrop
sumber