栈空间分配
线程状态转换图:
- 系统滴答时钟
每个操作系统都存在一个系统时钟,是操作系统中最小的时钟单位。这个时钟负责系统和时间相关的一些操作。这个时钟由硬件定时器的定时中断产生。
系统时钟的频率需要根据芯片的处理能力来决定,
频率越快,内核函数介入系统运行的几率就越大,内核占用处理器的时间就越长,系统的复核就变大;
频率越小,时间处理精度又会不够;
在STM32平台上一般设置系统滴答频率为100Hz,即每个滴答时间为10ms。
在rtconfig.h中
/* RT-Thread Configuration */
/* RT-Thread Kernel */
#define RT_NAME_MAX 8
#define RT_ALIGN_SIZE 4
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 100
#define RT_DEBUG
#define RT_USING_OVERFLOW_CHECK
#define RT_DEBUG_INIT 0
#define RT_DEBUG_THREAD 0
#define RT_USING_HOOK
#define IDLE_THREAD_STACK_SIZE 256 //栈大小
...
------------------
board.c中有对时钟的设置函数
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Initializes the CPU, AHB and APB busses clocks
*/
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_MUL9;
RT_ASSERT(HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK);
/**Initializes the CPU, AHB and APB busses 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;
RT_ASSERT(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) == HAL_OK);
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / RT_TICK_PER_SECOND);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
}
-----------
系统滴答时钟中断处理函数
/**
* This is the timer interrupt service routine.
*
*/
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_IncTick();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
在drv_gpio.h中有对引脚IO的驱动配置
IO初始化:
void rt_pin_mode(rt_base_t pin , rt_base_t mode)
mode:
PIN_MODE_OUTPUT
PIN_MODE_INPUT
PIN_MODE_INPUT_PULLUP
PIN_MODE_INPUT_PULLDOWN
PIN_MODE_OUTPUT_OD
IO写入:
void rt_pin_write(rt_base_t pin , rt_base_t value)
value:
PIN_HIGH
PIN_LOW
IO读出:
int rt_pin_read(rt_base_t pin)
以LED灯点亮和熄灭为例:
void led_th(void)
{
/* 创建线程,名称是led_th,入口是led_th_entry*/
tid1 = rt_thread_create("led_th",
led_th_entry, RT_NULL,
THREAD_STACK_SIZE, //设置线程在栈中的内存空间
THREAD_PRIORITY, THREAD_TIMESLICE);
/* 如果获得线程控制块,启动这个线程 */
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
}
-------------
入口函数:
static void led_th_entry(void *parameter)
{
rt_pin_mode(14,PIN_MODE_OUTPUT);
while (1)
{
rt_pin_write(14,PIN_LOW);
rt_kprintf("led on\n");
rt_thread_mdelay(500);
rt_pin_write(14,PIN_HIGH);
rt_kprintf("led off\n");
rt_thread_mdelay(500);
}
}
主函数:
int main(void)
{
led_th();
return 0;
}
先将线程栈空间大小设置一个固定值(比如2048),在线程运行时通过查看线程栈的使用情况,再根据使用的情况合理修改设置栈空间的大小,一般栈空间最大使用量设置为70%