Implementação da Máquina de Estados QP no STM32F4 com Keil

Primeiramente, utilize o STM32CubeMX para gerar um programa básico de piscar LED, contendo apenas as inicializações necessárias para validação inicial da funcionalidade.

Após a confirmação do funcionamento básico, adicione as três pastas necessárias do QPC ao diretório do projeto e crie novos arquivos no mesmo local.

Como estamos utilizando uma placa de teste STM32F407ZGT6, podemos limpar o diretório da pasta ports, mantendo apenas o arm-cm.

Observa-se que esta pasta contém quatro subpastas: qk, qutest, qv e qxk. Estas representam diferentes núcleos da máquina de estados: qk: Núcleo preemptivo (não bloqueante) qxk: Núcleo preemptivo (bloqueante) qv: Núcleo cooperativo (RTC) qutest: Núcleo de teste (não utilizar)

No Keil, crie novos grupos de arquivos e inclua os arquivos correspondantes. Para este exemplo, utilizaremos o núcleo qv, portanto, selecione os arquivos da pasta qv.

Ao selecionar os arquivos do qv, certifique-se de escolher a versão armclang.

A estrutura de inclusão deve seguir a seguinte organização:

É importante notar que a não inclusão dos arquivos gerados na pasta APP resultará no seguinte erro:

Após importar os arquivos gerados para a pasta APP e organizar corretamente as dependências, a compilação deve ser bem-sucedida, concluindo esta etapa inicial.

A seguir, estabeleça a base de tempo adicionando a seguinte função ao manipulador de serviço SysTick:

void QF_onClockTick(void)
{
    QF_TICK_X(0U, (void *)0); /* realiza o processamento do tick de relógio do QF */
}

Como mostrado abaixo:

Durante a compilação, é necessário marcar a opção MicrLib; caso contrário, o código pode funcionar em modo de depuração, mas falhará na execução real. A cadeia de compilação também deve ser da versão AC6.

  Neste ponto, ainda pode ser que o código não execute corretamente. Verifique se a prioridade do SysTick está configurada adequadamente. Uma configuração incorreta de prioridade também impedirá a execução normal do código, pois o QP redefine todas as prioridades durante sua operação.

Portanto, após a reinicialização, devemos redefinir as prioridades:

void QF_onStartup(void)
{
    NVIC_SetPriority(SysTick_IRQn, 1); // Define prioridade de interrupção
}

A função QF_onStartup é executada imediatamente após a inicialização da máquina de estados e geralmente contém inicializações de nível de placa, incluindo prioridades e periféricos. QF_onCleanup é executada durante o encerramento. QV_onIdle é executada na fase ociosa, funcionando como um gancho de ociosidade.

Se você estiver usando código gerado pelo Cube ou tiver código de inicialização BSP fixo, ainda pode colocar o código em QF_onStartup. Por exemplo:

void QF_onStartup(void)
{
    HAL_Init();
    SystemClock_Config();

    MX_GPIO_Init();
    MX_USART1_UART_Init();
}

Código-fonte disponível em: https://gitee.com/lzc56/qp-stm32-f407-zgt6-state-machine.git

Tags: STM32F4 QP Máquina de Estados Keil ARM-Cortex-M

Publicado em 7-14 16:13