segunda-feira, 30 de setembro de 2024

l610 - DEBUGGER - FIBOCOM

 

DEBUGGER

Está pode ser a solução para tornar mais fácil para você descobrir onde o programa está inativo. Isso permite que você veja facilmente as informações sobre variáveis globais e locais em seu programa. Para que você não precise se preocupar tanto na hora de procurar bugs!

Baseado no excelente documento

Fibocom_cat1_L610&LC610N&LG610&MC615_Log Capture Guide_Windows_V1.0.2.pdf

Foram realizados testes no KIT ADP-L610-GL-33-00

 Este documento descreve como capturar logs AP e logs CP no módulo em Ambiente Windows.

O exemplo utilizado foi o do blog

https://acessingslinkitfromanywhereintheworld.blogspot.com/2024/08/blog-post.html

Uma vez atualizado o Firmware base na FLASH do L610 e aplicado reset..

Se a porta serial DEGUG e USB porta do módulo são conectados ao computador Windows ao mesmo tempo, após o o módulo estiver ligado e o driver instalado, o gerenciador de dispositivos enumerará os seguintes portas:

Port 5 e Port 6 correspondem aos comandos  AT. Port 4 é para o DEBUG

Geralmente, apenas os logs AP são necessários sem envolver a rede. Se a rede for envolvido, você precisa fornecer logs AP e logs CP. 

Usando Coolwatcher para capturar Dump

Emissão do comando AT de acordo com o modo de captura O log AP é habilitado por padrão. Se não houver saída de log AP, você pode enviar AT^TRACECTRL=0,1 para ligar o interruptor de saída de log do AP.

Determine a linha de base do software do firmware: "05" é a linha de base V1.2 e "06" é a Linha de base V1.3. O número da versão é consultado por AT+CGMR?. Por exemplo, 16000.1000. 05.02.22 é uma "linha de base V1.2" e 16000.1000. 06.02.22 é uma versão baseada na V1.3

Selecione o AT correspondente de acordo com a situação da fiação e ele entrará em vigor após receber OK. 

 a. Se você capturar logs de AP ou logs de despejo por meio da porta serial de depuração. 

Emita um dos seguintes comandos AT com o número de versão 05 (linha de base V1.2): 

AT^TRACECTRL=0,1,3 // Habilitar a saída da porta serial de depuração e a saída USB simultaneamente 

AT ^ TRACECTRL = 0, 1, 0// Depurar somente a saída da porta serial 

Para a versão número 06 (linha de base V1.3), emita os seguintes comandos AT: 

AT ^ TRACECTRL = 0, 1, 1 // Habilitar somente a saída da porta serial de depuração 

 b. Se você capturar logs de AP por meio da porta USB: 

Selecione a porta COM correspondente à Porta 4 no Gerenciador de Dispositivos. 

Emita um dos seguintes comandos AT com o número de versão 05 (linha de base V1.2): 

AT^TRACECTRL=0,1,3 // Habilita a saída da porta serial de depuração e a saída USB

AT^TRACECTRL=0,1,2 // Habilitar somente saída USB

Número da versão 06 (linha de base V1.3):

AT^TRACECTRL=0,1,2 // Habilitar USB

Ou seja

Por padrão, os logs de nível de aplicativo (AP) e de nível de kernel (CP) estão desabilitados para.ativar a captura desses logs, proceda da seguinte forma:

Usando um programa de terminal (por exemplo: YAT, PUTTY, TERATERM), conecte à “Porta 0” (115200

8-N-1).

Verifique a versão do firmware em execução na placa com o comando AT:

ATI

A placa está respondendedo, para permitir a execução da captura de log utilize estes comandos AT:

Habilite a captura de log AP no PORT4 (com a ferramenta CoolWatcher):

    AT^TRACECTRL=0,1,2

Habilite a captura de log CP no PORT3 (com a ferramenta ArmTracer):

    AT^TRACECTRL=1,1

    AT^TRACECTRL=1,1,5

Reinicialize o módulo para aplicar essas alterações

Etapas da operação do CoolWatcher

Abra o CoolWatcher_usb.exe. Por exemplo, defina a porta serial de depuração para capturar logs de AP. Selecione 8910 à esquerda, preencha 8910 para ChipDie, preencha o número da porta 24 em lastcomport e clique OK no canto inferior direito.  (24 corresponde à "Unisoc Usb Serial Port 4"

Se a COM24 funcionar corretamente, o caractere verde de prompt "COM OPEN OK" aparecerá. 


Selecione no menu Plugins selecione Activate Tracer

Haverá três janelas à direita, basta prestar atenção no Trace Tool. As outras duas janelas podem ser fechado. Pare de capturar o log após a conclusão e use o botão salvar para salvar o O AP efetua login no caminho especificado

Analisar e salvar logs online 

Observe que os logs offline do CoolWatcher capturados só podem ser abertos com um editor de texto e não pode ser aberto com o coolwatcher. Ou seja, o CoolWatcher não suporta log offline análise. As configurações e descrições comuns são as seguintes:


Se a captura do log demorar muito, é recomendável usar o salvamento automático do log função. Clique no botão de configuração de log na figura acima e você também pode definir o geração automática de log Pcap (verifique Save PCAP para salvar o registro wireshark automaticamente). 

Caminho padrão de salvamento automático: 

UIS8910DM_cooltools_win32_R2.0.0002\logs

Analise o log on-line ou envie-o ao pessoal correspondente do FAE ou P&D para assistência

Capturando pacotes TCP/IP pelo CoolWatcher 

Conforme mostrado na figura acima: Verifique Save Pcap e reinicie o CoolWLatcher. Os logs TCP/IP no netif serão capturados e salvos automaticamente em UIS8910DM_cooltools_win32_R2.0.0002\logs, e a nova versão do software será salva no caminho UIS8910DM_cooltools_win32_R2.0.0002\logs. 

 Instale o Wireshark no PC para analisar logs TCP/IP.

 AT Switch para capturar log de despejo

Se ocorrer um despejo durante a depuração, não será suficiente fornecer os logs do AP e do CP. O log de despejo também é necessário. 

Arquivo necessário: arquivo elf correspondente à versão atual do software. Se for um OpenCPU projeto, é necessário um arquivo elf do OpenCPU. 

O CoolWatcher suporta análise de dump online. Após a ocorrência de um dump, o dump pode ser salvo no local. Você pode usar a ferramenta ARM-GDB fornecida pela ferramenta coolwatcher para executar análise preliminar de despejo.

Normalmente, o módulo será reiniciado automaticamente pelo software após o programa cliente trava. Durante a depuração, você pode executar oAT+GTSET= "GDB",1comando, e o o módulo responde OK e reinicia novamente para entrar em vigor, para garantir que o módulo não será reiniciado por despejo de software após despejo. Se a configuração de AT+GTSET=“GDB”,1 for inválida, o watchdog pode ter sido habilitado no aplicativo cliente. Neste caso, o cliente precisa para desabilitar o watchdog e gravar o aplicativo cliente para novo teste. Execute AT+GTSET=”GDB”,0 para restaurar para o valor padrão. A configuração é salva em caso de falha de energia e entra em vigor em reiniciar. 

Motivos comuns de despejo durante o desenvolvimento do projeto OpenCPU:---- 

Null Pointer. memcpy copia dados do ponteiro nulo para outra memória ou copia dados para o ponteiro nulo, etc.; 

O comprimento dos dados de destino do memcpy é maior que o do endereço de origem; 

Estouro de memória. A proteção de limite julga como um dump; 

A pilha de solicitações CreateThread é muito pequena e há grandes variáveis locais durante operação que causa travamento devido a operação anormal; 

Os threads de solicitação dinâmica ou semáforos ou a memória de solicitação dinâmica não são limpos em tempo hábil, e o heap não for liberado e recuperado em tempo hábil, o que resulta em consumo e vazamento de memória e tamanho livre cada vez menor após execução contínua e, eventualmente, trava devido ao esgotamento da memória; e outras razões

Análise on-line de captura de log de despejo 

Após AT+GTSET=“GDB”,1 ser executado, um dump ocorre e permanece durante o teste, use o Ferramenta ARM-GDB fornecida com o CoolWatcher para analisar e analisar o dump. 

 Escolher Tools>GDB Launcher, conforme mostrado na figura a seguir

Jogue no CMakeLists.txt o nome demo_hello_Debug.c compile, grave.

/*************** demo_hello_Debug ****************/ #include "iot_debug.h" #include "iot_os.h" HANDLE demo_hello_Debug_task; int demo_hello_Debug_num = 0; static void demo_hello_Debug(PVOID pParameter) { iot_debug_print("[hello]demo_hello_Debug"); //关闭看门狗,死机不会重启。默认打开 iot_debug_set_fault_mode(OPENAT_FAULT_HANG); //打开调试信息,默认关闭 iot_vat_send_cmd("AT^TRACECTRL=0,1,3\r\n", sizeof("AT^TRACECTRL=0,1,3\r\n")); volatile int n = 0; for (n = 0; n < 15; n++) { demo_hello_Debug_num++; iot_debug_print("[debug]hello world %d", n); iot_os_sleep(1000); } n++; OPENAT_assert(0, __func__, __LINE__); iot_os_delete_task(demo_hello_Debug_task); } int appimg_enter(void *param) { iot_debug_print("[hello]appimg_enter"); demo_hello_Debug_task = iot_os_create_task(demo_hello_Debug, NULL, 1024, 1, OPENAT_OS_CREATE_DEFAULT, "hello_Debug"); return 0; } void appimg_exit(void) { iot_debug_print("[hello]appimg_exit"); }



Existem três funções desconhecidas usadas no código acima, que são:

。 Após a reinicialização, as informações de exceção serão perdidas, portanto, não há como ler as informações anormais da pilha, portanto, é recomendável usar o seguinte comando na fase de depuração.

/** *@param mode: OPENAT_FAULT_RESET 重启模式 OPENAT_FAULT_HANG 调试模式 **/



VOID iot_debug_set_fault_mode(E_OPENAT_FAULT_MODE mode)


Desabilita a saída de informações de depuração por padrão. Em geral, depois que o dispositivo estiver em execução, você poderá enviar o comando AT por meio do assistente de depuração de porta serial para habilitar as informações de depuração e precisará reiniciá-lo após cada download. É muito problemático, por isso é recomendável usar o canal AT virtual para enviar automaticamente comandos AT através do software no estágio de depuração do programa para obter a função de abrir automaticamente a saída de informações de depuração.

//Via AT command
AT^TRACECTRL=0,1,1
vai mandar TRACE para DBG_TXD do Starter Kit.

**用来发送AT命令 *@param cmdStr: AT命令字符串 *@param cmdLen: AT命令长度 *@return TRUE: 成功 FALSE: 失败 *@note 注意,AT命令字符串cmdStr中需要包含"\r\n"或者"\r"结尾 **/

/



BOOL iot_vat_send_cmd(UINT8* cmdStr, UINT16 cmdLen)


Este código é o que faz as coisas, e a única coisa que ele faz é fazer seu programa congelar. Este exemplo é usado para criar uma cena de falha para apresentação.

/**assert断言 *@param condition: 断言条件 *@param func: 断言函数 *@param line: 断言位置 *@return TURE: 成功 * FALSE: 失败 **/




VOID iot_debug_assert (BOOL condition, CHAR *func, UINT32 line)


Em seguida, o programa também usa uma variável global e uma variável local, respectivamente, e quando ele travar, você pode verificar o valor da variável no momento do travamento para ver se ela atende às suas expectativas.

3. Baixe e verifique

Tudo funciona bem e não há problemas.

Espere, parece que há algo errado, como imprimir um helloworld se foi. O tutorial anterior realmente se foi quando se tratava de verificação de download, mas hoje é apenas o começo.


Enquanto esperarmos pelas duas coisas acima, nosso conteúdo de hoje começa oficialmente! (Eu não esperei até esperar, foram cerca de 15s).

Quarto, comece a depurar

4.1. GDB lê informações da pilha

4.1.1. Clique abaixo da guia Tools GDB Launcher

4.1.2. Selecione o arquivo correspondente na pequena janela que se abre.


Selecione o arquivo errado no diretório do projeto na caixa ELF !!~\iot_sdk_4g_8910Main\hex\Air720U_CSDK_demo_Debug_map\CSDK_RDA8910.elf

Modo. Em seguida, clique em Launch com 8910 AP

4.1.3. Carregue o arquivo ELF do APP

Normalmente, você verá uma interface como esta.

Os botões a seguir serão usados mais tarde, então vamos apresentá-los primeiro. Da esquerda para a direita: [Informações de registro], [Informações de memória], [Pilha de chamadas], [Exibir variáveis globais], [Variáveis locais], [Não sei o que é], [Console GDB].


Clique no terceiro botão para ver o efeito. Veja um, e há apenas alguns pontos de interrogação nele. O que é chamado em nosso programa é que todos eles têm uma palavra-chave que é. O que é realmente chamado é a interface fornecida pela camada subjacente. Então, por que a ferramenta de depuração é encontrada, mas não encontrada?

O fenômeno acima ocorre porque o que acabou de ser carregado é, na verdade, o arquivo ELF subjacente e o arquivo compilado pelo usuário ainda não foi carregado. Para carregar o arquivo ELF do usuário, basta clicar no último botão (o console gdb) e digitar o seguinte comando na janela que se abre. Esse comando não é fixo e precisa ser modificado com base no local real em que o projeto está armazenado.

:Antes de entrar, verifique se um arquivo é gerado no diretório raiz do projeto. Após a conclusão da compilação deste arquivo, ele precisa ser executado no console do gdb.OPENAT_assertiot_debug_assertassertiot_debug_assertOPENAT_assertOPENAT_assertiot_debug_assertapp.elfsource D:\AirJob\RDA8910CSDK\iot_sdk_4g_8910Main\start.gdb注意start.gdb自动生成的


Depois que a entrada terminar, o console prometerá uma bagunça de dados, basta procurar este campo nele e, se você encontrá-lo, é metade da batalha.

Depois que o carregamento for bem-sucedido, clique no terceiro botão novamente (você precisa fechar e reabrir a janela da pilha aberta anteriormente). Neste momento, antes da descoberta de ?? Foi substituído por uma função. O do meio é a tarefa de teste que acabamos de escrever, e também vemos o local do acidente à esquerda.demo_Debug.cdemo_hello_Debug

4.2. Visualizar informações variáveis

Na demonstração, escrevemos uma variável global e uma variável local para teste. Vamos ver se podemos ler as informações das variáveis em caso de travamento.demo_hello_Debug_num

4.2.1, por meio da leitura de informações de memória 

Abra o arquivo e procure o endereço que o precede. 

Clique no terceiro botão, insira as informações de endereço e leia os primeiros quatro bytes.

Analisando o programa, a variável global int é do tipo 4 bytes. Comece em 0 e adicione automaticamente os tempos dentro do loop for. Saia do loop e depois falhe, então o resultado é igual a hexadecimal. E como int tem quatro bytes, 15 deve ser igual para ver se é o mesmo que os dados lidos acima.~\iot_sdk_4g_8910Main\hex\Air720U_CSDK_demo_Debug_map\app.mapdemo_hello_Debug_num0x80f006200x80f006200x0000000f15demo_hello_Debug_num15150x0f0x0000000f

int demo_hello_Debug_num = 0; ..... { ..... for (n = 0; n < 15; n++) { demo_hello_Debug_num++; iot_debug_print("[debug]hello world %d", n); iot_os_sleep(1000); } n++; iot_debug_assert(0, __func__, __LINE__); ..... 

}






4.2.2 Leitura através do Watch (variáveis locais também podem ser usadas)

Algumas pessoas dizem: "Oh, isso é tão problemático". Você também tem que olhar para o endereço no mapa e ir até a memória para encontrá-lo você mesmo. Então aqui vem o caminho mais fácil.

Conforme mostrado na figura acima, clique no 4º botão, entre e na caixa de entrada e, finalmente, a janela exibirá as informações da variável.

: Aqui você só pode ver os valores de variáveis locais que não foram otimizadas pelo compilador. Se estiver otimizado, você não poderá vê-lo! Definir variáveis com palavras-chave impede a otimização.demo_hello_Debug_numn注意volatile

4.2.3. Olhar direto simples e brutal

Passe o mouse sobre a variável correspondente por um tempo e o valor da variável sairá ̑̑ฅ( ˃̶ ̇ω ̇˂̶ ฅ).


Ref

RDA8910(4GCAT1)CSDK二次开发:14、CSDK程序死机了怎么办?_rda 编程-CSDN博客

RDA8910(4GCAT1)CSDK二次开发:1、环境搭建_4g cat1 中boot按键作用-CSDN博客

How to Install GCC and GDB on Windows Using MSYS2 — Tutorial | by Sajid Anam Ifti | Medium

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 

quarta-feira, 4 de setembro de 2024

L610 - DEBUGGER - CHINA

DEBUGGER

Está pode ser a solução para tornar mais fácil para você descobrir onde o programa está inativo. Isso permite que você veja facilmente as informações sobre variáveis globais e locais em seu programa. Para que você não precise se preocupar tanto na hora de procurar bugs!

Jogue no CMakeLists.txt o nome demo_hello_Debug.c compile, grave.

/*************** demo_hello_Debug ****************/ #include "iot_debug.h" #include "iot_os.h" HANDLE demo_hello_Debug_task; int demo_hello_Debug_num = 0; static void demo_hello_Debug(PVOID pParameter) { iot_debug_print("[hello]demo_hello_Debug"); //关闭看门狗,死机不会重启。默认打开 iot_debug_set_fault_mode(OPENAT_FAULT_HANG); //打开调试信息,默认关闭 iot_vat_send_cmd("AT^TRACECTRL=0,1,3\r\n", sizeof("AT^TRACECTRL=0,1,3\r\n")); volatile int n = 0; for (n = 0; n < 15; n++) { demo_hello_Debug_num++; iot_debug_print("[debug]hello world %d", n); iot_os_sleep(1000); } n++; OPENAT_assert(0, __func__, __LINE__); iot_os_delete_task(demo_hello_Debug_task); } int appimg_enter(void *param) { iot_debug_print("[hello]appimg_enter"); demo_hello_Debug_task = iot_os_create_task(demo_hello_Debug, NULL, 1024, 1, OPENAT_OS_CREATE_DEFAULT, "hello_Debug"); return 0; } void appimg_exit(void) { iot_debug_print("[hello]appimg_exit"); }



Existem três funções desconhecidas usadas no código acima, que são:

。 Após a reinicialização, as informações de exceção serão perdidas, portanto, não há como ler as informações anormais da pilha, portanto, é recomendável usar o seguinte comando na fase de depuração.

/** *@param mode: OPENAT_FAULT_RESET 重启模式 OPENAT_FAULT_HANG 调试模式 **/



VOID iot_debug_set_fault_mode(E_OPENAT_FAULT_MODE mode)


Desabilita a saída de informações de depuração por padrão. Em geral, depois que o dispositivo estiver em execução, você poderá enviar o comando AT por meio do assistente de depuração de porta serial para habilitar as informações de depuração e precisará reiniciá-lo após cada download. É muito problemático, por isso é recomendável usar o canal AT virtual para enviar automaticamente comandos AT através do software no estágio de depuração do programa para obter a função de abrir automaticamente a saída de informações de depuração.

//Via AT command
AT^TRACECTRL=0,1,1
vai mandar TRACE para DBG_TXD do Starter Kit.

**用来发送AT命令 *@param cmdStr: AT命令字符串 *@param cmdLen: AT命令长度 *@return TRUE: 成功 FALSE: 失败 *@note 注意,AT命令字符串cmdStr中需要包含"\r\n"或者"\r"结尾 **/

/



BOOL iot_vat_send_cmd(UINT8* cmdStr, UINT16 cmdLen)


Este código é o que faz as coisas, e a única coisa que ele faz é fazer seu programa congelar. Este exemplo é usado para criar uma cena de falha para apresentação.

/**assert断言 *@param condition: 断言条件 *@param func: 断言函数 *@param line: 断言位置 *@return TURE: 成功 * FALSE: 失败 **/




VOID iot_debug_assert (BOOL condition, CHAR *func, UINT32 line)


Em seguida, o programa também usa uma variável global e uma variável local, respectivamente, e quando ele travar, você pode verificar o valor da variável no momento do travamento para ver se ela atende às suas expectativas.

3. Baixe e verifique

Tudo funciona bem e não há problemas.

Espere, parece que há algo errado, como imprimir um helloworld se foi. O tutorial anterior realmente se foi quando se tratava de verificação de download, mas hoje é apenas o começo.


Enquanto esperarmos pelas duas coisas acima, nosso conteúdo de hoje começa oficialmente! (Eu não esperei até esperar, foram cerca de 15s).

Quarto, comece a depurar

4.1. GDB lê informações da pilha

4.1.1. Clique abaixo da guia Tools GDB Launcher

4.1.2. Selecione o arquivo correspondente na pequena janela que se abre.


Selecione o arquivo errado no diretório do projeto na caixa ELF !!~\iot_sdk_4g_8910Main\hex\Air720U_CSDK_demo_Debug_map\CSDK_RDA8910.elf

Modo. Em seguida, clique em Launch com 8910 AP

4.1.3. Carregue o arquivo ELF do APP

Normalmente, você verá uma interface como esta.

Os botões a seguir serão usados mais tarde, então vamos apresentá-los primeiro. Da esquerda para a direita: [Informações de registro], [Informações de memória], [Pilha de chamadas], [Exibir variáveis globais], [Variáveis locais], [Não sei o que é], [Console GDB].


Clique no terceiro botão para ver o efeito. Veja um, e há apenas alguns pontos de interrogação nele. O que é chamado em nosso programa é que todos eles têm uma palavra-chave que é. O que é realmente chamado é a interface fornecida pela camada subjacente. Então, por que a ferramenta de depuração é encontrada, mas não encontrada?

O fenômeno acima ocorre porque o que acabou de ser carregado é, na verdade, o arquivo ELF subjacente e o arquivo compilado pelo usuário ainda não foi carregado. Para carregar o arquivo ELF do usuário, basta clicar no último botão (o console gdb) e digitar o seguinte comando na janela que se abre. Esse comando não é fixo e precisa ser modificado com base no local real em que o projeto está armazenado.

:Antes de entrar, verifique se um arquivo é gerado no diretório raiz do projeto. Após a conclusão da compilação deste arquivo, ele precisa ser executado no console do gdb.OPENAT_assertiot_debug_assertassertiot_debug_assertOPENAT_assertOPENAT_assertiot_debug_assertapp.elfsource D:\AirJob\RDA8910CSDK\iot_sdk_4g_8910Main\start.gdb注意start.gdb自动生成的


Depois que a entrada terminar, o console prometerá uma bagunça de dados, basta procurar este campo nele e, se você encontrá-lo, é metade da batalha.

Depois que o carregamento for bem-sucedido, clique no terceiro botão novamente (você precisa fechar e reabrir a janela da pilha aberta anteriormente). Neste momento, antes da descoberta de ?? Foi substituído por uma função. O do meio é a tarefa de teste que acabamos de escrever, e também vemos o local do acidente à esquerda.demo_Debug.cdemo_hello_Debug

4.2. Visualizar informações variáveis

Na demonstração, escrevemos uma variável global e uma variável local para teste. Vamos ver se podemos ler as informações das variáveis em caso de travamento.demo_hello_Debug_num

4.2.1, por meio da leitura de informações de memória 

Abra o arquivo e procure o endereço que o precede. 

Clique no terceiro botão, insira as informações de endereço e leia os primeiros quatro bytes.

Analisando o programa, a variável global int é do tipo 4 bytes. Comece em 0 e adicione automaticamente os tempos dentro do loop for. Saia do loop e depois falhe, então o resultado é igual a hexadecimal. E como int tem quatro bytes, 15 deve ser igual para ver se é o mesmo que os dados lidos acima.~\iot_sdk_4g_8910Main\hex\Air720U_CSDK_demo_Debug_map\app.mapdemo_hello_Debug_num0x80f006200x80f006200x0000000f15demo_hello_Debug_num15150x0f0x0000000f

int demo_hello_Debug_num = 0; ..... { ..... for (n = 0; n < 15; n++) { demo_hello_Debug_num++; iot_debug_print("[debug]hello world %d", n); iot_os_sleep(1000); } n++; iot_debug_assert(0, __func__, __LINE__); ..... 

}






4.2.2 Leitura através do Watch (variáveis locais também podem ser usadas)

Algumas pessoas dizem: "Oh, isso é tão problemático". Você também tem que olhar para o endereço no mapa e ir até a memória para encontrá-lo você mesmo. Então aqui vem o caminho mais fácil.

Conforme mostrado na figura acima, clique no 4º botão, entre e na caixa de entrada e, finalmente, a janela exibirá as informações da variável.

: Aqui você só pode ver os valores de variáveis locais que não foram otimizadas pelo compilador. Se estiver otimizado, você não poderá vê-lo! Definir variáveis com palavras-chave impede a otimização.demo_hello_Debug_numn注意volatile

4.2.3. Olhar direto simples e brutal

Passe o mouse sobre a variável correspondente por um tempo e o valor da variável sairá ̑̑ฅ( ˃̶ ̇ω ̇˂̶ ฅ).


Ref

RDA8910(4GCAT1)CSDK二次开发:14、CSDK程序死机了怎么办?_rda 编程-CSDN博客

RDA8910(4GCAT1)CSDK二次开发:1、环境搭建_4g cat1 中boot按键作用-CSDN博客

How to Install GCC and GDB on Windows Using MSYS2 — Tutorial | by Sajid Anam Ifti | Medium

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