2010-03-17 7 views
1

J'ai un environnement de vérification basé sur verilog pour puce basée sur ARM. Je dois écrire de nouveaux tests en C++ pour vérifier un périphérique. J'ai tous les outils GCC basés sur ARM en place. Je ne sais pas comment faire un registre de périphérique particulier visible dans le test basé sur C++. Je veux écrire dans ce registre, je veux attendre l'interruption du périphérique et ensuite vouloir lire l'état d'un autre registre de périphérique.Vous voulez configurer un registre de périphérique particulier dans la puce basée sur ARM9

Je voudrais savoir comment cela peut-il être fait? De quelle documentation d'ARM devrais-je me référer? J'ai essayé et trouver toutes les documentations sont pour les développeurs système J'ai besoin des informations de base. Cordialement Manish

Répondre

2

Vous finalement si ne voulez pas immédiatement l'ARM ARM (oui ARM deux fois, une fois pour ARM le second pour Manuel de référence d'architecture, vous pouvez google et trouver gratuitement en téléchargement). Deuxièmement, vous voulez le TRM, Manuel de référence technique pour le noyau spécifique de votre puce. ARM ne fabrique pas de puces, il fait des cœurs de processeur que d'autres personnes mettent dans leurs puces afin que la société qui a la puce peut ou non avoir le TRM inclus dans leur documentation. Si vous avez un noyau de bras dans Verilog alors je suppose que vous l'avez acheté et cela signifie que vous avez le TRM spécifique pour le noyau spécifique que vous avez acheté disponible, plus tout add ons (comme un cache par exemple).

Vous pouvez prendre ceci avec un grain de sel mais j'ai fait ce que vous faites depuis de nombreuses années (test en simulation et plus tard sur la vraie puce) maintenant et ma préférence est d'écrire mon code C comme si ça allait être exécuté embarqué sur le bras. Eh bien dans ce cas, peut-être que vous courez embarqué sur le bras.

Au lieu de quelque chose comme ceci:


#define SOMEREG (*(volatile unsigned int *)0X12345678) 

puis dans votre code


SOMEREG = 0xabc; 

ou


somevariable = SOMEREG; 
somevariable |= 0x10; 
SOMEREG = somevariable; 

Mon code C utilise des fonctions externes.


extern unsigned int GET32 (unsigned int address); 
extern void PUT32 (unsigned int address, unsigned int data); 

somevariable = GET32(0x12345678); 
somevariable|=0x10; 
PUT32(0x12345678,somevariable); 

Lors de l'exécution sur la puce ou de la simulation:


.globl PUT32 
PUT32: 
    str r1,[r0] 
    bx lr ;@ or mov pc,lr depending on architecture 
.globl PUT16 
PUT16: 
    strh r1,[r0] 
    bx lr 
.globl GET32 
GET32: 
    ldr r0,[r0] ;@ I know what the ARM ARM says, this works 
    bx lr 
.globl GET16 
GET16 
    ldrh r0,[r0] 
    bx lr 

Dites que vous nommez le fichier, il putget.s

 
arm-something-as putget.s -o putget.o 

redirigent ensuite dans putget.o avec vos objets C/C++.

J'ai eu gcc et à peu près tous les autres compilateurs ne parviennent pas à faire fonctionner le truc * volatile à 100%, généralement juste après que vous libérez votre code aux gens de fabrication pour prendre vos tests et les exécuter sur le produit échoue et vous devez arrêter la production et ré-écrire ou re-régler un tas de code pour obtenir le compilateur pas à nouveau confus. L'approche de la fonction externe a fonctionné à 100% sur tous les compilateurs, le seul inconvénient est la performance lors de l'exécution intégrée, mais les avantages de l'abstraction sur toutes les interfaces et les systèmes d'exploitation vous en revient. Je suppose que vous faites l'une des deux choses, soit vous exécutez du code sur le bras simulé en essayant de parler à quelque chose lié au bras simulé.Finalement, je suppose que le code va le faire, donc vous aurez à entrer dans les outils et les problèmes de liens, dont il existe de nombreux exemples, certains de mes propres, tout comme la construction d'un compilateur croisé gcc, trivial une fois montré la première fois . Si c'est un périphérique qui sera finalement lié à un bras, mais pour l'instant est en dehors du noyau mais à l'intérieur du design, ce qui signifie qu'il est mappé avec la mémoire et est lié à l'interface de mémoire des bras (amba, axi, etc). Pour le premier cas où vous devez surmonter l'obstacle intégré, vous devrez créer un code bootable, probablement basé sur rom/flash (en lecture seule) car c'est probablement la façon dont le bras/puce démarrera, traitant les scripts de l'éditeur de liens séparer le rom/ram. Voici mon conseil sur ce que finalement, sinon maintenant, les ingénieurs de matériel voudront simuler le chronométrage de rom, qui est péniblement lent dans la simulation. Compilez votre programme pour exécuter complètement de ram (autre que la table d'exception qui est un sujet distinct), compilez dans un format binaire que vous êtes prêt à écrire un utilitaire ad hoc pour la lecture, elf est facile, ainsi que ihex et srec, aucun aussi facile qu'un simple binaire .bin. Ce que vous voulez finalement faire est d'écrire un assembleur qui démarre sur le prom/flash virtuel, active le cache d'instructions (s'il a implémenté et fonctionne en simulation, sinon attendez sur cette étape) utilise les instructions ldm amd stm une boucle pour copier autant de mots à la fois que vous le pouvez pour ram, puis branchez à ram. J'ai un utilitaire basé sur l'hôte qui prend le fichier .bin crée un programme assembleur qui inclut l'assembleur qui copie le binaire à ram et intègre le binaire lui-même en tant que .words dans l'assembleur, puis assembler et lier ce programme à un format que la simulation peut utilisation. Ne laissez pas les ingénieurs du matériel vous convaincre que vous devez reconstruire le verilog à chaque fois, vous pouvez utiliser un $ readmemh() ou quelque chose de ce genre dans verilog pour lire un fichier à l'exécution et ne pas avoir à re-compiler le verilog pour changer le binaire du bras. Vous voudrez écrire un utilitaire basé sur l'hôte ad hoc pour convertir votre fichier .bin ou .elf ou n'importe quoi en un fichier que le verilog peut lire, readmemh est trivial ... Donc je descends sur une tangente, utilisez le put/get Pour parler aux registres, vous devez utiliser le TRM et le ARM ARM pour placer le code du gestionnaire d'interruption quelque part, vous devez activer l'interruption, probablement à plus d'un endroit dans le bras ainsi que dans le périphérique. La beauté de la simulation est que vous pouvez regarder votre code s'exécuter et vous pouvez voir l'interruption quitter le périphérique et déboguer votre code basé sur ce que vous voyez, avec une vraie puce que vous ne savez pas si votre code ne crée pas l'interruption ou si votre le code ne parvient pas à activer l'interruption ou si l'interruption fonctionne mais vous avez fait une erreur dans le gestionnaire d'interruptions, avec un simulateur verilog vous pouvez voir tout cela et vous devriez apprendre à lire les formes d'onde sans compter sur les ingénieurs le faire pour toi. modelsim ou cadence ou quiconque peut enregistrer les formes d'onde au format .vcd et vous pouvez utiliser un outil gratuit nommé gtkwave pour voir les formes d'onde. Ne les laissez pas vous convaincre qu'ils n'ont plus de licences disponibles pour vous de regarder des choses.

Tout cela est secondaire, s'il s'agit d'un processeur hors-ligne mais sur une puce périphérique, alors vous voudrez probablement tester cette logique sans le noyau du bras en premier. Si vous ne connaissez pas verilog, c'est facile, vous devriez juste regarder le code et vous pouvez le comprendre. Les ingénieurs logiciels peuvent le récupérer dans quelques jours ou une semaine s'ils ont déjà l'expérience des langages, en particulier C. De toute façon, l'ingénieur matériel a probablement un banc d'essai pour le périphérique, vous créez ou demandez-leur de créer un banc d'essai avec un registre est similaire à ce que vous verrez une fois connecté au bras, soit directement sur le bus de bras ou sur une interface de banc d'essai qui simplifie le bus de bras. Ensuite, utilisez vpi, qui est moche, mais qui fonctionne (google interface de langue étrangère ainsi que vpi) pour connecter le code C sur la machine hôte exécutant la simulation. Faites la plupart de votre travail en C et verilog en minimisant le cauchemar vpi. Parce que cela est compilé et lié à la simulation dans un sens, vous ne voulez pas avoir à reconstruire la simulation chaque fois que vous voulez changer votre programme de test. Donc, utilisez quelque chose comme des sockets ou une autre interface IPC afin que vous puissiez vous séparer du code vpi. Ensuite, écrivez un code hôte qui implémente put32 et get32 (put8, put16, toutes les fonctions que vous voulez implémenter). alors maintenant vous prenez votre programme de test qui peut fonctionner sur le bras si compilé de cette façon et à la place le compiler sur le perdu en le liant à la couche d'abstraction put/get/any. Vous pouvez maintenant écrire des programmes qui pour l'instant tournent sur l'hôte mais interagissent avec le périphérique en simulation comme s'il s'agissait d'un vrai matériel et comme si vos programmes hôtes étaient des programmes intégrés dans le bras.l'interruption est probablement triviale dans cet environnement car tout ce que vous avez à faire est de le chercher dans les formes d'onde ou d'avoir le code vpi imprime quelque chose sur la console lorsque le signal change d'état ou quelque chose comme ça. Oh, la raison pour laquelle vous copiez de ram vers ram est que, en moyenne, vos temps de simulation seront significativement plus courts, soit cinq et dix minutes au lieu d'heures. simuler le périphérique par lui-même sans le bras en utilisant une interface en langue étrangère pour faire un pont vers/depuis l'hôte, réduit votre temps de sim de cinq minutes à secondes en fonction de ce que vous faites. Si vous utilisez une sorte d'abstraction comme mon put/get vous pouvez écrire votre code périphérique une fois dans un fichier, en le liant de différentes façons qu'un fichier/programme/fonction peut être utilisé avec le perhipheral uniquement en simulation pour développer rapidement votre code, Ensuite, lancez le bras en place en simulation en ajoutant la complexité du système d'interruption des bras et d'interruption des bras, et plus tard sur la vraie puce pendant que vous courez sur la puce simulée. et puis plus tard, ce code peut être utilisé tel quel dans un pilote ou un espace d'application en utilisant mmap, etc.

Questions connexes