Saya sedang mempertimbangkan desain untuk sistem permainan minimalis berdasarkan PIC18F85J5. Bagian dari desain saya adalah bahwa game dapat dimuat dari kartu SD tanpa memprogram ulang chip atau mem-flash memori program. Saya memilih chip itu karena memiliki antarmuka memori eksternal yang memungkinkan saya menjalankan kode dari SRAM eksternal.
Ide dasarnya adalah bahwa memori program internal akan berisi antarmuka untuk menelusuri kartu sd, dan begitu pengguna memilih program itu akan menyalin file hex dari kartu sd ke ram eksternal, dan kemudian melompat eksekusi ke ruang ram eksternal .
Memori program internal juga akan memiliki berbagai perpustakaan untuk grafik, input pengontrol dan berbagai utilitas lainnya.
Saya cukup yakin saya tahu cara membuat bagian firmware internal berfungsi dengan baik. Masalahnya adalah membuat program untuk dijalankan dari RAM eksternal. Rasanya tidak sama dengan menargetkan gambar biasa, dan perlu mengetahui fungsi perpustakaan yang tersedia di memori internal, tetapi tidak mengkompilasi ulang, hanya tautan ke mereka. Ini juga harus mulai menggunakan alamat setelah 32k flash internal, bukan nol. Apakah ada cara yang baik untuk mengkompilasi program menggunakan jenis kendala ini?
Saya menggunakan MPLab IDE, tetapi saya tidak terlalu mengenalnya, atau bagaimana melakukan penyesuaian seperti ini.
Jawaban:
Anda memiliki dua masalah terpisah:
Ini sebenarnya sangat mudah. Yang harus Anda lakukan adalah membuat file tautan yang hanya berisi rentang alamat yang Anda inginkan untuk ditempati kode. Perhatikan bahwa Anda tidak hanya perlu memesan rentang alamat memori program tertentu untuk aplikasi eksternal ini, tetapi juga beberapa ruang RAM. Ruang RAM ini, seperti alamat memori program, perlu diperbaiki dan diketahui. Cukup sediakan hanya rentang alamat tetap dan dikenal yang tersedia untuk digunakan dalam file tautan. Jangan lupa untuk membuatnya TIDAK tersedia dalam file linker kode dasar.
Setelah kode dasar memuat aplikasi baru ke dalam memori eksternal, ia harus tahu cara menjalankannya. Yang paling mudah adalah memulai eksekusi di lokasi RAM eksternal pertama. Ini berarti kode Anda akan memerlukan satu bagian KODE di alamat awal absolut itu. Ini berisi GOTO di sebelah kanan label di sisa kode, yang semuanya akan dipindahkan.
Tidak ada cara sederhana untuk melakukan ini dengan alat Microchip yang ada, tetapi juga tidak seburuk itu.
Masalah yang jauh lebih besar adalah bagaimana Anda ingin berurusan dengan perubahan kode dasar. Strategi sederhananya adalah membuat kode dasar Anda, menjalankan program di atas file peta yang dihasilkan untuk memanen alamat global, lalu minta ia menulis file impor dengan pernyataan EQU untuk semua simbol yang ditentukan secara global. File impor ini kemudian akan dimasukkan dalam semua kode aplikasi. Tidak ada yang ditautkan, karena kode sumber aplikasi pada dasarnya berisi referensi alamat tetap ke titik entri kode dasar.
Itu mudah dilakukan dan akan berhasil, tetapi pertimbangkan apa yang terjadi ketika Anda mengubah kode dasar. Bahkan perbaikan bug kecil dapat menyebabkan semua alamat berpindah, dan semua kode aplikasi yang ada tidak akan bagus dan harus dibangun kembali. Jika Anda tidak pernah berencana untuk memberikan pembaruan kode dasar tanpa memperbarui semua aplikasi, maka mungkin Anda bisa lolos dengan ini, tapi saya pikir itu ide yang buruk.
Cara yang lebih baik adalah dengan memiliki area antarmuka yang ditentukan pada alamat yang diketahui tetap dikenal dalam kode dasar. Akan ada satu GOTO untuk setiap subrutin yang dapat dipanggil oleh kode aplikasi. GOTO-GOTO ini akan ditempatkan di alamat yang sudah diketahui, dan aplikasi eksternal hanya akan memanggil ke lokasi tersebut, yang kemudian akan melompat ke mana pun subrutin tersebut benar-benar berakhir dalam pembuatan kode dasar. Ini membutuhkan 2 kata memori program per subrutin yang diekspor dan dua siklus tambahan pada saat dijalankan, tetapi saya pikir ini sangat berharga.
Untuk melakukan ini dengan benar, Anda perlu mengotomatiskan proses menghasilkan GOTO dan file ekspor yang dihasilkan yang akan diimpor aplikasi eksternal untuk mendapatkan alamat subrutin (sebenarnya pengarah GOTO). Anda mungkin dapat melakukan dengan penggunaan makro MPASM yang cerdik, tetapi jika saya melakukan ini saya pasti akan menggunakan preprocessor saya karena dapat menulis ke file eksternal pada waktu preprocessing. Anda dapat menulis makro preprocessor sehingga setiap redirector dapat didefinisikan oleh satu baris kode sumber. Makro melakukan semua hal buruk di bawah tenda, yaitu untuk menghasilkan GOTO, referensi eksternal ke rutin target aktual, dan menambahkan baris yang sesuai ke file ekspor dengan alamat konstan yang diketahui dari rutin itu, semua dengan nama yang sesuai. Mungkin makro hanya membuat banyak variabel preprocessor dengan nama biasa (seperti array run-time diperluas), dan kemudian file ekspor ditulis setelah semua panggilan makro. Salah satu dari banyak hal yang dapat dilakukan preprocessor saya yang tidak dapat dilakukan macro MPASM adalah melakukan manipulasi string untuk membangun nama simbol baru dari nama lain.
Preprosesor saya dan banyak hal terkait lainnya tersedia secara gratis di www.embedinc.com/pic/dload.htm .
sumber
Opsi 1: Bahasa yang Diartikan
Ini tidak langsung menjawab pertanyaan (yang merupakan pertanyaan luar biasa, BTW, dan saya berharap dapat belajar dari jawaban yang mengatasinya secara langsung), tetapi sangat umum ketika melakukan proyek yang dapat memuat program eksternal untuk menulis program eksternal dalam bahasa yang ditafsirkan. Jika sumber daya terbatas (yang akan berada pada prosesor ini, pernahkah Anda berpikir tentang menggunakan prosesor PIC32 atau ARM kecil untuk ini?), Itu umum untuk membatasi bahasa ke subset dari spesifikasi lengkap. Lebih jauh ke bawah rantai adalah bahasa-bahasa khusus domain yang hanya melakukan beberapa hal.
Sebagai contoh, proyek elua adalah contoh dari bahasa yang ditafsirkan dengan sumber daya rendah (64 kB RAM). Anda dapat menekan ini hingga 32k RAM jika Anda menghapus beberapa fitur (Catatan: Ini tidak akan bekerja pada prosesor Anda saat ini, yang merupakan arsitektur 8-bit. Menggunakan RAM eksternal mungkin akan terlalu lambat untuk grafis). Ini memberikan bahasa yang cepat dan fleksibel di mana pengguna baru dapat dengan mudah memprogram game jika Anda menyediakan API minimal. Ada banyak dokumentasi yang tersedia untuk bahasa online. Ada bahasa lain (seperti Forth dan Basic) yang dapat Anda gunakan dengan cara yang sama, tapi saya pikir Lua adalah pilihan terbaik saat ini.
Dengan nada yang sama, Anda dapat membuat bahasa khusus domain Anda sendiri. Anda harus menyediakan API dan dokumentasi eksternal yang lebih lengkap, tetapi jika semua gim serupa maka ini tidak akan terlalu sulit.
Bagaimanapun, PIC18 mungkin bukan prosesor yang saya gunakan untuk sesuatu yang melibatkan pemrograman kustom / scripting dan grafik. Anda mungkin akrab dengan kelas prosesor ini, tetapi saya menyarankan agar ini saat yang tepat untuk menggunakan sesuatu dengan driver layar dan lebih banyak memori.
Opsi 2: Hanya memprogram ulang semuanya
Namun, jika Anda sudah merencanakan pemrograman sendiri semua game di C, maka jangan repot-repot hanya memuat logika game dari kartu SD. Anda hanya memiliki 32kB Flash untuk memprogram ulang, dan dapat dengan mudah mendapatkan kartu microSD 4 GB untuk ini. (Catatan: kartu yang lebih besar biasanya SDHC, yang lebih sulit untuk dihubungkan). Dengan asumsi bahwa Anda menggunakan setiap byte terakhir dari 32 kB Anda, yang memberikan ruang pada kartu SD untuk 131.072 salinan firmware Anda dengan logika permainan apa pun yang Anda butuhkan.
Ada banyak catatan aplikasi untuk menulis bootloader untuk PIC, seperti AN851 . Anda harus merancang bootloader Anda untuk menempati wilayah memori tertentu (mungkin bagian atas wilayah memori, Anda akan menentukan ini di tautan), dan menentukan bahwa proyek firmware penuh tidak mencapai wilayah ini. Catatan appnote ini lebih terinci. Cukup ganti "Bagian boot dari PIC18F452" dengan "Bagian boot yang saya tentukan di tautan" dan semuanya akan masuk akal.
Kemudian, bootloader Anda hanya perlu memungkinkan pengguna untuk memilih program untuk dijalankan dari kartu SD, dan menyalin semuanya. UI bisa jadi bahwa pengguna harus menahan tombol untuk masuk ke mode pemilihan. Biasanya, bootloader hanya akan memeriksa status tombol ini saat reset, dan, jika tidak ditekan, boot ke dalam gim. Jika tertahan, pengguna harus memilih file pada kartu SD, menyalin program, dan melanjutkan boot ke gim [baru].
Ini rekomendasi saya saat ini.
Opsi 3: Sihir yang dalam melibatkan hanya menyimpan sebagian dari file hex
Masalah dengan mekanisme yang Anda bayangkan adalah bahwa prosesor tidak berurusan dengan API dan pemanggilan fungsi, ini berkaitan dengan angka - alamat yang dapat dilompati oleh penunjuk instruksi dan mengharapkan ada kode yang mengeksekusi pemanggilan fungsi sesuai dengan spesifikasi API. Jika Anda mencoba mengkompilasi hanya sebagian dari program, linker tidak akan tahu apa yang harus dilakukan ketika Anda menelepon
check_button_status()
atautoggle_led()
. Anda mungkin tahu bahwa fungsi-fungsi itu ada di file hex pada prosesor, tetapi perlu tahu persis di mana mereka berada.Linker telah memecah kode Anda menjadi beberapa bagian; Anda secara teoritis dapat memecah ini menjadi bagian tambahan dengan beberapa
-section
dan#pragma
mantra. Saya belum pernah melakukan ini, dan tidak tahu caranya. Sampai kedua metode di atas gagal saya (atau seseorang memposting jawaban yang luar biasa di sini), saya mungkin tidak akan mempelajari mekanisme ini, jadi saya tidak bisa mengajarkannya kepada Anda.sumber