Quectel M66 OpenCPU. От теории к практике

В предыдущих статьях[12] по Quectel M66 OpenCPU было рассказано об основных особенностях системы OpenCPU и ее архитектуре. Настало время показать на практике эту архитектуру и как вообще начать программировать свое приложение под OpenCPU. По традиции будем решать задачу “Hello World!” для МК в виде мигания светодиодом.

Что нам понадобится для начала?

1. Отладочная плата M10-EVBKit, описание которого находим здесь, с модулем M66‐TE‐A и прошивкой M66FAR01A01;
2. Beta-версия прошивки M66 OpenCPU от Quectel: M66FAR01A02_BETA1008;
3. SDK-пакет от Quectel: M66_OpenCPU_GS3_SDK_V1.1 для среды разработки Eclipse;
4. GCC-компилятор для ARM: arm-none-eabi-gcc, сразу устанавливаем на диск С;
5. Сама среда разработки Eclipse: eclipse-cpp-kepler-SR2-win32.

Все архивы можно будет взять по ссылке в конце статьи.

Итак, заливаем в наш M66-модуль прошивку OpenCPU_Beta:
— Подключаем COM-порт (USB->COM-преобразователь) к разъему Main платы;
— Открываем программу QFlash_V3.0 и, нажав на кнопку “Load FW Files”, указываем файл нашей прошивки M66FAR01A02_BETA1008:

— Выбираем Com Port, соответствующий подключенному USB-COM-преобразователю. Скорость ставим 460800;
— Жмем “Start” и включаем на плате последовательно: “Тумблер D/L” -> “Тумблер Power” -> Зажимаем кнопку “Pwrkey” на 1сек;
— Начинается процесс прошивки:

— При успешном окончании прошивки появляется надпись PASS, FW upgrade success:

В принципе уже можно начать работать с модулем в режиме отправки AT-команд, однако наша цель все-таки OpenCPU, потому продолжим.
Теперь, скопируем из архива eclipse-cpp-kepler-SR2-win32.zip содержимое в корень жесткого диска (для удобства). Это заранее настроенный C/C++ Eclipse.
Также копируем из архива M66_OpenCPU_GS3_SDK_V1.1_Eclipse.rar в корень жесткого диска настроенный под Eclipse SDK.
Открываем eclipse.exe из каталога со средой eclipse-cpp-kepler. Нажимаем File -> Import -> Existing Project into Workspace:

Жмем Next и выбираем путь к нашему SDK, отмечаем галочкой найденный проект и жмем Finish:

Осталось перевести наш проект в режим Release: Project -> Build Configurations -> Set Active -> Release. И настроим проект: Project -> Properties:
В Environment -> GCC_PATH выбираем путь с установленным компилятором GCC.

Также во вкладке Settings опционально можно настроить проект и компилятор:

Теперь уже можно скомпилировать проект с заранее отлаженным файлом main: Project -> Clean…; Project -> Build Project. В окне Console можно посмотреть результат компиляции:

А в окне Problems увидим все предупреждения и ошибки, которые нужно(или можно) исправить:

Теперь, перед загрузкой прошивки в проект нужно после компиляции сделать: Project -> Make Target -> Build (Shft+F9), что добавит дополнительную информацию в бинарник прошивки, который находится в каталоге Release проекта.

Загрузка прошивки в модуль производится аналогично вышеописанному способу, только в Load FW Files выбираем .bin файл из каталога Release проекта.

Теперь мы можем проверить на деле OpenCpu. Возьмем файл примера example_gpio.c из каталога example проекта. Открываем этот файл и копируем его содержимое полностью и вставляем в пустой файл main. Удаляем в начале файла: #ifdef __EXAMPLE_GPIO__ и в конце файла: #endif //__EXAMPLE_GPIO__.
Компилируем проект и получаем некоторые предупреждения (Warnings), однако уже можно загружать прошивку в модуль и проверять работу.

Немного о структуре данного примера

Основной функцией любого проекта OpenCPU является void proc_main_task(s32 taskId), также как и функция main() при программировании МК:

/************************************************************************/
/* The entrance for this example application                            */
/************************************************************************/
void proc_main_task(s32 taskId)
{
    ST_MSG msg;
    Ql_Debug_Trace("\r\n<-- OpenCPU: GPIO Example -->\r\n");

    // Start to program GPIO pin
    GPIO_Program();

    // Start message loop of this task
    while (TRUE)
    {
        Ql_OS_GetMessage(&msg);
        switch(msg.message)
        {
        case MSG_ID_USER_START:
            break;
        default:
            break;
        }
    }
}

В начале функции идет строка Ql_Debug_Trace("\r\n< — OpenCPU: GPIO Example -->\r\n");, которая выводит в порт Debug платы некоторую информацию о примере. Эта функция аналогична printf(“\r\nString\r\n”); в привычном виде. Описание данной функции можно прочитать, зажав CTRL и щелкнув по функции:

Таким же образом можно получать информацию обо всех функциях SDK.
Далее по листингу идет инициализация порта ввода-вывода для мигания светодиодом Netlight:

static void GPIO_Program(void)
{
    // Specify a GPIO pin
    Enum_PinName  gpioPin = PINNAME_NETLIGHT;

    // Define the initial level for GPIO pin
    Enum_PinLevel gpioLvl = PINLEVEL_HIGH;

    // Initialize the GPIO pin (output high level, pull up)
    Ql_GPIO_Init(gpioPin, PINDIRECTION_OUT, gpioLvl, PINPULLSEL_PULLUP);
    Ql_Debug_Trace("<-- Initialize GPIO pin (PINNAME_STATUS): output, high level, pull up -->\r\n");

    // Get the direction of GPIO
    Ql_Debug_Trace("<-- Get the GPIO direction: %d -->\r\n",   Ql_GPIO_GetDirection(gpioPin));

    // Get the level value of GPIO
    Ql_Debug_Trace("<-- Get the GPIO level value: %d -->\r\n\r\n", Ql_GPIO_GetLevel(gpioPin));

    // Set the GPIO level to low after 500ms.
    Ql_Debug_Trace("<-- Set the GPIO level to low after 500ms -->\r\n");
    Ql_Sleep(500);
    Ql_GPIO_SetLevel(gpioPin, PINLEVEL_LOW);
    Ql_Debug_Trace("<-- Get the GPIO level value: %d -->\r\n\r\n", Ql_GPIO_GetLevel(gpioPin));

    // Set the GPIO level to high after 500ms.
    Ql_Debug_Trace("<-- Set the GPIO level to high after 500ms -->\r\n");
    Ql_Sleep(500);
    Ql_GPIO_SetLevel(gpioPin, PINLEVEL_HIGH);
    Ql_Debug_Trace("<-- Get the GPIO level value: %d -->\r\n", Ql_GPIO_GetLevel(gpioPin));
}

Здесь выполняется инициализация

gpioPin = PINNAME_NETLIGHT;

настройка на выход, в высокое состояние с подтяжкой к питанию:

Ql_GPIO_Init(gpioPin, PINDIRECTION_OUT, gpioLvl, PINPULLSEL_PULLUP);

Далее проверяется состояние выхода:

Ql_GPIO_GetLevel(gpioPin));

Переводится в низкое состояние на 500 мсек:

Ql_GPIO_SetLevel(gpioPin, PINLEVEL_LOW);

И переводится в высокое состояние:

Ql_GPIO_SetLevel(gpioPin, PINLEVEL_HIGH);

Все комментарии по операциям выведутся в Debug-порт.

Для проверки выполнения команды рекомендуется использовать следующую конструкцию при инициализации и выполнении других функций:

s32 ret;

        // Initialize GPIO
ret=Ql_GPIO_Init(m_gpioPin,PINDIRECTION_OUT, PINLEVEL_LOW, PINPULLSEL_PULLUP);
        if(QL_RET_OK==ret)
        {
                Ql_Debug_Trace("<--Initialize GPIO successfully -->\r\n");
        }else{
Ql_Debug_Trace("<--Fail to initialize GPIO pin, cause=%d -->\r\n",ret);
}

Т.е. можно через Debug-порт посмотреть результат выполнения функции.
Важной частью программы OpenCPU является выполнение функции Ql_OS_GetMessage(&msg);, которая получает сообщения из очереди сообщений текущей задачи, где &msg – указатель на сообщение. Пример получения сообщений от системы:

// START MESSAGE LOOP OF THIS TASK
    while(TRUE)
    {
        Ql_OS_GetMessage(&msg);
        switch(msg.message)
        {
                case MSG_ID_RIL_READY:
                        Ql_Debug_Trace("<-- RIL is ready -->\r\n");
                Ql_RIL_Initialize();
                break;
                case MSG_ID_URC_INDICATION:
//Ql_Debug_Trace("<-- Received URC: type: %d, -->\r\n", msg.param1);
            switch (msg.param1)
            {
                case URC_SIM_CARD_STATE_IND:
                        SIM_Card_State_Ind(msg.param2);
                break;
default:
                        break;
      }
   }
}

Здесь получаем сообщения о готовности RIL-слоя: MSG_ID_RIL_READY
Также получаем сообщения URC: MSG_ID_URC_INDICATION, где URC_SIM_CARD_STATE_IND – сообщение о состоянии SIM-карты.
Вышеописанный пример позволит начать программировать OpenCPU M66 и проверять написанный код «в железе». Основную информацию по OpenCPU нужно читать в файле Quectel_OpenCPU_User_Guide_V6.0_Preliminary.pdf
Скачать необходимые файлы можно здесь.

Спасибо, что дочитали до конца. Подписывайтесь на нашу группу в ВК и заходите общаться в наш чат.

4 Ответов в “Quectel M66 OpenCPU. От теории к практике

  1. M66_OpenCPU_GS3_SDK_V2.0_Eclipse вместо M66_OpenCPU_GS3_SDK_V1.1 для среды разработки Eclipse подойдёт?

  2. Всем здравствовать! — ищу единомышлинников

Комментарии отключены.