learn rtos
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

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();
}
}