Saat ini, semakin banyak perangkat tertanam yang mendukung pembaruan otomatis jarak jauh tanpa perlu menggunakan perangkat pengunduh, sehingga pemeliharaan perangkat menjadi sangat mudah. Untuk mengaktifkan pembaruan jarak jauh pada suatu perangkat, kita perlu menulis kode program yang mendukung proses pembaruan tersebut. Program ini umumnya disebut sebagai BootLoader.
Pada dasarnya, kode program perangkat dibagi menjadi dua bagian: BootLoader dan APP. BootLoader bertanggung jawab untuk memperbarui APP dan memulai eksekusinya. Di sisi lain, APP bertanggung jawab untuk mengimplementasikan fungsi operasional perangkat, yang pada dasarnya menampung fungsi inti perangkat.
Untuk mikrokontroler seri Cortex-M, mencapai transisi yang aman dari BootLoader ke APP memerlukan konfigurasi tertentu. Artikel ini menggunakan mikrokontroler STM32 sebagai contoh untuk menguraikan langkah-langkah konfigurasi utama yang diperlukan guna mengimplementasikan transisi yang sukses dari BootLoader ke APP.
BootLoader Lompat ke Aplikasi
Langkah 1: Partisi Flash
Selama tahap pemrograman dan perancangan, penting untuk membagi memori Flash sesuai dengan kebutuhan aplikasi yang spesifik. Hal ini mencakup penentuan lokasi penyimpanan BootLoader dan APP, serta alokasi ruang untuk masing-masing. Penempatan penyimpanan ini secara langsung memengaruhi eksekusi program dan transisinya.
Salah satu strategi pembaruan yang paling sederhana melibatkan penggunaan BootLoader dan APP. BootLoader menangani transisi dan memfasilitasi pembaruan APP. Artikel ini menggunakan strategi pembaruan ini sebagai contoh untuk penjelasan.
Untuk mikrokontroler STM32, alamat yang dipetakan untuk memulai program adalah 0x8000000.
BootLoader dapat disimpan di alamat 0x8000000, dan ruang yang dialokasikan dapat disesuaikan berdasarkan ukuran Flash chip yang spesifik, misalnya, 0x10000 atau 64KB.
Alamat penyimpanan APP ditempatkan setelah BootLoader, tepatnya di alamat 0x8010000. Ruang yang tersisa di Flash dapat dialokasikan untuk APP.
Langkah 2: Konfigurasi Proyek BootLoader
Mengkonfigurasi proyek BootLoader memerlukan beberapa langkah. Mengambil MDK sebagai contoh, program BootLoader disimpan dalam memori FLASH pada alamat 0x8000000 dengan ukuran 0x10000.

Saat beralih ke APP menggunakan kode program, perhatikan hal-hal berikut:
- Pastikan keabsahan alamat puncak tumpukan, artinya pastikan alamat awal APP valid.
if(((*(__IO uint32_t *)APP_FLASH_ADDR) & 0x2FFE0000) == 0x20000000)
- Nonaktifkan semua interupsi untuk mencegah gangguan selama proses transisi yang dapat menyebabkan terjadinya pengecualian.
- Dapatkan alamat awal program APP, yang disimpan sebagai kata kedua (alamat awal + 4, data disimpan di Flash).
- Inisialisasi penunjuk tumpukan (kata pertama di area kode pengguna menyimpan alamat puncak tumpukan).
- Konversikan alamat awal APP menjadi tipe penunjuk fungsi dan lakukan transisi.
Kode spesifik untuk transisi tersebut adalah sebagai berikut:
/* Define type */
typedef void (*pFunction)(void);
/* APP flash address */
#define APP_FLASH_ADDR (0x8010000)
void jump_to_app(void)
{
uint32_t JumpAddress;
pFunction Jump_To_Application;
/* Check if the stack top address is valid */
if(((*(__IO uint32_t *)APP_FLASH_ADDR) & 0x2FFE0000) == 0x20000000)
{
/* Disable all interrupts to prevent disturbances during transition */
__disable_irq();
/* The second word in the user code area is the program's start address (reset address) */
JumpAddress = *(__IO uint32_t *) (APP_FLASH_ADDR + 4);
/* Initialize the user application's Stack Pointer */
__set_MSP(*(__IO uint32_t *) APP_FLASH_ADDR);
/* Type conversion */
Jump_To_Application = (pFunction) JumpAddress;
/* Transition to the APP */
Jump_To_Application();
}
}
Langkah 3: Konfigurasi Proyek Aplikasi
Demikian pula, proyek APP memerlukan konfigurasi tertentu. Mengambil MDK sebagai contoh, program APP disimpan dalam memori FLASH pada alamat 0x8010000 dengan ukuran 0x30000.

Konfigurasi untuk program APP mencakup langkah-langkah berikut:
- Pindahkan tabel vektor Flash internal di dalam APP dengan memodifikasi SCB->VTOR.
- Setelah APP mulai berjalan, sangat penting untuk mengaktifkan interupsi dalam fungsi inisialisasi guna memastikan eksekusi program berjalan lancar. Jika tidak dilakukan, hal ini dapat menyebabkan anomali pada program.
Secara umum, dalam berkas startup, fungsi SystemInit() dipanggil. Fungsi ini mengonfigurasi informasi antarmuka Flash.
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET

Ubah nilai definisi makro VECT_TAB_OFFSET menjadi 0x10000.

Setelah program APP dimulai, sangat penting untuk mengaktifkan interupsi global. Anda dapat menempatkan kode berikut di bagian inisialisasi:
/* Enable interrupts */
__enable_irq();
Aplikasi: Langsung ke BootLoader
Selama perangkat beroperasi, aplikasi sedang berjalan dan memproses fungsi-fungsi bisnis. Jika Anda ingin memperbarui aplikasi, Anda perlu beralih dari aplikasi ke BootLoader. Jadi, bagaimana cara membuat aplikasi beralih ke BootLoader? Ada dua metode:
- Mode perangkat keras, mematikan daya perangkat lalu menyalakannya kembali atau menekan tombol reset
- Mode perangkat lunak, mereset MCU melalui kontrol perangkat lunak
Dalam mode perangkat lunak, perintah kontrol dapat ditambahkan ke kode aplikasi, dan ketika aplikasi menerima perintah loncat (atau perintah pembaruan), MCU akan direset. Kode berikut dapat mereset MCU:
/* reset chip */
HAL_NVIC_SystemReset();




