This post was last edited by hotsauce1861 on 2018-11-10 12:59 I have been quite busy recently. Because of all kinds of things, I have become a little overworked and fat, so I still need to take care of my health. I stopped the evaluation of MM32 for a while because I was not familiar with the hardware, and the experts on the forum have already evaluated it in detail. After reading it, I also benefited a lot. Then I felt that I could transplant an operating system to try it out. Considering various factors, I decided to transplant FreeRTOS and give it a try. After tinkering for a night, I almost finished the most basic and pure system transplantation. Later, I will transplant a CLI to try it out depending on the situation. Interested friends can try it out by themselves. If you have any questions, you can communicate with us. There are many tutorials on the Internet, and it is actually OK to refer to STM32F103. However, the official has given tutorials, and there are also many demos in the source code. It is almost the same to refer to the demos to modify them.
Official porting tutorial link address https://www.freertos.org/porting ... erent-hardware.html Source code download link https://www.freertos.org/FreeRTOS-quick-start-guide.html The work required for porting is briefly summarized as follows:
1 FreeRTOSConfig.h This file can be copied from
FreeRTOSv10.1.1\FreeRTOS\Demo\CORTEX_M0_STM32F0518_IAR\FreeRTOSConfig.h in the source code.
2 prot.c portmacro.h FreeRTOSv10.1.1\FreeRTOS\Source\portable\RVDS\ARM_CM0 in the source code path
If it is other compilers, you need to select them separately. Keil uses the files under RVDS Problems encountered: Everything went smoothly during the porting. Later, it was found that the timer did not play a role in task scheduling. In
port.c, the
prvSetupTimerInterrupt function re-initialized sys_tick and everything was normal. The modifications in the source code are not very clear. It’s annoying. There may be a problem with the macro definition. For details, please see the code main.c A test routine is written with two tasks, 1 The lighting task has a low priority. After the task starts, the light is on and blocked for 500 milliseconds 2 The light-off task has a high priority, so it will seize the CPU, then turn off the light, block for 1000 milliseconds and give up the CPU usage rights. After the light-on task is blocked, it will regain the CPU usage rights and then light up the LED again. So main.c is a program that flashes the LED every 500 milliseconds. , please post the code, this makes the article seem longer- #include "FreeRTOS.h" #include "task.h" #include "delay.h" #include "sys.h" #include "led.h" #include "HAL_gpio.h" #define STACK_SIZE 128 #define LED_OFF() do {GPIO_SetBits(GPIOA,GPIO_Pin_8);}while(0) #define LED_ON() do {GPIO_ResetBits(GPIOA,GPIO_Pin_8);}while(0) #define LED_TOGGLE() do {(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_8)) \ ?(GPIO_ResetBits(GPIOA,GPIO_Pin_8)) \ :(GPIO_SetBits(GPIOA,GPIO_Pin_8));} while(0) void prvSetupHardware(void); void vCreateFlashTasks(void); void vTaskCodeLEDON( void * pvParameters ); void vTaskCodeLEDOFF( void * pvParameters ); int main( void ) { /* Setup the microcontroller hardware for the demo.*/ prvSetupHardware(); /* Leave this function. */ vCreateFlashTasks(); /*Start the RTOS scheduler. */ vTaskStartScheduler(); /* Should never get here! */ } void prvSetupHardware(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStru cture); LED_OFF(); //System_Clock_Init(6); //delay_init(); //LED_ON(); } #if 1 void vCreateFlashTasks(void){ BaseType_t xReturned; TaskHandle_t xHandle = NULL; /* Create the task, storing the handle. */ xReturned = xTaskCreate( vTaskCodeLEDON, /* Function that implements the task. */ "LEDON", /* Text name for the task. */ STACK_SIZE, /* Stack size in words, not bytes. */ ( void * ) 1, /* Parameter passed into the task. */ tskIDLE_PRIORITY + 1,/* Priority at which the task is created. */ &xHandle ); /* Used to pass out the created task's handle. */ /* Create the task, storing the handle. */ xReturned = xTaskCreate( vTaskCodeLEDOFF, /* Function that implements the task. */ "LEDOFF", /* Text name for the task. */ STACK_SIZE, /* Stack size in words, not bytes. */ ( void * ) 1, /* Parameter passed into the task. */ tskIDLE_PRIORITY + 2, /* Priority at which the task is created. */ &xHandle ); /* Used to pass out the created task's handle. */ if( xReturned == pdPASS ) { /* The task was created. Use the task's handle to delete the task. */ //vTaskDelete( xHandle ); } } /* Task to be created. */ void vTaskCodeLEDOFF( void * pvParameters ) { /* The parameter value is expected to be 1 as 1 is passed in the pvParameters value in the call to xTaskCreate() below. configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); */ const TickType_t xDelay = 500 / portTICK_PERIOD_MS; for( ;; ) { LED_ON(); vTaskDelay(xDelay); } } /* Task to be created.*/ void vTaskCodeLEDON( void * pvParameters ) { /* The parameter value is expected to be 1 as 1 is passed in the pvParameters value in the call to xTaskCreate() below. configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); */ const TickType_t xDelay = 1000 / portTICK_PERIOD_MS; //LED_ON(); for( ;; ) { /* Task code goes here. */ LED_OFF(); vTaskDelay(xDelay); } } #endif
复制代码 Demo Addresshttps://github.com/hotsauce1861/MM32_FreeRTOS.git