2008-10-11 9 views
2

La question que je me pose est la suivante: lorsque j'utilise mon application avec un code de lancement autre que sysAppLaunchCmdNormalLaunch, je ne peux pas utiliser de code en dehors du segment de code par défaut. bibliothèque qui est multi-segmentée, contournant ainsi ce problème? Un peu d'information de fond: J'évalue la possibilité de porter une application mobile existante à PalmOS. Une partie essentielle de cette application est qu'elle effectue une communication réseau en arrière-plan toutes les 10 minutes environ, ou lorsqu'elle reçoit des données entrantes (via un rappel réseau/socket). Pendant ce temps, je n'ai pas accès aux globals et donc pas aux segments de code dans mon application autre que celui par défaut. Le problème est maintenant que les actions impliquées dans la communication (protocole, traitement des données, etc.) nécessitent beaucoup de code qui ne tient pas dans un segment. Mis à part la question de savoir s'il est logique d'avoir autant de code dans le contexte, le problème évident est: comment le gérerais-je en premier lieu? D'où la question, si le code dans une bibliothèque partagée (multi-segment) aiderait.Application/bibliothèque PalmOS multi-segmentée en "arrière-plan"

Dans l'attente de vos idées.

Répondre

2

Je n'ai pas l'habitude d'utiliser des bibliothèques partagées, mais nous avons rencontré ce problème avec notre logiciel, et nous avons rencontré trois différentes manières de résoudre le problème.

Peut-être le plus simple est d'activer le mode étendu en utilisant le compilateur Metrowerks, mais je ne suis pas complètement certain que cela fonctionne. Ce mode spécial vous permet d'accéder à certaines données globales constantes lors d'un appel à partir d'un lancement non global. Cependant, il y a beaucoup de mises en garde à l'utilisation de cette approche. De plus, je n'ai pas confirmé que le mode étendu permet des sauts inter-segments à coup sûr. Il y a un livre blanc écrit par Ben Combee qui explique en détail comment utiliser le mode étendu. Il s'intitule "Prise en charge du mode étendu sur Palm OS". Je ne pouvais pas le trouver sur le web, donc j'ai mis une copie sur mon site:

Une autre option plus compliquée est de charger les globals vous même et de les placer dans A5. Pour ce faire, vous devez modifier (ou dupliquer) le code de démarrage de Metrowerks qui charge les globals, puis appeler ce code modifié lorsque vous recevez un lancement non global. Metrowerks inclut la source complète de cette partie de l'exécution, donc vous pouvez le faire assez facilement, même si une partie de ce code est assez mystérieux. Nous avons utilisé avec succès cette technique dans une version de Pocket Tunes pour accéder à des globals et à un nombre illimité de segments quand ils sont appelés à partir d'un code de lancement non global. Assurez-vous simplement de restaurer A5 en revenant du code de lancement.

La dernière option consiste à déplacer tout (ou une partie) du code dans PNOlets. Cela peut être pénible parce que vous devez segmenter votre code en 68K et PNO, ce qui peut rapidement devenir un cauchemar à maintenir. Nous avons également utilisé cette méthode avec succès, mais la maintenance du code d'interfonctionnement était horrible. Nous avons finalement fini par déplacer notre code entier vers un PNOlet en utilisant le chargeur PEAL, ce qui fonctionne très bien pour les gros codes car il segmente automatiquement le code en morceaux de 64 Ko et exécute le code ARM sur place. Cependant, c'est un très gros effort car le développement de PNOlet n'est pas bien supporté sur ARM, donc vous devez fournir vous-même beaucoup de support de bas niveau (comme des thunks pour appeler chaque fonction de l'API).

+0

Merci pour cette excellente idée. Je pensais à utiliser PNOlets mais malheureusement les délais pour ce projet sont trop serrés pour faire beaucoup d'expérimentation. Cependant PEAL a l'air très intéressant! J'allais aussi utiliser PODS (ou gcc), donc le mode étendu de CW ne va probablement pas m'aider ;-) – Steven

+0

Bonne réponse, Tim ... mieux que ce que j'aurais écrit! –

0

Stockez un pointeur sur une structure volumineuse que vous allouez avec MemPtr dans la mémoire Ftr à l'aide de FtrSet. Cela peut être récupéré n'importe où dans votre application qui a besoin d'un accès global en utilisant FtrGet.

Utilisez alternativement __STANDALONE_CODE_RESOURCE__ pour placer chaque fonction dans un segment de code séparé et utilisez une fonction.c partagée avec des wrappers pour les charger et les verrouiller dans la mémoire pour les appeler.

//segment 1000 

UInt32 foobar(char* hi) 
{ 
    return 12; 
} 

// functions.c 
typedef (UInt32)(*fooPtr)(char*); // this is now a type representing a pointer to your function. 
UInt32 foobar(char* hi) 
{ 
    LocalID id; UInt16 cn; SysCurAppDatabase(&cn,&id); 
    DmOpenRef ref = DmOpenDatabase (cn, id, dmModeReadOnly); 
    MemHandle H = DmGetResource('code',1000); 
    fooPtr code = MemHandleLock(H); 
    UInt32 result = (*fooPtr)(hi); 

    return result; 
} 
+0

vous devez déverrouiller cette poignée lorsque vous avez terminé, ohbtw. MemHandleUnlock (H); – PhrkOnLsh