You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
3.9 KiB
153 lines
3.9 KiB
4 months ago
|
#include "main.h"
|
||
|
#include "usart.h"
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
//================ 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();
|
||
|
}
|
||
|
}
|
||
|
|