Harici RAM'den çalıştırmak için kod derleme


13

PIC18F85J5'e dayanan minimalist bir oyun sistemi için tasarımları düşünüyorum. Tasarımımın bir kısmı, oyunların çipi yeniden programlanmadan veya program belleğini yanıp sönmeden bir SD karttan yüklenebilmesidir. Bu yongayı seçtim çünkü harici bir SRAM'den kod çalıştırmamı sağlayacak harici bir bellek arayüzü var.

Temel fikir, dahili program belleğinin sd karta göz atmak için bir arabirim içermesi ve kullanıcı bir programı seçtikten sonra, onaltılık bir dosyayı sd karttan harici ram'a kopyalayıp yürütmeyi harici ram alanına atlamasıdır. .

Dahili program hafızasında ayrıca grafikler, denetleyici girişi ve diğer çeşitli yardımcı programlar için çeşitli kütüphaneler bulunur.

Dahili bellenim parçalarının nasıl iyi çalışacağını bildiğime oldukça eminim. Sorun, harici RAM'den çalıştırılacak programlar oluşturmaktır. Normal bir resmi hedeflemekle aynı şey hissetmez ve dahili bellekte bulunan, ancak bunları yeniden derlemeyen kütüphane işlevlerinin farkında olması gerekir, yalnızca bunlara bağlanır. Ayrıca, 32k dahili flaştan hemen sonra adresleri kullanmaya başlamalı, sıfırda değil. Bu tür kısıtlamaları kullanarak bir programı derlemenin iyi bir yolu var mı?

MPLab IDE kullanıyorum, ancak bu tür bir özelleştirmeyi nasıl yapacağımı çok iyi bilmiyorum.


Bir süredir burada gördüğüm en iyi sorulardan biri ... Fikir ve cevapları duymayı dört gözle bekliyorum.
Jon L

Bazı ilginç alternatif yaklaşımlar electronics.stackexchange.com/questions/5386/… '
Toby Jaffey

Bunu gördüm, ama çoğunlukla kaçınmak istediğim flaş yazmayı tavsiye ediyorlar. Donanım tasarımım, kabul edilen yanıttaki uygulama notundaki şekil 6'ya benzeyecektir.
captncraig

Yanıtlar:


8

İki ayrı sorununuz var:

  1. Harici RAM adres aralığı için kod oluşturma.

    Bu aslında çok kolay. Tek yapmanız gereken, kodun işgal etmesini istediğiniz adres aralıklarını içeren bir bağlayıcı dosyası oluşturmaktır. Sadece bu harici uygulamalar için belirli bir program belleği adres aralığı ayırmanızın yanı sıra bazı RAM alanı ayırmanız gerektiğini unutmayın. Program belleği adresleri gibi bu RAM alanının da düzeltilmesi ve bilinmesi gerekir. Yalnızca sabit ve bilinen adres aralıklarını bağlayıcı dosyasında kullanılabilir hale getirin. Bunları temel kod bağlayıcı dosyasında KULLANMAYIN.

    Temel kod harici bir belleğe yeni bir uygulama yükledikten sonra, nasıl çalıştırılacağını bilmek zorundadır. En kolay şey muhtemelen yürütmenin ilk harici RAM konumunda başlatılmasıdır. Bu, kodunuzun mutlak başlangıç ​​adresinde bir KOD bölümüne ihtiyacı olacağı anlamına gelir. Bu, kodun geri kalanında yer alan ve tümü yeniden konumlandırılabilecek bir GOTO içerir.

  2. Uygulamaları temel koddaki kütüphane rutinlerine bağlama.

    Mevcut Microchip araçlarıyla bunu yapmanın hemen basit bir yolu yok, ama o kadar da kötü değil.

    Çok daha büyük bir sorun, temel kod değişiklikleriyle nasıl başa çıkmak istediğinizdir. Basit strateji, temel kodunuzu oluşturmak, genel adresleri toplamak için ortaya çıkan harita dosyası üzerinde bir program çalıştırmak, ardından tüm global olarak tanımlanmış semboller için EQU ifadeleri içeren bir içe aktarma dosyası yazmasını sağlamaktır. Bu içe aktarma dosyası daha sonra tüm uygulama koduna dahil edilir. Uygulama kaynak kodu temelde temel kod giriş noktalarına sabit adres referanslarını içerdiğinden, bağlantı kurulacak hiçbir şey yoktur.

    Bunu yapmak kolaydır ve çalışır, ancak temel kodu değiştirdiğinizde ne olacağını düşünün. Küçük bir hata düzeltmesi bile tüm adreslerin hareket etmesine neden olabilir ve ardından mevcut tüm uygulama kodu iyi olmaz ve yeniden oluşturulması gerekir. Asla tüm uygulamaları güncellemeden temel kod güncellemeleri sağlamayı planlamıyorsanız, belki de bununla kurtulabilirsiniz, ancak bunun kötü bir fikir olduğunu düşünüyorum.

    Daha iyi bir yol, temel kodda seçilen bir sabit bilinen adreste tanımlı bir arayüz alanına sahip olmaktır. Uygulama kodunun çağırabileceği her altyordam için bir GOTO olacaktır. Bu GOTO'lar bilinen bilinen adreslere yerleştirilecek ve harici uygulamalar yalnızca bu konumlara çağrı yapacak ve bu da alt programın temel kodun bu yapısında sonlandığı yere atlayacaktır. Bu, dışa aktarılan altyordam başına 2 program belleği kelimesine ve çalışma zamanında iki ekstra döngüye mal olur, ancak bence buna değer.

    Bu hakkı yapmak için, GOTO'ları oluşturma işlemini ve harici uygulamaların alt program (aslında GOTO yeniden yönlendirici) adreslerini almak için içe aktarılacağı dışa aktarma dosyasını otomatikleştirmeniz gerekir. MPASM makrolarının bazı akıllıca kullanımlarıyla ilgili olabilirsiniz, ancak bunu yapsaydım, önişleme sırasında harici bir dosyaya yazabildiğinden kesinlikle önişlemcimi kullanırdım. Her yeniden yönlendiricinin tek bir kaynak kodu satırı ile tanımlanabilmesi için bir önişlemci makrosu yazabilirsiniz. Makro, gerçek hedef yordamın dış referansı olan GOTO'yu oluşturmak ve bu rutinin bilinen sabit adresiyle birlikte tüm uygun adlarla dışa aktarma dosyasına uygun satırı eklemek için başlık altındaki tüm kötü şeyleri yapar. Belki de makro, normal adlara sahip bir grup önişlemci değişkeni yapar (çalışma zamanı genişletilebilir dizi gibi bir tür) ve ardından dışa aktarma dosyası tüm makro çağrılarından sonra bir kez yazılır. Ön işlemcimin MPASM makrolarının yapamayacağı birçok şeyden biri, diğer adlardan yeni sembol adları oluşturmak için dize manipülasyonu yapmaktır.

    Önişlemcim ve bir dizi diğer ilgili şey www.embedinc.com/pic/dload.htm adresinden ücretsiz olarak edinilebilir .


Sabit bir atlama masası fikrini gerçekten seviyorum. Flaş belleğin sonundan başlayabilir ve her sistem çağrısı için sabit konumlara sahip olabilirim. Açıkladığınız tüm bu önişlemci voodoo anlayamıyorsam, muhtemelen tüm alt yordamların adresleri ile elle tutulan bir başlık dosyası ile kurtulmak olabilir.
captncraig

5

Seçenek 1: Yorumlanan Diller

Bu doğrudan soruyu cevaplamıyor (bu mükemmel bir soru, BTW ve doğrudan doğruya cevap veren bir cevaptan öğrenmeyi umuyorum), ancak harici programları yazmak için harici programlar yükleyebilen projeler yaparken çok yaygındır. yorumlanmış bir dil. Kaynaklar sıkıysa (bu işlemcide olacaklar, bunun için bir PIC32 veya küçük ARM işlemcisi kullanmayı düşündünüz mü?), Dili tam spesifikasyonun bir alt kümesiyle sınırlamak yaygındır. Zincirin daha da ötesinde, sadece birkaç şey yapan etki alanına özgü diller vardır.

Örneğin, elua projesi düşük kaynaklı (64 kB RAM) yorumlanmış dil örneğidir. Bazı özellikleri kaldırırsanız bunu 32k RAM'e kadar sıkıştırabilirsiniz (Not: 8-bit mimari olan mevcut işlemcinizde çalışmaz. Harici RAM kullanmak muhtemelen grafikler için çok yavaş olacaktır). En az API sağlarsanız yeni kullanıcıların oyunları kolayca programlayabileceği hızlı ve esnek bir dil sağlar. Çevrimiçi dil için birçok doküman mevcut. Benzer bir şekilde kullanabileceğiniz diğer diller (Forth ve Basic gibi) vardır, ancak şu anda Lua'nın en iyi seçenek olduğunu düşünüyorum.

Benzer bir şekilde, alana özgü kendi dilinizi oluşturabilirsiniz. Daha kapsamlı bir API ve harici belgeler sağlamanız gerekir, ancak oyunların hepsi benzer olsaydı bu çok zor olmazdı.

Her durumda, PIC18 muhtemelen özel programlama / komut dosyası ve grafik içeren bir şey için kullanacağım işlemci değil. Bu işlemci sınıfına aşina olabilirsiniz, ancak bunun bir ekran sürücüsü ve daha fazla bellek ile bir şey kullanmak için iyi bir zaman olacağını öneririm.

2. Seçenek: Sadece her şeyi yeniden programlayın

Bununla birlikte, zaten tüm oyunları C'de programlamayı planlıyorsanız, sadece SD karttan oyun mantığını yüklemekle uğraşmayın . Yeniden programlamak için sadece 32kB Flash'a sahipsiniz ve bunun için kolayca 4 GB microSD kart alabilirsiniz. (Not: daha büyük kartlar genellikle SDHC'dir, bu da arayüzle daha zordur). 32 kB'nizin her son baytını kullandığınızı varsayarsak, SD kartta, ihtiyacınız olan herhangi bir oyun mantığına sahip yazılımınızın 131.072 kopyası için yer kalır.

AN851 gibi PIC'ler için önyükleyici yazmak için birçok uygulama vardır . Önyükleyicinizi belirli bir bellek bölgesini kaplayacak şekilde tasarlamanız gerekir (muhtemelen bellek bölgesinin en üstünde, bunu bağlayıcıda belirtirsiniz) ve tam bellenim projelerinin bu bölgeye ulaşmadığını belirtmeniz gerekir. Appnote bunu daha ayrıntılı olarak açıklıyor. Sadece "PIC18F452'nin önyükleme bölümünü" "bağlayıcıda belirttiğim önyükleme bölümünü" ile değiştirin ve hepsi anlamlı olacaktır.

Ardından, önyükleyicinizin kullanıcının SD karttan çalışacak bir program seçmesine ve her şeyi kopyalamasına izin vermesi yeterlidir. Kullanıcı arabirimi, kullanıcının seçim moduna girmek için bir düğmeyi basılı tutması olabilir. Normalde, önyükleyici sıfırlama sırasında bu düğmenin durumunu kontrol eder ve basılı tutulmuyorsa oyuna önyükleme yapar. Basılı tutulursa, kullanıcının SD kartta bir dosya seçmesine, programı kopyalamasına ve [yeni] oyuna önyüklemeye devam etmesine izin vermesi gerekir.

Bu benim şu anki tavsiyem.

Seçenek 3: Onaltılık dosyanın yalnızca bir bölümünü depolamayı içeren derin sihir

Öngörülen mekanizmanızla ilgili sorun, işlemcinin API'ler ve işlev çağrıları ile ilgilenmemesi , komut işaretçisinin atlayabileceği sayılarla ilgilenmesi ve bir API spesifikasyonuna göre bir işlev çağrısı yürüten kod olmasını beklemesidir. Programın sadece bir bölümünü derlemeye çalışırsanız, linker check_button_status()veya aradığınızda ne yapacağını bilemez toggle_led(). Bu işlevlerin işlemci üzerindeki hex dosyasında bulunduğunu biliyor olabilirsiniz, ancak tam olarak hangi adreste bulunduklarını bilmeleri gerekir.

Bağlayıcı, kodunuzu zaten birden çok bölüme ayırıyor; teorik olarak bunu bazı -sectionve #pragmabüyülerle ek bölümlere ayırabilirsiniz. Bunu hiç yapmadım ve nasıl yapacağımı bilmiyorum. Yukarıdaki iki yöntem başarısız olana kadar (ya da burada harika bir cevap gönderene kadar), muhtemelen bu mekanizmayı öğrenmeyeceğim ve bu yüzden size öğretemiyorum.


2 numaraya itirazım, flash belleğin çip ömrü boyunca sınırlı sayıda silme döngüsüne sahip olmasıdır. Daha sert bir mcu kullanmak istemiyorum çünkü 8 bitlik minimalizm için gidiyorum.
captncraig

@CMP - En az 10.000 silme döngüsü vardır. Birisi her gün farklı bir oyun oynarsa, 2039 yılına kadar sürecek. Flash neredeyse devrenin geri kalanından daha uzun süre dayanacaktır. Her gün onlarca kez oynanacak bir arcade'ye gitmedikçe, bu konuda endişelenmeniz gerektiğini düşünmüyorum.
Kevin Vermeer

1
İkincisi, 8 bit minimalizm harika görünebilir, ancak programlama için berbat. İşlemcinizin sınırlarını zorladığınız için sağlam bir mikro denetleyici almak ve retro görünmesini sağlamak daha zor görünmekten çok daha kolaydır.
Kevin Vermeer

1
Her ikisi de çok adil noktalar. Düşük parça sayısı için bile olsa, bir pic32 maliyet veya harici bileşenlerde olduğundan daha farklı değildir ve 512K dahili flaşı varsa bile kazanır.
captncraig

Pratik bir çözüm, bir pic32 kullanmak ve sd karttan geri tepmek için bir bootloader yazmak gibi görünüyor. Hem bootloader hem de kullanıcı kodunun ihtiyaç duyduğu işlevleri yeniden kullanmakta zorlanıyordum, ancak 12k önyükleme flaşında tuttuğum sürece, kullanıcı koduna tüm çipi vermeli ve kaynakta istedikleri kütüphaneleri içerebilir seviyesi.
captncraig
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.