Мультисегментированное приложение / библиотека PalmOS в фоновом режиме - PullRequest
2 голосов
/ 11 октября 2008

у меня возникает вопрос: при запуске моего приложения с кодом запуска, отличным от sysAppLaunchCmdNormalLaunch, я не могу использовать код вне сегмента кода по умолчанию, но могу ли я использовать разделяемую библиотеку с несколькими сегментами, что позволяет обойти эту проблему

Немного справочной информации: я оцениваю возможность портирования существующего мобильного приложения на PalmOS. Основная часть этого приложения состоит в том, что оно выполняет сетевое взаимодействие в фоновом режиме каждые 10 минут или около того, или когда оно получает входящие данные (через обратный вызов сети / сокета). В течение этого времени у меня нет доступа к глобальным переменным и, следовательно, к каким-либо сегментам кода в моем приложении, кроме сегмента по умолчанию.

Проблема сейчас заключается в том, что действия, связанные с обменом данными (протокол, обработка данных и т. Д.), Требуют большого количества кода, который просто не помещается в один сегмент. Помимо вопроса о том, имеет ли смысл запускать столько кода в фоновом режиме, очевидна проблема: как бы я его запустил? Отсюда вопрос, поможет ли помещение кода в разделяемую (многосегментную) библиотеку.

Ждем ваших идей.

Ответы [ 2 ]

2 голосов
/ 12 октября 2008

У меня нет опыта использования общих библиотек, но у нас была эта проблема с нашим программным обеспечением, и мы нашли три различных способа решения этой проблемы.

Возможно, проще всего включить расширенный режим при использовании компилятора Metrowerks, но я не совсем уверен, что это работает. Этот специальный режим позволяет вам получать доступ к определенным постоянным глобальным данным при вызове из неглобального запуска. Тем не менее, есть много предостережений при использовании этого подхода. Кроме того, я не подтвердил, что расширенный режим разрешает межсегментные переходы наверняка. Там есть белая книга, написанная Беном Комби, которая подробно объясняет, как использовать расширенный режим. Он называется «Поддержка расширенного режима в Palm OS». Я не смог найти его в Интернете, поэтому я разместил копию на своем сайте: http://www.normsoft.com/tim/technical/Codewarrior_Expanded_Mode.pdf

Другим более сложным вариантом является загрузка глобалов самостоятельно и указатель на них в A5. Чтобы сделать это, вы должны изменить (или продублировать) код запуска Metrowerks, который загружает глобальные переменные, а затем вызвать этот измененный код при получении неглобального запуска. Metrowerks включает полный исходный код этой части среды выполнения, поэтому вы можете сделать это довольно легко, хотя часть этого кода довольно загадочна. Мы успешно использовали эту технику в одной версии Pocket Tunes для доступа к глобальным и неограниченному количеству сегментов при вызове из неглобального кода запуска. Обязательно восстановите A5 при возврате из кода запуска.

Последний вариант - переместить весь (или часть) код в PNOlets. Это может быть проблемой, потому что вы должны сегментировать свой код в 68K и PNO, что может быстро стать кошмаром для обслуживания. Мы также успешно использовали этот метод, но поддержка кода взаимодействия была ужасной. В итоге мы переместили весь наш код в PNOlet с помощью загрузчика PEAL, который действительно хорошо работает с большим кодом, поскольку он автоматически сегментирует код на куски по 64 КБ и запускает код ARM на месте. Однако это очень большое усилие, потому что разработка PNOlet не очень хорошо поддерживается в ARM, поэтому вы должны самостоятельно обеспечить большую низкоуровневую поддержку (например, громкие вызовы для вызова каждой функции API).

1 голос
/ 27 мая 2009

Сохраните указатель на красивую большую структуру, которую вы выделяете с помощью MemPtr в памяти Ftr с помощью FtrSet. Это можно найти в любом месте вашего приложения, которому необходим глобальный доступ с помощью FtrGet.

Альтернативно используйте __STANDALONE_CODE_RESOURCE__ для помещения каждой функции в отдельный сегмент кода и используйте общий файл functions.c с обертками для загрузки и блокировки их в памяти для вызова.

//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;
}
...