[OpenHarmony] Migración del sistema de la versión 3.1 a STM32

[OpenHarmony] STM32F407 portabilidad del sistema versión 3.1

I. Introducción

Recientemente se lanzó oficialmente OpenHarmony 3.1, se mejoraron las capacidades básicas del sistema estándar (LiteOS-A) y el sistema pequeño (LiteOS-M) básicamente permaneció sin cambios y se volvió estable. Escribí un artículo sobre la migración de LiteOS a STM32 antes. La versión LiteOS aún no está incluida en OpenHarmony, y algunas funciones no son compatibles

Enlace del artículo de portabilidad: [OpenHarmony] Portabilidad de LiteOS-M a STM32 bajo VSCode

Para compensar este defecto, trasplanté el último LiteOS-M a la MCU y utilicé las últimas funciones del sistema. También estudié el proceso de migración de OpenHarmony a la MCU. No noté algunos detalles de la falla de trasplante anterior. Después de investigar, descubrí que el marco general sigue siendo muy claro. Por cierto, compartiré con ustedes el proceso de migración de OpenHarmony a MCU. Los tutoriales y códigos relevantes se encuentran en mis repositorios de Gitee y Github.

El entorno de desarrollo se desarrolla utilizando VSCode + GCC + OpenOCD, y la configuración del entorno se puede ver en el artículo anterior:

Enlace del blog: VSCode construye el entorno de desarrollo STM32

El Makefile utilizado en el método de trasplante y compilación se usa para compilar y construir. El najia recomendado oficialmente no se usa para construir. La descripción oficial del método de construcción de najia es bastante detallada, y también es el método principal. Si está interesado , puedes averiguarlo por ti mismo. Personalmente, prefiero Usar el método Make

2. Entorno de desarrollo

Plataforma de hardware :

20220404235342

Entorno de software :

VSCode, STM32CubeMX, herramientas Git

Base técnica :

  • El proyecto Makefile se generará usando la configuración STM32CubeMX
  • utilizará Git
  • Comprender un poco de sintaxis de archivos MAKE

3. Obtenga el código fuente y agregue dependencias de terceros

Tire del código en Gitee y elija la versión lanzada por 3.1: enlace

20220405000511

Tire a una carpeta local:

git clone https://gitee.com/openharmony/kernel_liteos_m.git

Jalar:

20220405000024

Luego vaya a kernel_liteos_m en git, cree un nuevo directorio de terceros e ingrese

cd kernel_liteos_m 
mkdir ./third_party
cd third_party

Luego extraiga los archivos dependientes de terceros al local

git clone https://gitee.com/openharmony/third_party_bounds_checking_function.git ./bounds_checking_function
git clone https://gitee.com/openharmony/third_party_cmsis.git ./cmsis
git clone https://gitee.com/openharmony/third_party_musl.git ./musl

El tirón se hace de la siguiente manera:

20220405095206

Cuarto, importe el proyecto Makefile STM32

Use STM32CubeMX para crear un nuevo proyecto STM32F407ZGT6 y expórtelo al directorio de objetivos en el directorio liteos. Baidu puede encontrar el tutorial detallado sobre cómo exportar el proyecto Makefile desde STM32CubeMX. Simplemente lo escribiré. En el proyecto CubeMX, configuramos el árbol del reloj:

Por favor agregue la descripción de la imagen

Abra el puerto serie y el puerto serie DMA para facilitar la depuración:

20220405001922

Modifique el reloj básico del retraso de la biblioteca HAL y cámbielo a otros temporizadores que no sean SysTick para evitar conflictos entre el temporizador de retraso de la biblioteca HAL y el temporizador de ejecución del sistema:

20220405001829

Configurar las opciones del proyecto:

20220405002301

20220405002320

Coloque el proyecto generado en el directorio de destino de origen:

20220405002556

Debajo del objetivo, hay varios ejemplos de chips basados ​​en la arquitectura chip risc-v y sifive risc-v, no nos preocupamos por él

Cinco, configure el archivo de compilación

Abra el directorio de origen en VSCode:

20220405094125

Cree un nuevo archivo My_Path.mk en el directorio del proyecto bajo nuestro Destino para ayudar en la compilación y construcción, y agregue el siguiente código Makefile al archivo a su vez

localizar el directorio de nivel superior

# Topdir
LITEOSTOPDIR := ../../
LITEOSTOPDIR := $(realpath $(LITEOSTOPDIR))

Rutas y archivos comunes del kernel:

# Common
C_SOURCES   +=  $(wildcard $(LITEOSTOPDIR)/kernel/src/*.c) \
				$(wildcard $(LITEOSTOPDIR)/kernel/src/mm/*.c) \
				$(wildcard $(LITEOSTOPDIR)/components/cpup/*.c) \
				$(wildcard $(LITEOSTOPDIR)/components/power/*.c) \
				$(wildcard $(LITEOSTOPDIR)/components/backtrace/*.c) \
				$(wildcard $(LITEOSTOPDIR)/components/exchook/*.c) \
				$(wildcard $(LITEOSTOPDIR)/components/signal/*.c) \
                $(wildcard $(LITEOSTOPDIR)/utils/*.c)

C_INCLUDES  +=  -I$(LITEOSTOPDIR)/utils \
				-I$(LITEOSTOPDIR)/kernel/include \
				-I$(LITEOSTOPDIR)/components/cpup \
				-I$(LITEOSTOPDIR)/components/power \
				-I$(LITEOSTOPDIR)/components/backtrace \
				-I$(LITEOSTOPDIR)/components/exchook \
				-I$(LITEOSTOPDIR)/components/signal

Directorios y archivos de bibliotecas de terceros:

# Third party related
C_SOURCES    += $(wildcard $(LITEOSTOPDIR)/third_party/bounds_checking_function/src/*.c)\
				$(wildcard $(LITEOSTOPDIR)/kal/cmsis/*.c)\
				$(wildcard $(LITEOSTOPDIR)/kal/posix/src/*.c)

C_INCLUDES   += -I$(LITEOSTOPDIR)/third_party/bounds_checking_function/include \
				-I$(LITEOSTOPDIR)/third_party/bounds_checking_function/src\
				-I$(LITEOSTOPDIR)/third_party/cmsis/CMSIS/RTOS2/Include \
				-I$(LITEOSTOPDIR)/third_party/musl/porting/liteos_m/kernel/include\
				-I$(LITEOSTOPDIR)/kal/cmsis \
				-I$(LITEOSTOPDIR)/kal/posix/include \
				-I$(LITEOSTOPDIR)/kal/posix/musl_src/internal

Archivos personales y rutas, ubicación reservada:

# My file
C_SOURCES    += 

C_INCLUDES   += 

Archivos relacionados con la arquitectura, seleccione el directorio de archivos de arquitectura relacionados con M4

# Arch related
ASM_SOURCES   += $(wildcard $(LITEOSTOPDIR)/arch/arm/cortex-m4/gcc/*.s)

ASMS_SOURCES  += $(wildcard $(LITEOSTOPDIR)/arch/arm/cortex-m4/gcc/*.S)

C_SOURCES     += $(wildcard $(LITEOSTOPDIR)/arch/arm/cortex-m4/gcc/*.c)

C_INCLUDES    += -I. \
                 -I$(LITEOSTOPDIR)/arch/include \
                 -I$(LITEOSTOPDIR)/arch/arm/cortex-m4/gcc

CFLAGS        += -nostdinc -nostdlib
ASFLAGS       += -imacros $(LITEOSTOPDIR)/kernel/include/los_config.h -DCLZ=CLZ

# list of ASM .S program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMS_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASMS_SOURCES)))

$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
	$(CC) -c $(CFLAGS) $(ASFLAGS) $< -o $@

Luego llame a nuestro archivo MAKE en la siguiente ubicación en el archivo MAKE del proyecto:

20220405101840

6. Agregar archivo de configuración del proyecto

Queremos agregar un archivo de configuración del proyecto para configurar y recortar el núcleo. En el directorio del proyecto en Destinos, agregue un archivo target_config.h con los siguientes contenidos:

/**@defgroup los_config System configuration items
 * @ingroup kernel
 */

#ifndef _TARGET_CONFIG_H
#define _TARGET_CONFIG_H

#include "stm32f4xx.h"
#include "stm32f4xx_it.h"

#ifdef __cplusplus
#if __cplusplus
extern "C"
{
    
    
#endif /* __cplusplus */
#endif /* __cplusplus */

/*=============================================================================
                                        System clock module configuration
=============================================================================*/
#define OS_SYS_CLOCK SystemCoreClock
#define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL)
#define LOSCFG_BASE_CORE_TICK_HW_TIME 0
#define LOSCFG_BASE_CORE_TICK_WTIMER 0
#define LOSCFG_BASE_CORE_TICK_RESPONSE_MAX SysTick_LOAD_RELOAD_Msk

/*=============================================================================
                                        Hardware interrupt module configuration
=============================================================================*/
#define LOSCFG_PLATFORM_HWI 0
#define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT 0
#define LOSCFG_PLATFORM_HWI_LIMIT 128

/*=============================================================================
                                        Openharmony Kernel configuration
=============================================================================*/

/*=============================================================================
                                       Task module configuration
=============================================================================*/
#define LOSCFG_BASE_CORE_TSK_LIMIT 24
#define LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE (0x500U)
#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE (0x2D0U)
#define LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE (0x130U)
#define LOSCFG_BASE_CORE_TIMESLICE 1
#define LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT 20000
/*=============================================================================
                                       Semaphore module configuration
=============================================================================*/
#define LOSCFG_BASE_IPC_SEM 1
#define LOSCFG_BASE_IPC_SEM_LIMIT 48

/*=============================================================================
                                       Mutex module configuration
=============================================================================*/
#define LOSCFG_BASE_IPC_MUX 1
#define LOSCFG_BASE_IPC_MUX_LIMIT 24
/*=============================================================================
                                       Queue module configuration
=============================================================================*/
#define LOSCFG_BASE_IPC_QUEUE 1
#define LOSCFG_BASE_IPC_QUEUE_LIMIT 24
/*=============================================================================
                                       Software timer module configuration
=============================================================================*/
#define LOSCFG_BASE_CORE_SWTMR 1
#define LOSCFG_BASE_CORE_SWTMR_ALIGN 1
#define LOSCFG_BASE_CORE_SWTMR_LIMIT 48
/*=============================================================================
                                       Memory module configuration
=============================================================================*/
#define LOSCFG_MEM_MUL_POOL 1
#define OS_SYS_MEM_NUM 20
/*=============================================================================
                                       Exception module configuration
=============================================================================*/
#define LOSCFG_PLATFORM_EXC 1

/*=============================================================================
                                        TestSuite configuration
=============================================================================*/
#define LOSCFG_TEST 0

#ifndef LOSCFG_BACKTRACE_TYPE
#define LOSCFG_BACKTRACE_TYPE 1
#endif
/**
 * @ingroup los_config
 * Configuration backtrace depth.
 */
#ifndef LOSCFG_BACKTRACE_DEPTH
#define LOSCFG_BACKTRACE_DEPTH 15
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */

#endif /* _TARGET_CONFIG_H */

El significado y las funciones de estos archivos de configuración se modifican principalmente para los_config.h, ¡y los analizaré más adelante!

Una vez que se completa el archivo de configuración, se compila el código y el task.json utilizado para la compilación se usa para una configuración rápida.Como mencioné en la sección sobre la configuración del entorno, la ruta de modificación es la siguiente:

20220405103400

Luego compile, la compilación se completa de la siguiente manera:

20220405103519

Siete, modifica el script del enlace.

La dirección inicial de la pila definida en el targets\OpenHarmony_Demo\STM32F407ZGTx_FLASH.ldscript es 0x20000000:

/* Lowest address of the user mode stack */
_sstack = 0x20000000;    /* start of RAM */

Agregue la dirección inicial de la sección .text, que es la sintaxis para vincular secuencias de comandos, y asigne la dirección de ubicación actual a _stext:

   _stext = .;

Las ubicaciones específicas son las siguientes:

20220405113138

Ocho, modifica la función de servicio de interrupción.

Aunque la compilación se completa, incluso si el programa se descarga, no puede ejecutarse normalmente, porque el código de configuración anterior se escribió

/*=============================================================================
                                        Hardware interrupt module configuration
=============================================================================*/
#define LOSCFG_PLATFORM_HWI 0
#define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT 0
#define LOSCFG_PLATFORM_HWI_LIMIT 128

No utiliza la toma de control de interrupciones de hardware, por lo que debemos agregar la interfaz del kernel a las dos funciones importantes del servicio de interrupciones que se ejecutan en el sistema, para que la gestión de interrupciones de STM32 pueda pasar a la función de procesamiento del kernel:

Ingrese el targets\OpenHarmony_Demo\Core\Src\stm32f4xx_it.carchivo y agregue las siguientes funciones a las siguientes dos funciones:

Ingrese la función de manejo de excepciones LiteOS HalPendSV en la excepción PendSV para realizar operaciones de cambio de tareas

void PendSV_Handler(void)
{
    
    
    /* USER CODE BEGIN PendSV_IRQn 0 */
    HalPendSV();
    /* USER CODE END PendSV_IRQn 0 */
    /* USER CODE BEGIN PendSV_IRQn 1 */

    /* USER CODE END PendSV_IRQn 1 */
}

Agregue la función OsTickHandler a la función de servicio de interrupción de SysTick para proporcionar una base de tiempo para el sistema

void SysTick_Handler(void)
{
    
    
    /* USER CODE BEGIN SysTick_IRQn 0 */
    OsTickHandler();
    /* USER CODE END SysTick_IRQn 0 */

    /* USER CODE BEGIN SysTick_IRQn 1 */

    /* USER CODE END SysTick_IRQn 1 */
}

Agregue un archivo de encabezado que contenga:

#include "los_arch_context.h"
#include "los_tick.h"

Nueve, modifique la asignación del puerto serie

Hemos abierto el puerto serie antes, por lo que asignamos la capa inferior de printf al puerto serie para que el kernel llame para facilitar la depuración. Incluya el archivo de encabezado en main.c include "stdio.h"y luego agregue la interfaz de la capa inferior. Cuando la capa inferior la interfaz no se inicia, use el método de bloqueo para generar datos. Después de que se inicie el sistema, la transmisión DMA se usa para evitar conflictos de uso de DMA a través de semáforos:

#if 1
int _write(int fd, char *ptr, int len)
{
    
    
    osStatus_t result;
    osKernelState_t state;

    if (osKernelGetState() == osKernelInactive)
    {
    
    
        //系统未启动时不使用DMA
        HAL_UART_Transmit(&huart1, ptr, len, 0xFFFF);
        return len;
    }
    else
    {
    
    
        //获取信号,如果上一个DMA传输完成
        //信号就能获取到,没有传输完成任务就挂起
        //等到传输完成再恢复
        result = osSemaphoreAcquire(UART1_TX_DMA_SemaphoreHandle, 0xFFFF);
        if (result == osOK)
        {
    
    
            HAL_UART_Transmit_DMA(&huart1, ptr, len); //获取成功,发送数据
            return len;
        }
        else
        {
    
    
            return -1; //获取失败
        }
    }
}
#endif

// DMA 传输完成后会调用传输完成回调函数,在该函数中我们释放信号
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    
    
    if (huart->Instance == huart1.Instance)
        osSemaphoreRelease(UART1_TX_DMA_SemaphoreHandle);
}

10. Agregar tareas de prueba

Luego agregue una tarea de prueba y un semáforo a la función principal:

Definiciones de variables:

osSemaphoreId_t UART1_TX_DMA_SemaphoreHandle;
const osSemaphoreAttr_t UART1_TX_DMA_Semaphore_attributes = {
    
    
    .name = "UART1_TX_DMA_Semaphore",
};

osThreadId_t uart_taskHandle;
const osThreadAttr_t uart_task_attributes = {
    
    
    .name = "uart_task",
    .stack_size = 512 * 2,
    .priority = (osPriority_t)osPriorityNormal3,
};

inicialización:

    osKernelInitialize();
    UART1_TX_DMA_SemaphoreHandle = osSemaphoreNew(1, 1, &UART1_TX_DMA_Semaphore_attributes);
    uart_taskHandle = osThreadNew(Uart_Task, NULL, &uart_task_attributes);
    osKernelStart();

Entidad de tarea:

void Uart_Task(void *argument);
void Uart_Task(void *argument)
{
    
    
    while (1)
    {
    
    
        printf("System Runing!!!\r\n");
        osDelay(1000);
    }
}

Compilar el código:

20220405113340

11. Fenómeno experimental

Información de funcionamiento normal del sistema de impresión del puerto serie

20220405130651

12. Código fuente del proyecto

El código central del proyecto de ejemplo se coloca en Gitee y debe ser recogido por usted mismo.

Gitee: https://gitee.com/JeckXu666/openharmony-for-mcu

Supongo que te gusta

Origin blog.csdn.net/qq_45396672/article/details/123971394
Recomendado
Clasificación