All for Joomla All for Webmasters

Sistema mínimo da API CMSIS RTOS para ARM Cortex STM32

Conforme já sabemos, a arquitetura de microcontroladores ARM Cortex de 32 bits é bem mais potente e também mais complexa em relação a microcontroladores comuns de 8 ou 16 bits como, por exemplo, um Microchip PIC. Exatamente por essa maior complexidade, o software para esses dispositivos é usualmente programado em linguagem C e, recentemente, houve um esforço de várias indústrias no desenvolvimento e adoção do padrão CMSIS (Cortex Microcontroller Software Standard) que consiste um framework para aplicações embarcadas que visa padronizar a API utilizada na programação desses microcontroladores, simplificando todos os passos no desenvolvimento e manutenção do código-fonte.

Para demonstrarmos o início da utilização do padrão CMSIS e programação dos microcontroladores Cortex-M para leigos, publicamos a seguir um exemplo de código-fonte escrito em C com o intuito de piscar um LED conectado no pino 6 da porta I/O de propósito geral C (GPIOC) para demonstrar o quanto o código fica mais inteligível em relação a uma programação menos profissional com referências diretas a constantes binárias ou hexadecimais. Para o software não ficar muito trivial, estabelecemos um sistema operacional de tempo real (RTOS), também padronizado pelo CMSIS, e configuramos uma thread (código de execução paralela) com prioridade normal para execução do código de acendimento e desligamento do LED com atraso de tempo.

O leitor pode estranhar a ausência de código para programação da inicialização do microcontrolador. Pois uma das finalidades do CMSIS é justamente padronizar e facilitar também o código-fonte de toda a inicialização do microcontrolador (e independente da fabricante, família e modelo da melhor maneira possível). Neste exemplo, bastamos selecionar as opções "ARM::CMSIS:CORE:", "ARM::CMSIS:RTOS:", "Keil::Startup", "Keil::GPIO", "Keil::Device:StdPeriph Drives:GPIO"e "Keil::Device:StdPeriph Drives:RCC" em "Manage Run-Time Environment" na IDE Keil uVision e criarmos um novo arquivo template main em C. Impossível ser mais simples e inteligível: procure um código-fonte similar sem a utilização do CMSIS e perceba a dificuldade em ler o código, compreender rapidamente seu propósito e ter que decorar inúmeras constantes e posicionamento de bits que foram substituídos por estruturas (struct) com descrições melhores em C no CMSIS:

/*----------------------------------------------------------------------------
 * CMSIS-RTOS 'main' function template
 *---------------------------------------------------------------------------*/

#define osObjectsPublic                     // define objects in main module
#include "osObjects.h"                      // RTOS object definitions
#include "stm32f10x.h"                  // Device header
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

#define LEDG            GPIO_Pin_6
#define LEDPORT         GPIOC
#define LEDPORTCLK      RCC_APB2Periph_GPIOC

// Função thread piscar led
void Piscar (void const *argumento){
	while (1){
		GPIO_SetBits(LEDPORT, LEDG);
		osDelay(100);
		GPIO_ResetBits(LEDPORT, LEDG);
		osDelay(100);
	}
}

// Definir prioridade e definir thread
osThreadDef(Piscar, osPriorityNormal, 1, 0);

/*
 * main: initialize and start the system
 */
int main (void) {
  GPIO_InitTypeDef GPIO_InitStructure;
	
	//SystemCoreClockUpdate();
  osKernelInitialize ();                    // initialize CMSIS-RTOS
		
  //GPIO structure used to initialize port
	 RCC_APB2PeriphClockCmd(LEDPORTCLK, ENABLE);
  //select pins to initialize LED
  GPIO_InitStructure.GPIO_Pin = LEDG;
  //select output push-pull mode
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  //highest speed available
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(LEDPORT, &GPIO_InitStructure);
  //using same structure we will initialize button pin
 	
  // create 'thread' functions that start executing,
  // example: tid_name = osThreadCreate (osThread(name), NULL);
	osThreadCreate (osThread(Piscar), NULL);

	osKernelStart ();                         // start thread execution 
}

Deixe um comentário

Certifique-se de preencher os campos indicados com (*). Não é permitido código HTML.