Demo berbagi koneksi CoreMQTT - FreeRTOS

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Demo berbagi koneksi CoreMQTT

penting

Ini adalah versi arsip dari Panduan Pengguna FreeRTOS untuk digunakan dengan rilis FreerTOS 202012.00. Untuk versi terbaru dari dokumen ini, lihat Panduan Pengguna FreeRTOS.

Pengantar

Proyek demo berbagi koneksi CoreMQTT menunjukkan kepada Anda cara menggunakan aplikasi multithreaded untuk membuat koneksi ke broker AWS MQTT menggunakan TLS dengan otentikasi timbal balik antara klien dan server. Demo ini menggunakan implementasi antarmuka transport berbasis MBEDTLS untuk membuat server dan koneksi TLS yang diautentikasi klien, dan menunjukkan alur kerja subscribe-publish MQTT pada tingkat QoS 1. Demo berlangganan filter topik, menerbitkan topik yang cocok dengan filter, dan kemudian menunggu untuk menerima pesan tersebut kembali dari server di tingkat QoS 1. Siklus penerbitan ke broker dan menerima pesan yang sama kembali dari broker diulang tanpa batas waktu. Pesan dalam demo ini dikirim di QoS 1, yang menjamin setidaknya satu pengiriman sesuai dengan spesifikasi MQTT.

catatan

Untuk mengatur dan menjalankan demo FreeRTOS, ikuti langkah-langkahnya. Memulai dengan FreeRTOS

Demo ini menggunakan antrian aman utas untuk menahan perintah untuk berinteraksi dengan MQTT API. Ada empat tugas yang perlu diperhatikan dalam demo ini.

  • Tugas perintah (utama) mengambil perintah dari antrian perintah dan memprosesnya. Tugas lain menempatkan perintah dalam antrian ini untuk diproses. Tugas ini memasuki loop, di mana ia memproses perintah. Jika perintah terminasi diterima, tugas ini akan keluar dari loop.

  • Tugas penerbit sinkron membuat serangkaian operasi publikasi dan mendorongnya ke antrian perintah. Operasi ini kemudian dijalankan oleh tugas perintah. Tugas ini menggunakan penerbitan sinkron, yang berarti bahwa tugas ini akan menunggu setiap operasi publikasi selesai sebelum menjadwalkan yang berikutnya.

  • Tugas penerbit asinkron membuat serangkaian operasi publikasi dan mendorongnya ke antrian perintah. Operasi ini kemudian dijalankan oleh tugas perintah. Perbedaan antara tugas ini dan yang sebelumnya adalah bahwa ia tidak akan menunggu operasi publikasi selesai sebelum menjadwalkan yang berikutnya. Ini memeriksa status setiap operasi publikasi setelah semua operasi publikasi telah ditambahkan ke antrian. Perhatikan bahwa perbedaan antara penerbitan sinkron dan asinkron hanya dalam perilaku tugas-tugas ini. Tidak ada perbedaan dalam perintah publish yang sebenarnya.

  • Tugas pelanggan membuat langganan MQTT ke filter topik yang cocok dengan topik semua pesan yang diterbitkan oleh dua tugas penerbit. Tugas ini memasuki lingkaran dan menunggu untuk menerima kembali pesan yang diterbitkan oleh tugas lain.

Tugas dapat memiliki antrian untuk menyimpan pesan yang diterima. Tugas perintah akan mendorong pesan masuk ke antrian tugas apa pun yang berlangganan topik yang masuk.

Demo ini menggunakan koneksi TLS dengan otentikasi timbal balik untuk terhubung. AWS Jika jaringan tiba-tiba terputus selama demo, maka klien mencoba untuk menyambung kembali menggunakan logika backoff eksponensial. Jika klien berhasil terhubung kembali, tetapi broker tidak dapat melanjutkan sesi sebelumnya, maka klien akan berlangganan kembali ke topik yang sama dengan sesi sebelumnya.

Single threaded vs multithreaded

Ada dua model penggunaan CoreMQTT, single threaded dan multithreaded (multitasking). Demo ini menunjukkan cara membuat skema multithreading Anda sendiri. Ada juga contoh multithreaded lain yang menjalankan protokol MQTT di latar belakang dalam tugas agen (atau daemon). Untuk informasi lebih lanjut, lihat Agen dan Demo MWTT menggunakan CoreMQTT. Jika Anda menjalankan protokol MQTT dalam tugas agen, maka tidak perlu secara eksplisit mengelola status MQTT apa pun atau memanggil fungsi tersebut. MQTT_ProcessLoop Selain itu, jika Anda menggunakan tugas agen, beberapa tugas aplikasi dapat berbagi satu koneksi MQTT tanpa perlu sinkronisasi primitif, seperti mutex.

Kode sumber

File sumber demo diberi nama mqtt_demo_connection_sharing.c dan dapat ditemukan di freertos/demos/coreMQTT/ direktori dan GitHubsitus web.

Fungsionalitas

Demo ini membuat total empat tugas: tiga yang meminta panggilan API MQTT, dan satu yang memproses permintaan tersebut, yang merupakan tugas utama. Dalam demo ini, tugas utama memasuki loop yang membuat tiga subtugas, memanggil loop pemrosesan, dan membersihkan setelahnya. Tugas utama menciptakan koneksi MQTT tunggal ke broker yang dibagi di antara subtugas. Dua subtugas mempublikasikan pesan ke broker, dan yang ketiga menerima pesan kembali, menggunakan langganan MQTT ke filter topik yang cocok dengan semua topik pesan yang diterbitkan.

Typedefs

Demo mendefinisikan struktur, enum, dan pointer fungsi berikut.

Commands

Daripada membuat panggilan MQTT API secara langsung, tugas menggunakan Command_t struktur untuk membuat perintah yang menginstruksikan tugas utama untuk memanggil operasi API yang sesuai untuk mereka. Perintah memiliki jenis berikut:

  • PROCESSLOOP

  • PUBLISH

  • SUBSCRIBE

  • UNSUBSCRIBE

  • PING

  • DISCONNECT

  • RECONNECT

  • TERMINATE

TERMINATEPerintah tidak memiliki operasi API MQTT yang sesuai. Ini digunakan dalam demo untuk menginstruksikan tugas utama untuk menghentikan perintah pemrosesan dan memulai operasi pembersihan. Karena beberapa informasi tambahan, misalnya, mempublikasikan atau berlangganan informasi, diperlukan untuk beberapa perintah MQTT sepertiMQTT_Publish,, dan MQTT_SubscribeMQTT_Unsubscribe, kami menggunakan bidang tersebut. CommandContext_t Bidang ini diperlukan untuk ketiga perintah ini, dan ini opsional untuk yang lain.

Karena konteks ini diperlukan untuk perintah ini, jangan ubah nilai ini setelah perintah ditempatkan dalam antrian, sampai perintah selesai. Ketika perintah selesai, callback opsional dapat dipanggil. Dalam demo ini, kami menggunakan callback yang membuat notifikasi tugas untuk menginformasikan tugas panggilan bahwa perintah telah selesai. Untuk operasi MQTT yang memerlukan tanda terima kasih (berlangganan, berhenti berlangganan, dan menerbitkan dengan QoS lebih besar dari 0), perintah dianggap selesai setelah pengakuan diterima. Jika tidak, perintah selesai setelah panggilan MQTT API yang sesuai telah kembali.

Definisi berikut dapat ditemukan dalam mqtt_demo_connection_sharing.c file:

Ucapan Terima Kasih

Karena beberapa operasi MQTT memerlukan pengakuan, mereka menggunakan array AckInfo_t yang berisi pengenal paket dari pengakuan yang diharapkan, dan perintah asli yang mengharapkannya, sehingga callback penyelesaiannya dapat dipanggil.

Langganan

Demo ini dapat melacak langganan untuk setiap tugas. Untuk melakukannya, setiap tugas yang meminta langganan harus menyediakan antrian pesan di mana ia akan menerima kembali pesan yang diterbitkan (SubscriptionElement_t). Beberapa tugas dapat berlangganan filter topik yang sama, karena mereka diharapkan menggunakan antrian respons terpisah.

Menerima pesan yang diterbitkan

Karena tugas berjalan paralel dengan tugas utama, akan sulit dan memakan waktu untuk tugas utama harus menunggu setiap tugas berlangganan untuk membaca pesan yang diterbitkan yang diterima. Oleh karena itu, setiap pesan yang diterima disalin ke antrian respons tugas apa pun yang berlangganan topik pesan yang diterbitkan (PublishElement_t). Karena paket publikasi yang diterima dari klien MQTT berisi pointer ke buffer jaringan klien, payload dan nama topik pesan yang masuk disalin ke buffer terpisah sebelum dimasukkan ke dalam antrian respons. Dengan cara ini, tugas berlangganan masih dapat membaca informasi yang diterima setelah klien MQTT membersihkan buffer jaringannya.

Tugas utama

Tugas aplikasi utama, RunCoreMQTTConnectionSharingDemo, menetapkan sesi MQTT persisten, membuat tiga subtugas, dan menjalankan loop pemrosesan hingga perintah terminasi diterima. Sesi persisten digunakan, jadi jika jaringan tiba-tiba terputus, demo akan terhubung kembali ke broker di latar belakang, tanpa kehilangan langganan atau pesan yang dipublikasikan dari broker. Untuk membuat sesi persisten baru untuk setiap proses, demo terhubung ke broker dengan clean session flag set, lalu terputus dan terhubung kembali dengan flag unset. Setelah loop pemrosesan dihentikan, ia terputus dari broker, dan loop lagi dari titik di mana ia membuat koneksi ulang jaringan.

Penyelesaian demo yang berhasil akan menghasilkan output yang mirip dengan gambar berikut.

Koneksi MQTT berbagi output terminal demo pada penyelesaian yang berhasil
Loop perintah

Loop perintah prvCommandLoop,, menunggu perintah ditempatkan dalam antrian perintah, dan kemudian memanggil API MQTT yang sesuai. Semua perintah kecuali DISCONNECT dan TERMINATE menghasilkan MQTT_ProcessLoop dipanggil juga. Demo ini menetapkan callback soket wakeup untuk menambahkan PROCESSLOOP perintah ke antrian saat data tersedia di soket. Namun, mungkin ada banyak perintah di depannya dalam antrian pada saat itu. Untuk memastikan bahwa kita tidak mengabaikan data yang masuk saat perintah lain diproses, MQTT_ProcessLoop dipanggil untuk satu iterasi setelah setiap perintah.

Memproses perintah

Lihat prvProcessCommandfungsinya.

Tugas penerbit sinkron

Tugas penerbit sinkron, prvSyncPublishTugas, membuat PUBLISH operasi secara sinkron, dan menunggu setiap operasi selesai sebelum menjadwalkan yang berikutnya. Demo ini menggunakan QoS 1 untuk mempublikasikan pesan, yang berarti bahwa operasi ini tidak dianggap selesai sampai paket pengakuan publikasi telah diterima.

Tugas penerbit asinkron

Tugas penerbit asinkron, prvAsyncPublishTugas, tidak menunggu publikasi selesai sebelum menempatkan yang berikutnya dalam antrian. Ini menunjukkan bahwa tugas tidak selalu perlu menunggu operasi MQTT selesai sebelum dapat dilanjutkan. Karena setiap perintah publish memerlukan struct konteksnya sendiri, tugas ini tidak dapat menggunakan kembali struktur konteks tunggal seperti tugas penerbit sinkron, karena perintah sebelumnya mungkin masih membutuhkannya. Oleh karena itu, ia mengalokasikan memori untuk setiap struktur konteks, dan kemudian menunggu untuk membebaskan semua memori yang dialokasikan setelah semua pesan yang akan diterbitkan telah ditempatkan dalam antrian.

Tugas pelanggan

Tugas pelanggan, prvSubscribeTask, berlangganan filter topik yang cocok dengan semua topik pesan yang diterbitkan dari tugas sinkron dan asinkron. Kemudian menunggu untuk menerima kembali semua pesan yang diterbitkan sebelum berhenti berlangganan. Tugas ini juga bertanggung jawab untuk membuat TERMINATE operasi yang memberi sinyal tugas utama untuk mengakhiri loop perintah.