#include "main.h" #include "usart.h" #include #include //================ debug uart config =====================// #define ITM_PORT8(n) (*(volatile unsigned char *)(0xe0000000 + 4*(n))) #define ITM_PORT16(n) (*(volatile unsigned short *)(0xe0000000 + 4*(n))) #define ITM_PORT32(n) (*(volatile unsigned long *)(0xe0000000 + 4*(n))) #define DEMCR (*(volatile unsigned long *)(0xE000EDFC)) #define TRCENA 0X01000000 //========================================================// #define STACK_SIZE 1024 #define MAX_TASK_NUM 5 struct Thread { unsigned long ip; unsigned int *sp; }; typedef struct PCB { struct Thread thread; int pid; volatile long state; /* -1 idle, 0 runnable */ unsigned int stack[STACK_SIZE]; struct PCB *next; } tPCB; tPCB task[MAX_TASK_NUM]; tPCB *current_task = NULL; tPCB *next_task = NULL; void tTaskRunFirst(void); void tTaskSwitch(void); void tTask_schedule(void); void my_process(void) { int i = 0; while (1) { i++; if (i % 100 == 0) { printf("this is process %d - \r\n", current_task->pid); tTask_schedule(); printf("this is process %d + \r\n", current_task->pid); } } } void StackInit (tPCB * task, void (*entry)(void), unsigned int ** stack) { (*stack)--; **stack = (unsigned long)entry; // the entry } void tTaskInit(int task_num) { int i = 0; task[i].pid = i; task[i].state = 0; task[i].thread.ip = (unsigned long)my_process; task[i].thread.sp = &task[i].stack[STACK_SIZE - 1]; task[i].next = &task[i]; StackInit(&task[i], my_process, &(task[i].thread.sp)); for (i = 1; i < task_num; i++) { task[i].pid = i; task[i].state = 0; task[i].thread.ip = (unsigned long)my_process; task[i].thread.sp = &task[i].stack[STACK_SIZE - 1]; task[i].next = task[i - 1].next; task[i - 1].next = &task[i]; StackInit(&task[i], my_process, &(task[i].thread.sp)); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 }; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6; if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL; if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } #define printf USART_SendString int main(void) { HAL_Init(); SystemClock_Config(); MX_USART1_UART_Init(); printf("Compile time\r\n"); printf("Init tasks\r\n"); tTaskInit(MAX_TASK_NUM); /* run the first task */ current_task = &task[0]; tTaskRunFirst(); } void tTask_schedule(void) { if (current_task == NULL || current_task->next == NULL) { return; } printf("enter task schedule ->\r\n"); next_task = current_task->next; if (next_task->state == 0) { /* switch to next process */ tTaskSwitch(); } }