Produção de transplante FreeRTOS qemu mps2-an385 bsp: impressão em porta serial

Artigos relacionados

Produção de transplante FreeRTOS qemu mps2-an385 bsp: construção ambiental

Produção de transplante FreeRTOS qemu mps2-an385 bsp: inicialização do sistema

Produção de transplante FreeRTOS qemu mps2-an385 bsp: operação do sistema

ambiente de desenvolvimento

  • Win10 64 bits + VS Code, conexão remota ssh com o Ubuntu

  • Estação de trabalho VMware Pro 16 + Ubuntu 20.04

  • FreeRTOSv202212.01 (Observação: você pode obter a versão mais recente no github)

  • placa de desenvolvimento qemu qemu-system-arm mps2-an385, versão qemu Emulador QEMU versão 4.2.1 ou superior

  • conjunto de ferramentas de compilação cruzada arm gcc: atualmente usando o ambiente de compilação gcc, gcc-arm-11.2-2022.02-x86_64-arm-none-eabi, gcc versão 11.2.1 20220111

prefácio

Produção de transplante FreeRTOS qemu mps2-an385 bsp: a operação do sistema realiza a operação do FreeRTOS, cria uma tarefa e a executa com sucesso

  • Este artigo continua otimizando, adicionando um driver de porta serial, permitindo que o sistema imprima informações da porta serial quando estiver em execução

Driver serial

  • O driver da porta serial do qemu mps2-an385 é relativamente simples. A impressão da porta serial atual só precisa se preocupar com a saída da porta serial e a entrada de interrupção da porta serial. Ela será processada posteriormente quando a função do terminal shell for adicionada .

  • Criar qemu_mps2/driver/drv_uart.c, o conteúdo é o seguinte:

#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include "drv_uart.h"
#include "CMSDK_CM3.h"

#define DBG_BUFF_MAX_LEN    256
static char rt_log_buf[DBG_BUFF_MAX_LEN] = {
    
     0 };

/* qemu uart dirver class */
struct uart_instance
{
    
    
    const char *name;
    CMSDK_UART_TypeDef *handle;
    IRQn_Type irq_num;
    int uart_index;
};

static struct uart_instance uart0_handle = {
    
     0 };

static void uart_putc(uint8_t c)
{
    
    
    uart0_handle.handle->DATA = c;
}

static int serial_put(const char *data, int length)
{
    
    
    int size;

    size = length;
    while (length)
    {
    
    
        uart_putc(*data);
        ++ data;
        -- length;
    }

    return size - length;
}

/* debug print */
int os_printf(const char *fmt, ...)
{
    
    
    int length;
    va_list args;
    va_start(args, fmt);
    length = vsnprintf(rt_log_buf, sizeof(rt_log_buf) - 1, fmt, args);

    serial_put(rt_log_buf, length);
    return length;
}

void UART0RX_Handler(void)
{
    
    
    uint32_t irq_status = 0x00;
    irq_status = uart0_handle.handle->INTCLEAR;
    uart0_handle.handle->INTCLEAR = irq_status;
}

int uart_init(void)
{
    
    
    uart0_handle.handle = CMSDK_UART0;
    uart0_handle.uart_index = UART0RX_IRQn;
    uart0_handle.name = "uart0";

    uart0_handle.handle->BAUDDIV = 16; /* 115200bps */
    uart0_handle.handle->CTRL = CMSDK_UART_CTRL_RXIRQEN_Msk | CMSDK_UART_CTRL_RXEN_Msk | CMSDK_UART_CTRL_TXEN_Msk;
    NVIC_EnableIRQ(uart0_handle.irq_num);
    uart0_handle.handle->STATE = 0;

    return 0;
}
  • Aqui, com a ajuda da função da biblioteca C vsnprintf, a saída formatada é realizada e a comparação é simples, semelhante à printffunção

  • Crie qemu_mps2/driver/drv_uart.hum arquivo de cabeçalho serial

#ifndef __DRV_UART_H__
#define __DRV_UART_H__

#include <stdint.h>

int uart_init(void);
int os_printf(const char *fmt, ...);

#endif //__DRV_UART_H__

Modifique main.c para adicionar impressão de porta serial

  • Em qemu_mps2/application/main.c, crie outra tarefa. Observe que o espaço de pilha pode ser aumentado adequadamente para evitar que o estouro de pilha cause exceções.
#include "FreeRTOS.h"
#include "task.h"

#include <stdio.h>
#include <string.h>

#include "drv_uart.h"

#define TASK_TEST_PRIORITY      (tskIDLE_PRIORITY + 6)
#define TASK_TEST2_PRIORITY     (tskIDLE_PRIORITY + 8)

static void task_test_entry(void *pvParameters)
{
    
    
    uint32_t cnt = 0;

    os_printf("%s : enter\r\n", __func__);
    while (1)
    {
    
    
        vTaskDelay(1000);
        os_printf("%s : cnt %d\r\n", __func__, cnt++);
    }
}

static void task_test2_entry(void *pvParameters)
{
    
    
    uint32_t cnt = 0;

    os_printf("%s : enter\r\n", __func__);
    while (1)
    {
    
    
        vTaskDelay(2000);
        os_printf("%s : cnt %d\r\n", __func__, cnt++);
    }
}

void main( void )
{
    
    
    uart_init();
    os_printf("%s : enter\r\n", __func__);
    xTaskCreate(task_test_entry, "task_test", 512, NULL, TASK_TEST_PRIORITY, NULL);
    xTaskCreate(task_test2_entry, "task_test2", 512, NULL, TASK_TEST2_PRIORITY, NULL);
    vTaskStartScheduler();
    for( ;; );
}
  • Informações de saída da porta serial

insira a descrição da imagem aqui

  • A saída da porta serial é normal e as duas tarefas saem por sua vez

resumo

  • A função de impressão de saída da porta serial implementada principalmente neste artigo qemu mps2-an385pode ser facilmente realizada com a ajuda das funções da biblioteca C

  • No futuro, a função de terminal shell da porta serial poderá ser adicionada, e o recebimento e processamento da porta serial serão usados ​​nesse momento

Acho que você gosta

Origin blog.csdn.net/tcjy1000/article/details/132331194
Recomendado
Clasificación