Library 1 – sterownik silnika krokowego na STM32F429 DISCO (part 2).

Projekt oparty został na systemie czasu rzeczywistego Keil RTX w wersji 5 (RTX5) implementującego CMSIS-RTOS2 jako natywny interfejs RTOS dla urządzeń opartych na procesorach Arm Cortex-M.

Projekt do pobrania z: https://github.com/PiotrPoterala/stm32f429i-disco_stepper_motor

oraz biblioteki: https://github.com/PiotrPoterala/PP_Library

Utworzenie projektu opartego na RTX5

  1. Stworzyć nowy projekt i wybrać mikrokontroler, pod który będzie pisane oprogramowanie,
  2. W oknie Menage Run-Time Enviroment zaznaczyć Device::Startup, CMSIS::CORE oraz CMSIS::RTOS2(API)::KEIL RTX5,
  3. Kliknąć OK i upewnić się, że w drzewie projektu pojawiły się odpowiednie pliki w tym RTX_Config.h oraz RTX_Config.c
  1. Skonfigurować RTOS’a przy pomocy RTX_Config.h. Na potrzeby opisywanego projektu należy zwiększyć:
    • rozmiar globalnej pamięci dynamicznej do 32kB,
    • częstotliwość taktowania jądra do 100kHz (domyślnie jest 1kHz),
    • domyślny rozmiar stosu zarezerwowany dla danego wątku do 1kB.

Widok pliku RTX_Config.h po przejściu do zakładki Configuration Wizard (dostępna w dolnym, lewym rogu okna edycji pliku):

  1. Skonfigurować startup_stm32f429xx.s.  Plik  służy do ustawienia:
    • rozmiaru stosu używanego przez wyjątki i procedury obsługi przerwań (ISR),
    • rozmiaru sterty używanej przez funkcje alokacji pamięci (ponieważ w projekcie wykorzystywany jest dynamiczny przydział pamięci do tworzenie egzemplarzy obiektów, należy zwiększyć rozmiar sterty do co najmniej 1kB) .
startup_stm32f429xx.s
; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00001024

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

Uruchomienie systemu

W celu zainicjowania pracy RTX5 funkcja main() powinna implementować następujące elementy w podanej kolejności:

  1. Konfiguracja oraz aktualizacja zegara rdzenia systemu przy pomocy odpowiedniej funkcji CMSIS-Core (Cortex-M): wywołanie SystemCoreClockUpdate() wewnątrz funkcji RCC_Config(),
  2. Inicjalizacja i konfiguracja sprzętu, w tym urządzeń peryferyjnych, pamięci, pinów i systemu przerwań,
  3. Inicjalizacja jądra CMSIS-RTOS: osKernelInitialize,
  4. Utworzenie wątków bezpośrednio w main(),
  5. Uruchomienie scheduler’a RTOS: osKernelStart.
main.cpp
int main (void) {
	
//1) Configuration clocks and update the system core clock using the respective CMSIS-Core (Cortex-M) 
  RCC_Config();
	
//2) Initialization and configuration of hardware including peripherals, memory, pins and the interrupt system.
  GPIO_Config();
  NVIC_Config();																									
  USART_Config();
	
	
//3) Initialize CMSIS-RTOS
  osKernelInitialize();  

...

//4) Create threads
  Init_vSecondThread(osPriorityBelowNormal);  
  Init_vRealizationFunctionThread(osPriorityNormal);  
  Init_vReceiveAndInterpretDataFromComUartThread (osPriorityHigh); 
	
//5) Start the RTOS scheduler
  osKernelStart();                      
  for (;;) {}
}

Wątki

W projekcie utworzono trzy wątki:

  1. vSecondThread: odpowiada za mruganie diodą z częstotliwością 1Hz. Mając najniższy priorytet, pełni dwie funkcje: sygnalizuje funkcjonowanie systemu oraz poprawność jego działania (jest najprostszą formą sprawdzenia czy, żaden z wątków nie został „zagłodzony”),
  2. vReceiveAndInterpretDataFromComUartThread: odpowiada za odbiór danych z portu USART, ich interpretację oraz przesłanie (z wykorzystaniem kolejki taskCommunicationQueues) do wątku „funkcyjnego”. Do vReceiveAndInterpretDataFromComUartThread, w pierwszej kolejności, trafiają AT komendy (przesyłane z PC) będące dla omawianego projektu formą interfejsu użytkownika,
  3. vRealizationFunctionThread: odpowiada za realizację podstawowych zadań projektu, a więc za obrót wirnika silnika o określony kąt, z określoną trajektorią prędkości obrotowej.

Aby wygenerować plik z szablonem wątku należy kliknąć prawym klawiszem na Source Group 1 w drzewie projektu, a następnie wybrać Add New Item to group. W pojawiającym się oknie, wybrać User Code Template -> CMSIS-RTOS2 Thread, wpisać nazwę tworzonego szablonu i kliknąć Add.

vSecondThread.cpp
#include "cmsis_os2.h"                          // CMSIS RTOS header file
 #include "input_signals.h"
 #include "RTX_Config.h"
 
 #define FREQUENCY_OF_SECOND_THREAD	1
 
osThreadId_t tid_vSecondThread;                        // thread id
 
void vSecondThread (void *argument);                   // thread function
 
int Init_vSecondThread  (osPriority_t priority) {
 
	const osThreadAttr_t thread_attr = {
		.stack_size = 256, 	
		.priority = priority	
	};
	
  tid_vSecondThread = osThreadNew(vSecondThread, NULL, &thread_attr);
	osThreadSetPriority (tid_vSecondThread, priority);
  if (tid_vSecondThread == NULL) {
    return(-1);
  }
 
  return(0);
}
 
void vSecondThread (void *argument) {
 
  while (1) {
    PIN_TOG(PORT_LED, LED1);  
    osDelay(OS_TICK_FREQ/FREQUENCY_OF_SECOND_THREAD);  
  }
}

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *