1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/openharmony-systemabilitymgr_samgr_lite

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

samgr_lite

Введение

В связи с ограниченными ресурсами платформы предлагается унифицированный фреймворк системных возможностей, который гармонизирует различия архитектур аппаратных средств (например, RISC-V, Cortex-M и Cortex-A), ресурсов платформы и режимов выполнения. Определяются два типа аппаратных платформ (M- и A-ядра).

  • M-ядро: аппаратные платформы с возможностями обработки, эквивалентными Cortex-M или аналогичными. Обычно объем системной памяти составляет менее 512 КБ. Используется легковесная файловая система, применимая в ограниченных сценариях, или вовсе отсутствует файловая система. Платформы M-ядра соответствуют стандарту CMSIS (Cortex Microcontroller Software Interface Standard).
  • A-ядро: аппаратные платформы с возможностями обработки, эквивалентными Cortex-A или аналогичными. Объем системной памяти превышает 512 КБ. Используется полная файловая система для хранения большого объема данных. Платформы A-ядра соответствуют спецификациям POSIX (Portable Operating System Interface).

Этот сервисно-ориентированный фреймворк системных возможностей позволяет разрабатывать сервисы, функции и внешние API, а также реализовывать многопроцессное взаимодействие и вызовы сервисов для межпроцессного взаимодействия (IPC).- M-ядро предоставляет сервисы, функции, внешние API и разработку многопроцессного взаимодействия.

  • В дополнение к возможностям, предоставляемым M-ядром, A-ядро предоставляет возможности, такие как вызовы сервисов IPC, контроль прав доступа для вызовов сервисов IPC и разработку API сервисов IPC.## Архитектура системы

Рис. 1 Сервисно-ориентированная архитектура

  • Поставщик: сервисный поставщик, предоставляющий возможности (внешние API) для системы.
  • Потребитель: сервисный потребитель, вызывающий функции (внешние API), предоставляемые сервисом.
  • Samgr: агент, управляющий возможностями, предоставляемыми поставщиками, и помогающий потребителям находить возможности поставщиков.

Рис. 2 Основные объекты фреймворка системных возможностей

  • SamgrLite: предоставляет регистрацию и обнаружение служб.
  • Service: реализует API жизненного цикла службы во время разработки службы.
  • Feature: реализует API жизненного цикла функции во время разработки функции.
  • IUnknown: реализует внешние API для служб или функций на основе IUnknown.
  • IClientProxy: реализует прокси-клиента для отправки сообщений во время вызова IPC.
  • IServerProxy: реализует прокси-провайдера во время вызова IPC, который должен быть реализован разработчиками.

Структура директорий

Рис. 1 Структура директории исходного кода фреймворка системных возможностей| Имя | Описание | | -------------------------------------------------- | -------------------------------------------- | | interfaces/kits/samgr_lite/samgr | Внешние API фреймворков системных возможностей M- и A-ядра. | | interfaces/kits/samgr_lite/registry | Внешние API для вызова служб между процессами A-ядра. | | interfaces/kits/samgr_lite/communication/broadcast | Внешние API службы рассылки событий внутри процессов M- и A-ядра. | | services/samgr_lite/samgr/adapter | Слой адаптации POSIX и CMSIS интерфейсов, используемый для гармонизации различий между API M- и A-ядра.| | services/samgr_lite/samgr/registry | Stub-функции для регистрации и обнаружения служб M-ядра. | | services/samgr_lite/samgr/source | Основной код фреймворков системных возможностей M- и A-ядра. | | services/samgr_lite/samgr_client | Регистрация и обнаружение для вызова служб между процессами A-ядра. | | services/samgr_lite/samgr_server | Управление адресами IPC и контроль доступа для вызова служб между процессами A-ядра. | | services/samgr_lite/samgr_endpoint | Управление приемом и передачей пакетов для IPC A-ядра. | | services/samgr_lite/communication/broadcast | Служба рассылки событий для процессов M- и A-ядра. |## Ограничения

  • Фреймворк системных возможностей разработан с использованием языка программирования C.
  • Службы в одном процессе используют IUnknown для вызова. Сообщения передаются службе через IUnknown.
  • Имя службы и имя функциональности должны быть постоянными строками, длина которых должна быть меньше 16 байт.
  • Многоядерное ядро зависит от службы Bootstrap и вызывает функцию OHOS_SystemInit() в функции запуска системы.
  • Ядро A-ядра зависит от библиотеки Samgr и вызывает функцию SAMGR_Bootstrap() в функции main.

Разработка службы

  • Наследуйте и переопределяйте сервис.

    typedef struct ExampleService {
        INHERIT_SERVICE;
        INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
        Identity identity;
    } ExampleService;
  • Реализуйте функции жизненного цикла сервиса.

    static const char *GetName(Service *service)
    {
        return EXAMPLE_SERVICE;
    }
    
    static BOOL Initialize(Service *service, Identity identity)
    {
        ExampleService *example = (ExampleService *)service;
        // Сохраните уникальный идентификатор сервиса, который используется при использовании IUnknown для отправки сообщений сервису.
        example->identity = identity;
        return TRUE;
    }
    
    static BOOL MessageHandle(Service *service, Request *msg)
    {
        ExampleService *example = (ExampleService *)service;
        switch (msg->msgId) {
            case MSG_SYNC:
                // Обрабатывайте сервис.
                break;
            default:break;
        }
        return FALSE;
    }
    
    static TaskConfig GetTaskConfig(Service *service)
    {
        TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL,
                             0x800, 20, SHARED_TASK};
        return config;
    }
    ```-   Создайте объект сервиса.
    

    static ExampleService g_example = { .GetName = GetName, .Initialize = Initialize, .MessageHandle = MessageHandle, .GetTaskConfig = GetTaskConfig, SERVER_IPROXY_IMPL_BEGIN, .Invoke = NULL, .SyncCall = SyncCall, IPROXY_END, };

  • Зарегистрируйте сервис и API с Samgr.

    static void Init(void)
    {
        SAMGR_GetInstance()->RegisterService((Service *)&g_example);
        SAMGR_GetInstance()->RegisterDefaultFeatureApi(EXAMPLE_SERVICE, GET_IUNKNOWN(g_example));
    }
  • Определите инициализатор сервиса.

    SYSEX_SERVICE_INIT(Init);
    

Разработка функции сервиса

  • Наследуйте и переопределяйте функцию.

    typedef struct DemoFeature {
        INHERIT_FEATURE;
        INHERIT_IUNKNOWNENTRY(DemoApi);
        Identity identity;
        Service *parent;
    } DemoFeature;
  • Реализуйте функции жизненного цикла функции.

    ```c
    static const char *FEATURE_GetName(Feature *feature)
    {
        return EXAMPLE_FEATURE;
    }
    
    static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
    {
        DemoFeature *demoFeature = (DemoFeature *)feature;
        demoFeature->identity = identity;
        demoFeature->parent = parent;
    }
    
    static void FEATURE_OnStop(Feature *feature, Identity identity)
    {
        g_example.identity.queueId = NULL;
        g_example.identity.featureId = -1;
        g_example.identity.serviceId = -1;
    }
    
    static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
    {
        if (request->msgId == MSG_PROC) {
            Response response = {.data = "Да, вы это сделали!", .len = 0};
            SAMGR_SendResponse(request, &response);
            return TRUE;
        } else {
            if (request->msgId == MSG_TIME_PROC) {
                LOS_Msleep(WAIT_FEATURE_PROC * 10);
                if (request->msgValue) {
                    SAMGR_PrintServices();
                } else {
                    SAMGR_PrintOperations();
                }
                AsyncTimeCall(GET_IUNKNOWN(g_example));
                return FALSE;
            }
        }
        return FALSE;
    }
  • Создайте объект функции. ``` static DemoFeature g_example = { .GetName = FEATURE_GetName, .OnInitialize = FEATURE_OnInitialize, .OnStop = FEATURE_OnStop, .OnMessage = FEATURE_OnMessage, DEFAULT_IUNKNOWN_ENTRY_BEGIN, .AsyncCall = AsyncCall, .AsyncTimeCall = AsyncTimeCall, .SyncCall = SyncCall, .AsyncCallBack = AsyncCallBack, DEFAULT_IUNKNOWN_ENTRY_END, .identity = {-1, -1, NULL}, };

  • Зарегистрируйте функцию и API с Samgr.

    static void Init(void){
        SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE, (Feature *)&g_example);
        SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
    }
  • Определите инициализатор функции.

    SYSEX_FEATURE_INIT(Init);
    

Разработка внешнего API для межпроцессного взаимодействия

  • Определите API IUnknown.

    typedef struct DemoApi {
        INHERIT_IUNKNOWN;
        BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
        BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
        BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
        BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, Handler handler);
    } DemoApi;
  • Определите объект-ссылку IUnknown.

    typedef struct DemoRefApi {
        INHERIT_IUNKNOWNENTRY(DemoApi);
    } DemoRefApi;
  • Инициализируйте объект IUnknown.

    static DemoRefApi api = {
        DEFAULT_IUNKNOWN_ENTRY_BEGIN,
            .AsyncCall = AsyncCall,
            .AsyncTimeCall = AsyncTimeCall,
            .SyncCall = SyncCall,
            .AsyncCallBack = AsyncCallBack,
        DEFAULT_IUNKNOWN_ENTRY_END,
    };
  • Зарегистрируйте функциональный API.

    SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(api));
    

Вызов сервиса в том же процессе

  • Получите внешний API сервиса. ``` DemoApi *demoApi = NULL; IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE); if (iUnknown == NULL) { return NULL; } int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi); if (result != 0 || demoApi == NULL) { return NULL; }

    if (demoApi->AsyncCallBack == NULL) { return NULL; } demoApi->AsyncCallBack((IUnknown *)demoApi, "Я хочу асинхронный вызов обратного вызова с хорошим результатом!", AsyncHandler);

  • Освободите API.

    int32 ref = demoApi->Release((IUnknown *)demoApi);
    

Разработка внешнего API для IPC

  • Наследуйте IServerProxy для замены IUnknown: INHERIT_SERVER_IPROXY

    typedef struct DemoFeatureApi {
        INHERIT_SERVER_IPROXY;
        BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
        BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
        BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
        BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
    } DemoFeatureApi;
  • Инициализируйте объект IServerProxy.

    static DemoFeature g_example = {
        SERVER_IPROXY_IMPL_BEGIN,
        .Invoke = Invoke,
        .AsyncCall = AsyncCall,
        .AsyncTimeCall = AsyncTimeCall,
        .SyncCall = SyncCall,
        .AsyncCallBack = AsyncCallBack,
        IPROXY_END,
    };
    ```-   Реализуйте функцию **Invoke** для обработки сообщений IPC.```diff

static int32 Вызвать(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *ответ) { DemoFeatureApi *api = (DemoFeatureApi *)iProxy; BOOL ret; size_t len = 0; switch (funcId) { case ID_ASYNCALL: ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len)); IpcIoPushBool(ответ, ret); break; case ID_ASYNTIMECALL: ret = api->AsyncTimeCall((IUnknown *)iProxy); IpcIoPushBool(ответ, ret); break; case ID_SYNCCALL: { struct Payload payload; payload.id = IpcIoPopInt32(req); payload.value = IpcIoPopInt32(req); payload.name = (char *)IpcIoPopString(req, &len); ret = api->SyncCall((IUnknown *)iProxy, &payload); IpcIoPushString(ответ, ret ? "TRUE" : "FALSE"); } break; case ID_ASYNCCALLBACK: { // конвертировать в синхронный прокси IpcIoPushString(ответ, "Да, вы это сделали!"); IpcIoPushBool(ответ, TRUE); } break; default: IpcIoPushBool(ответ, FALSE); break; } return EC_SUCCESS; }


```diff
-   Реализуйте функцию **Invoke** для обработки сообщений IPC.
```diff
static int32 Вызвать(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *ответ)
{
    DemoFeatureApi *api = (DemoFeatureApi *)iProxy;
    BOOL ret;
    size_t len = 0;
    switch (funcId) {
        case ID_ASYNCALL:
            ret = api->AsyncCall((IUnknown *)iProxy, (char *)IpcIoPopString(req, &len));
            IpcIoPushBool(ответ, ret);
            break;
        case ID_ASYNTIMECALL:
            ret = api->AsyncTimeCall((IUnknown *)iProxy);
            IpcIoPushBool(ответ, ret);
            break;
        case ID_SYNCCALL: {
            struct Payload payload;
            payload.id = IpcIoPopInt32(req);
            payload.value = IpcIoPopInt32(req);
            payload.name = (char *)IpcIoPopString(req, &len);
            ret = api->SyncCall((IUnknown *)iProxy, &payload);
            IpcIoPushString(ответ, ret ? "TRUE" : "FALSE");
        }
            break;
        case ID_ASYNCCALLBACK: { // конвертировать в синхронный прокси
            IpcIoPushString(ответ, "Да, вы это сделали!");
            IpcIoPushBool(ответ, TRUE);
        }
            break;
        default:
            IpcIoPushBool(ответ, FALSE);
            break;
    }
    return EC_SUCCESS;
}
```-   Зарегистрируйте API. Этот шаг аналогичен регистрации API для внутрисистемной коммуникации.    ```
    SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE, GET_IUNKNOWN(g_example));
    
    ```


## Вызов сервиса в другом процессе

-   Получите внешний API сервиса в другом процессе.

    ```
    IClientProxy *demoApi = NULL;
    IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
    if (iUnknown == NULL) {
        return NULL;
    }
    int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&demoApi);
    if (result != 0 || demoApi == NULL) {
        return NULL;
    }
    ```

-   Вызовите API для отправки сообщений IPC.

    ```
    IpcIo request;
    char data[250];
    IpcIoInit(&request, data, sizeof(data), 0);
    demoApi->Invoke(demoApi, 0, &request, NULL, NULL);
    ```

-   Освободите API.

    ```
    int32 ref = demoApi->Release((IUnknown *)demoApi);
    
    ```


## Разработка клиентского прокси для вызова сервиса между процессами

-   Определите клиентский прокси для API IPC.

    ```
    typedef struct DemoClientProxy {
        INHERIT_CLIENT_IPROXY;
        BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
        BOOL (*AsyncTimeCall)(IUnknown *iUnknown);
        BOOL (*SyncCall)(IUnknown *iUnknown, struct Payload *payload);
        BOOL (*AsyncCallBack)(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler);
    } DemoClientProxy;
    typedef struct DemoClientEntry {
        INHERIT_IUNKNOWNENTRY(DemoClientProxy);
    } DemoClientEntry;
    ```-   Активируйте клиентский прокси для упаковки API сообщений IPC.

```markdown
     ```
      static BOOL AsyncCall(IUnknown *iUnknown, const char *buff)
      {
          DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
          IpcIo request;
          char data[MAX_DATA_LEN];
          IpcIoInit(&request, data, MAX_DATA_LEN, 0);
          IpcIoPushString(&request, buff);
          int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCALL, &request, NULL, NULL);
          return ret == EC_SUCCESS;
      }
       static BOOL AsyncTimeCall(IUnknown *iUnknown)
      {
          DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
          IpcIo request;
          char data[MAX_DATA_LEN];
          IpcIoInit(&request, data, MAX_DATA_LEN, 0);
          int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNTIMECALL, &request, NULL, NULL);
          return ret == EC_SUCCESS;
      }
       static int Callback(IOwner owner, int code, IpcIo *reply)
      {
          size_t len = 0;
          return strcpy_s(owner, MAX_DATA_LEN, (char *)IpcIoPopString(reply, &len));
      }
       static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload)
      {
          DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
          IpcIo request;
          char data[MAX_DATA_LEN];
          IpcIoInit(&request, data, MAX_DATA_LEN, 0);
          IpcIoPushInt32(&request, payload->id);
          IpcIoPushInt32(&request, payload->value);
          IpcIoPushString(&request, payload->name);
          int ret = proxy->Invoke((IClientProxy *)proxy, ID_SYNCCALL, &request, data, Callback);
          data[MAX_DATA_LEN - 1] = 0;
          HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Remote response is %s!  ", pthread_self(), data);
          return ret == EC_SUCCESS;
      }
       struct CurrentNotify {
          IOwner notify;
          INotifyFunc handler;
      };
       static int CurrentCallback(IOwner owner, int code, IpcIo *reply)
      {
          struct CurrentNotify *notify = (struct CurrentNotify *)owner;
          size_t len = 0;
          char *response = (char *)IpcIoPopString(reply, &len);
          HILOG_INFO(HILOG_MODULE_APP, "[TID:0x%lx]Notify Remote response is %s!  ", pthread_self(), response);
          notify->handler(notify->notify, response);
          return EC_SUCCESS;
      }
       static BOOL AsyncCallBack(IUnknown *iUnknown, const char *buff, IOwner notify, INotifyFunc handler)
      {
```         struct CurrentNotify owner = {notify, handler};
          DemoClientProxy *proxy = (DemoClientProxy *)iUnknown;
          IpcIo request;
          char data[MAX_DATA_LEN];
 ```        IpcIoInit(&request, data, MAX_DATA_LEN, 0);
          IpcIoPushString(&request, buff);
          int ret = proxy->Invoke((IClientProxy *)proxy, ID_ASYNCCALLBACK, &request, &owner, CurrentCallback);
          return ret == EC_SUCCESS;
      }
      ```- Реализуйте фабричный метод для создания прокси-клиента.    ```
    void *DEMO_CreatClient(const char *service, const char *feature, uint32 size)
    {
        (void)service;
        (void)feature;
        uint32 len = size + sizeof(DemoClientEntry);
        uint8 *client = malloc(len);
        (void)memset_s(client, len, 0, len);
        DemoClientEntry *entry = (DemoClientEntry *)&client[size];
        entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
        entry->ref = 1;
        entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
        entry->iUnknown.AddRef = IUNKNOWN_AddRef;
        entry->iUnknown.Release = IUNKNOWN_Release;
        entry->iUnknown.Invoke = NULL;
        entry->iUnknown.AsyncCall = AsyncCall;
        entry->iUnknown.AsyncTimeCall = AsyncTimeCall;
        entry->iUnknown.SyncCall = SyncCall;
        entry->iUnknown.AsyncCallBack = AsyncCallBack;
        return client;
    }
    void DEMO_DestroyClient(const char *service, const char *feature, void *iproxy)
    {
        free(iproxy);
    }
    ```

- Зарегистрируйте фабричный метод прокси-клиента в Samgr.

    ```
    SAMGR_RegisterFactory(EXAMPLE_SERVICE, EXAMPLE_FEATURE, DEMO_CreatClient, DEMO_DestroyClient);
    ```

- Получите внешний API службы в другом процессе.

    ```
    DemoClientProxy *demoApi = NULL;
    IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(EXAMPLE_SERVICE, EXAMPLE_FEATURE);
    if (iUnknown == NULL) {
        return NULL;
    }
    int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
    if (result != 0 || demoApi == NULL) {
        return NULL;
    }
    ```

- Вызовите API прокси-клиента службы в другом процессе.

    ```
    if (demoApi->AsyncCallBack == NULL) {
        return NULL;
    }
    demoApi->AsyncCallBack((IUnknown *)demoApi,
                           "Хочу асинхронный вызов обратного вызова с хорошим результатом!", NULL, AsyncHandler);
    ```

- Освободите API.

    ```
    int32 ref = demoApi->Release((IUnknown *)demoApi);
    ```


## Вовлечённые репозитории

Samgr

[**systemabilitymgr\_samgr\_lite**](https://gitee.com/openharmony/systemabilitymgr_samgr_lite)[systemabilitymgr_samgr](https://gitee.com/openharmony/systemabilitymgr_samgr)[systemabilitymgr_safwk](https://gitee.com/openharmony/systemabilitymgr_safwk)

[systemabilitymgr_safwk_lite](https://gitee.com/openharmony/systemabilitymgr_safwk_lite)

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Описание недоступно Развернуть Свернуть
C
Apache-2.0
Отмена

Обновления (1)

все

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/openharmony-systemabilitymgr_samgr_lite.git
git@api.gitlife.ru:oschina-mirror/openharmony-systemabilitymgr_samgr_lite.git
oschina-mirror
openharmony-systemabilitymgr_samgr_lite
openharmony-systemabilitymgr_samgr_lite
master