Saat ini saya memiliki nomor seri yang dikodekan dalam firmware saya untuk desain yang saya kerjakan. Firmware dapat membaca dan melaporkan kembali nomor seri. Itu berfungsi dengan baik untuk apa yang saya butuhkan. Masalahnya adalah bahwa setiap nomor seri baru mengharuskan saya untuk mengubah kode dan mengkompilasi ulang. Ini rumit ketika ada banyak unit yang akan dibangun, memiliki kemungkinan untuk memperkenalkan kesalahan, dan merupakan praktik buruk yang menyeluruh. Nomor seri diberikan kepada saya dan desain perangkat keras diatur dalam batu, jadi saya tidak bisa menambahkan fitur dalam perangkat keras untuk membuat serial unit (EEPROM / Silicon ID Chip / Pull-Ups). Yang ingin saya lakukan adalah mencari nomor seri di alamat tetap, mengkompilasi kode sekali, lalu mengedit alamat itu di file HEX yang dikompilasi untuk setiap nomor seri baru. Nomor direferensikan di beberapa tempat, jadi idealnya, saya ingin mendefinisikan & menemukannya sekali, kemudian referensi "variabel" di tempat lain dalam kode saya. Adakah yang tahu cara menemukan data konstan di lokasi memori spesifik yang dapat saya pilih, menggunakan C18 Compiler? Apakah ada cara yang lebih baik yang bisa disarankan seseorang?
sumber
Jawaban:
Khusus untuk menyelesaikan pertanyaan tentang variabel terikat ke alamat spesifik dalam memori flash pada PIC18 dengan kompiler C18, silakan merujuk bagian "Pragmas" di hlpC18ug.chm di direktori doc tempat kompiler diinstal.
Untuk melakukan ini, Anda perlu mendefinisikan "bagian" baru dalam memori dan mengikatnya ke alamat awal
#pragma romdata serial_no_section=0x1700
Ini menciptakan bagian baru yang disebut "serial_no_section" yang dimulai pada alamat 0x1700 dalam memori flash (program) (karena kami mendefinisikan "romdata" di #pragma).
Langsung setelah baris #pragma, tentukan variabel Anda jadi:
Sekarang Anda memiliki 0x12 di alamat 0x1700 dan 0x34 di alamat 0x1701 dalam memori (karena PIC18 menggunakan model little-endian). "Const rom" memastikan bahwa kompiler mengetahui bahwa ini adalah tipe variabel const, dan bahwa variabel tersebut terletak pada memori "rom" dan karenanya perlu diakses melalui instruksi membaca tabel.
#pragma romdata
Pernyataan akhir memastikan bahwa setiap deklarasi variabel berikut ini ditautkan ke bagian memori default sebagai linker melihat cocok daripada mengikuti di bagian "serial_no_section".Sekarang semua kode dapat dengan mudah merujuk variabel "mySerialNumber", dan Anda tahu persis apa alamat nomor seri dapat ditemukan di dalam memori.
Mengedit kode HEX bisa sedikit menantang karena Anda perlu menghitung checksum untuk setiap baris yang Anda edit. Saya sedang mengerjakan kelas C ++ untuk memecahkan kode dan menyandikan file Intel HEX yang seharusnya membuat ini lebih mudah, tetapi belum selesai. File decoding berfungsi, encoding lagi belum diimplementasikan. Proyek (jika Anda tertarik) ada di sini https://github.com/codinghead/Intel-HEX-Class
Semoga ini membantu
sumber
Saya telah melakukan nomor seri (s / n singkatnya) dengan cara yang mirip dengan apa yang Joel gambarkan. Saya menggunakan kompilator PIC18F4620 dan CCS. Lokasi s / n dalam memori Flash memaksa hingga 4 byte terakhir. Karena saya hanya menggunakan 80% Flash, kompiler dan tautan saya tidak akan menulis kode yang dapat dieksekusi dalam 4 byte terakhir.
Lalu saya punya 2 cara alternatif untuk benar-benar menulis s / n ke unit individu:
Membalas komentar Joel
Tidak tahu tentang C18, tetapi kompiler CCS dilengkapi dengan fungsi pustaka
write_program_eeprom(...)
danread_program_eeprom(...)
. Di sini terlihat seperti apa mereka berkumpul.sumber
write_program_eeprom(...)
danread_program_eeprom(...)
. EEPROM dan Flash adalah dua hal yang berbeda!Saya sudah melakukan ini beberapa kali. Biasanya saya mendefinisikan area info firmware di lokasi tetap dalam memori program, kemudian menulis sebuah program yang membuat file HEX serial dari file HEX template. Ini semua adalah hal yang mudah dilakukan.
Dalam produksi, Anda menjalankan program bersambung satu kali setelah semua tes lulus. Itu membuat file HEX sementara dengan nomor seri unik, yang akan diprogram ke dalam PIC, kemudian file HEX sementara dihapus.
Saya tidak akan membiarkan lokasi dipindahkan, kemudian harus menemukannya. Itu dapat mengubah setiap bangunan saat tautan bergerak. Saya telah melakukannya untuk PIC yang sangat kecil seperti seri 10F di mana konstanta ini adalah bagian dari instruksi MOVLW. Dalam kasus-kasus itu saya minta baca file MAP dengan cepat untuk menentukan di mana lokasi tersebut. Saya memiliki kode parsing file MAP MPLINK di perpustakaan hanya untuk tujuan itu.
Untuk meletakkan sesuatu di lokasi tetap, tentukan segmen pada alamat tetap. Linker akan menempatkan segmen absolut seperti itu terlebih dahulu, kemudian yang relocatable di sekitarnya. Jangan lupa untuk menggunakan CODE_PACK alih-alih hanya CODE pada PIC 18, kalau tidak Anda akan berurusan dengan kata-kata instuksi keseluruhan alih-alih byte individu. Misalnya (cukup mengetik, tidak berjalan melewati assemlber):
sumber
Saya sarankan menyimpan nomor seri di alamat tetap. Bergantung pada kompiler / tautan Anda dan bagian yang dimaksud, ada beberapa pendekatan yang dapat Anda ambil:
sumber
retlw
pendekatannya seringkali jauh lebih cepat (pada PIC 18-bit, acall
ke aretlw
membutuhkan empat siklus total; menggunakanclrf TBLPTRU/movlw xx/movwf TBLPTRH/movlw xx/movwf TBLPTRL/tblrd *+/movf TABLAT,w
akan membutuhkan delapan).Saya akan melakukan yang sebaliknya: kompilasi dan tautkan kode, lalu cari tahu di mana nilai disimpan dari file linker. Anda mungkin perlu menemukan variabel secara eksplisit di segmen yang dipetakan ke flash.
Jangan meminta ini, tetapi perangkat lunak PC yang saya berikan untuk programmer Wisp648 saya memiliki kemampuan untuk membaca file .hex, memodifikasi lokasi tertentu, dan menulis file .hex kembali (ke file yang sama atau yang lain). Tidak perlu ada programmer saya hadir. Sumber tersedia (dalam Python), lisensi memungkinkan semua penggunaan: www.voti.nl/xwisp Mungkin berguna setelah Anda menyelesaikan masalah utama Anda.
sumber