sábado, 10 de agosto de 2024

FIBOCOM L610 - OPENCPU

  


unisoc:Cortex-A5
L7R5:500 MHz

Testado no KIT ADP-L610-GL-33-00

Modo OpenCPU garante a comunicação entre os aplicativos dos clientes e o módulo sem a necessidade de os conjuntos de comandos MCU ou AT. Os aplicativos dos clientes, como parte do programa de firmware principal, chamam APIs integradas para implementar as funções desejadas, por exemplo, iniciar/parar o protocolo integrado pilha para rede dial-up (DUN). Os aplicativos chamam APIs que encapsulam o LWIP interno interface para transmissão de dados, chamada encapsulada HTTP, MQTT, FTP e outras APIs para implementar diferentes requisitos de serviço, chame UART encapsulado, I2C, SPI e outras APIs para controlar periféricos dispositivos, incluindo o LCD e a câmera, chamam APIs de sistema operacional encapsuladas para criar threads, filas de mensagens, e semáforos, e chamar APIs GPIO encapsuladas para gerenciamento GPIO e outros requisitos. 
A função de implementação da API é a mesma que a função de implementação do comando AT. Quase todos as operações que os conjuntos de comandos AT podem executar podem ser desenvolvidas para APIs para que os aplicativos chamem assim quanto a atender requerimentos em diferentes cenários.


Modo OpenCPU economiza hardware MCU, o que diminui muito os custos dos clientes. As operações realizadas enviando e recebendo comandos AT pelo MCU pode ser implementado por software. CPU aberta integra aplicativos e chama APIs encapsuladas. O cliente precisa executar de forma independente desenvolvimento, gerar arquivos executáveis e gravá-los no flash para carregar e executar normalmente.

Executando OpenCPU na inicialização


Conforme mostrado na figura anterior, quando o aplicativo do cliente carrega o aplicativo de versão principal após o bootloader, ele carregará o aplicativo armazenado no 0x2C0000 (relativo ao endereço de início da aplicação) da flash e verifica o cabeçalho de algumas centenas de bytes armazenados neste endereço inicial. Depois de confirmar que o aplicativo cliente está correto, ele redireciona para a pilha inicial endereço do aplicativo do cliente a ser executado, ou seja, a função de entrada do aplicativo exibida para o cliente.

void *appimg_enter(void *parameter)
{
return user_callback; 
}

Use o endereço da variável da estrutura da função como o valor retornado da função de entrada.

A estrutura da função define dois retornos de chamada internamente (CallBacks): um para relatório de eventos assíncronos e outro para receber respostas a comandos AT enviados chamando APIs AT. Para obter detalhes sobre o método de uso, consulte  código.

A função de entrada void *appimg_enter(void *param) do aplicativo do cliente é uma função vazia para o sistema, e a demonstração de referência só pode imprimir uma linha de logs, que terminará após a inicialização, carregamento, execução e saída e não será carregado outra vez. Portanto, o aplicativo do cliente deve ser executado dentro do thread criado neste interface e chamar a API dentro do thread para lidar com várias funções do aplicação, como ativação de conexão PDP e serviço de dados.

Mecanismo de Eventos

O mecanismo de notificação OpenCPU para receber eventos através de APIs assíncronas e o mecanismo de chamada de APIs para envio de comandos AT para receber respostas de comandos AT são mantidos.
As APIs são classificadas em APIs de bloco e não-bloco com base no fato de o resultado da execução ser notificado após a chamada da API. As APIs de bloqueio notificam os resultados imediatamente após serem chamadas, e as APIs sem bloqueio notificam outros threads de processamento ou notificar o resultado do processamento no retorno de chamada.
Para APIs sem bloco, a conclusão da execução não significa o fim de um evento. O evento mecanismo de notificação é necessário para notificar a aplicação do cliente sobre se um evento está foi bem-sucedido ou falhou ou se o resultado calculado precisa ser executado. A aplicação do cliente aumenta o semáforo ou atraso para aguardar o resultado da execução.
O código a seguir define a função de retorno de chamada para receber eventos

Struct FIBO_CALLBACK_S {
    fibo_at_resp_tat_resp;
    fibo_signal_tfibo_signal; 
};

at_resp é a função de retorno de chamada que recebe a resposta do comando AT quando a API para envio de AT comandos envia um determinado comando AT.

fibo_signal é a função de retorno de chamada que trata e recebe o resultado da execução assíncrona da API e relatar o evento. 

SignalEvent é definido em fibo_OpenCPU_comm.h

OpenCPU Flash

Atualmente, a plataforma se integra internamente com 8 MB de flash. A figura a seguir mostra o tamanho do flash ocupado por diferentes módulos de software.

Entre eles, 512 KB de espaço são alocados da partição "aplicativo" para o OpenCPU.

Macro


Divisão de espaço de armazenamento de aplicativos

O espaço restante do sistema de arquivos é de cerca de 1,2 MB. Algum espaço será retido para armazenando da versão principal do pacote de atualização diferencial FOTA e o aplicativo do cliente pacote de atualização FOTA. Como o tamanho do pacote de atualização FOTA é incerto, nem todos o espaço restante do sistema de arquivos pode ser alocado para armazenar arquivos fixos.

A biblioteca TTS (text-to-sound) também é compilada na versão principal e armazenada no espaço flash do aplicativo. Ocupa cerca de 700 KB do espaço flash. Como resultado, o espaço flash restante real do aplicativo é de cerca de 100 KB. Se você não precisar do TTS ou tem requisitos para o espaço flash, remova o TTS.

Configuração do ambiente de desenvolvimento OpenCPU e Compilação

Será necessário a execução da Virtualização do UBUNTU, no caso foi utilizado o WSL.


Depois de instalar o Ubuntu, conecte-se à Internet conforme necessário. Depois de se conectar à Internet com sucesso, use o privilégio de root do Ubuntu para executar os seguintes comandos: 

sudo apt install build-essential python3 python3-tk qtbase5-dev



sudo apt install libc6 libstdc++6 zlib1g


Os comandos anteriores são usados para instalar a biblioteca e o software necessários para compilar um programa do usuário.

Obtenha com a FIBOCOM  
o SDK core_sdk_16000.1000.00.88.15.03.tar.zip

ou Docker

Copie core_sdk.tar.gz para um diretório no Ubuntu, por exemplo, /home/user/. Rode o seguinte comando na interface de shell do Ubuntu.:

cd /home/ubuntu/
unzip core_sdk_16000.1000.00.88.15.03.tar.zip


Depois de descompactar o pacote, execute os seguintes comandos de compilação em sequência: 

cd core_sdk_16000.1000.00.88.15.03.tar/
tar xzvf core_sdk_16000.1000.00.88.15.03.tar.gz


Adicionando código a ser compilado

Depois de obter o pacote TAR e descompactá-lo em uma pasta , você verá arquivos mostrados na figura a seguir, pasta ROOT do CSDK.


Entre eles, hello_world.c e demo.c são códigos de exemplo.

Enfim, para o código exemplo abaixo, chamado de Uart Demo, crie um arquivo oc_uart_demo.c na pasta ROOT e copie o conteúdo para dentro.

Exemplo que utiliza UART
/* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA"). * All rights reserved. * * This software is supplied "AS IS" without any warranties. * RDA assumes no responsibility or liability for the use of the software, * conveys no license or title under any patent, copyright, or mask work * right to the product. RDA reserves the right to make changes in the * software without notification. RDA also make no representation or * warranty that such application will be suitable for the specified use * without further testing or modification. */ #define OSI_LOG_TAG OSI_MAKE_LOG_TAG('M', 'Y', 'A', 'P') #include "fibo_opencpu.h" #include "oc_uart.h" #include "stdio.h" #include "stdlib.h" #include "string.h" void uart_recv(hal_uart_port_t uart_port, UINT8 *data, UINT16 len, void *arg) { OSI_PRINTFI("uartapi recv uart_port=%d len=%d, data=%s", uart_port, len, (char *)data); } static void prvThreadEntry(void *param) { OSI_LOGI(0, "application thread enter, param 0x%x", param); hal_uart_config_t drvcfg = {0}; drvcfg.baud = 115200; drvcfg.parity = HAL_UART_NO_PARITY; drvcfg.data_bits = HAL_UART_DATA_BITS_8; drvcfg.stop_bits = HAL_UART_STOP_BITS_1; drvcfg.rx_buf_size = UART_RX_BUF_SIZE; drvcfg.tx_buf_size = UART_TX_BUF_SIZE; int port = 0; uint8_t send_test[] = "uart testando"; fibo_hal_uart_init(port, &drvcfg, uart_recv, NULL); for (size_t i = 0; i < 3; i++) { fibo_hal_uart_put(port, send_test, sizeof(send_test) - 1); fibo_taskSleep(1 * 1000); } OSI_LOGI(0, "application thread exit, param 0x%x", param); fibo_hal_uart_deinit(port); fibo_thread_delete(); } void* appimg_enter(void *param) { OSI_LOGI(0, "application image enter, param 0x%x", param); fibo_thread_create(prvThreadEntry, "mythread", 1024, NULL, OSI_PRIORITY_NORMAL); return 0; } void appimg_exit(void) { OSI_LOGI(0, "application image exit"); }

Você só precisa adicionar código à macro CONFIG_APPIMG_LOAD_FLASH em CMakeLists.txt e adicionar o caminho do arquivo de cabeçalho recém-adicionado.

Execute

. tools/core_launch.sh 
cout
cd ..
cmake .. /.. -G Ninja
adicione em CMakeLists.txt (root do sdk) o fonte que voce quer testar

if(CONFIG_APPIMG_LOAD_FLASH)
    set(target hello_flash)
    add_appimg(${target} ${flash_ldscript} 
     ###hello_world.c
     ###demo.c
### pingpong.c
oc_uart_demo )

ninja
ubuntu@DESKTOP-UHGFA4M:~/core_sdk_16000.1000.00.88.15.03.tar/out$ ninja clean
[1/1] Cleaning all built files...
Cleaning... 8 files.
ubuntu@DESKTOP-UHGFA4M:~/core_sdk_16000.1000.00.88.15.03.tar/out$ ninja
[6/6] Generating hex/hello_flash.pac
ubuntu@DESKTOP-UHGFA4M:~/core_sdk_16000.1000.00.88.15.03.tar/out$


Gravando o hello_Flash.pac (ps: NINJA gera sempre este nome), grave também o .pac encontrado em 16000.1000.00.88.15.03.zip



Execução


Continuando...

No desenvolvimento real, você pode definir os nomes de arquivo .c e .h e criar uma nova pasta para armazenar sua aplicação.
Por exemplo, você pode criar uma pasta de teste no caminho em que CMakeLists.txt está localizado. Em seguida, crie a pasta src e a pasta include na pasta de teste para armazenar arquivos .c e .h, respectivamente. 

Crie uma pasta para armazenar arquivos .c e .h, por exemplo, criando test.c e test2.c em src.



Adicione o caminho do arquivo de cabeçalho recém-adicionado. Se vários caminhos de arquivo de cabeçalho forem criados, adicione-os a partir daqui.


Se houver muitos arquivos de aplicativo, adicione a variável LIB_SOURCES_FILE a CMakeLists.txt gravar os caminhos de todos os arquivos .c e fazer referência a essa variável em add_appimg.
Conforme mostrado na figura a seguir, se houver vários arquivos .c na pasta abc, adicione-os a partir do script de declaração de arquivo.



Sobre appimg

Apenas uma função de entrada void*appimg_enter(void*param) é permitida para todo o código. Se houver for qualquer função de entrada em outros arquivos .c, ocorrerá um erro de compilação. Observe o nome e do arquivo em que a função de entrada está armazenada.

Erro compilação UBUNTU (WSL WINDOWS)

The error message "dtools: error while loading shared libraries: libicui18n.so.55: cannot open shared object file: No such file or directory" indicates that the library libicui18n.so.55 is missing from your system. Here are some steps to resolve this issue:

1. Install the Missing Library:
•  On Ubuntu or Debian-based systems, you can download and install the missing library using the following commands:

wget http://security.ubuntu.com/ubuntu/pool/main/i/icu/libicu55_55.1-7_amd64.deb
sudo dpkg -i libicu55_55.1-7_amd64.deb

MQTT - Como seria inclusão de LIB



REF


Sobre a SMARTCORE

A SmartCore fornece módulos para comunicação wireless, biometria, conectividade, rastreamento e automação.
Nosso portfólio inclui modem 2G/3G/4G/NB-IoT/Cat.M, satelital, módulos WiFi, Bluetooth, GNSS / GPS, Sigfox, LoRa, leitor de cartão, leitor QR code, mecanismo de impressão, mini-board PC, antena, pigtail, LCD, bateria, repetidor GPS e sensores.

Mais detalhes em www.smartcore.com.br

Nenhum comentário:

Postar um comentário