RTT移植STM32之创建进程

目录

1.RTT系统启动

2.创建自己的进程


1.RTT系统启动

RTT系统将main函数重定义在$Sub$$main(void)中,即程序运行顺序如下:

LDR     R0, =SystemInit
BLX     R0               
LDR     R0, =__main
int $Sub$$main(void)
{
    rt_hw_interrupt_disable();
    rtthread_startup();
    return 0;
}

 

int rtthread_startup(void)
{
    rt_hw_interrupt_disable();

    /* board level initialization
     * NOTE: please initialize heap inside board initialization.
     */
    rt_hw_board_init();

    /* show RT-Thread version */
    rt_show_version();

    /* timer system initialization */
    rt_system_timer_init();

    /* scheduler system initialization */
    rt_system_scheduler_init();

#ifdef RT_USING_SIGNALS
    /* signal system initialization */
    rt_system_signal_init();
#endif

    /* create init_thread */
    rt_application_init();

    /* timer thread initialization */
    rt_system_timer_thread_init();

    /* idle thread initialization */
    rt_thread_idle_init();

    /* start scheduler */
    rt_system_scheduler_start();

    /* never reach here */
    return 0;
}

rtthread_startup函数中 rt_hw_board_init()在boardc中,是对板子硬件的初始化,程序如下

extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN  ((void *)&Image$$RW_IRAM1$$ZI$$Limit)
#define STM32_SRAM_SIZE 64
#define STM32_SRAM_END (0x20000000 + STM32_SRAM_SIZE * 1024)
void rt_hw_board_init()
{	
	/* System Clock Update */
	RCC_Configuration();
	GPIO_InitTypeDef gpioInit;

    //打开GPIOB的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE);
    //LED上拉连接GPIOB 12引脚,所以设置如下,推挽输出,Pin12,2MHz输出速度
    gpioInit.GPIO_Mode=GPIO_Mode_Out_PP;
    gpioInit.GPIO_Pin=GPIO_Pin_5;
    gpioInit.GPIO_Speed=GPIO_Speed_2MHz;
    GPIO_Init(GPIOB,&gpioInit);
	GPIO_Init(GPIOE,&gpioInit);
	
	  gpioInit.GPIO_Mode=GPIO_Mode_Out_PP;
    gpioInit.GPIO_Pin=GPIO_Pin_12;
    gpioInit.GPIO_Speed=GPIO_Speed_2MHz;
    GPIO_Init(GPIOB,&gpioInit);
	/* System Tick Configuration */
	_SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND)                                                                                                                         ;

    /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif
    
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
	rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
    
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    //rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
		rt_system_heap_init(HEAP_BEGIN, (void *)STM32_SRAM_END);
#endif
}

其中rt_system_heap_init(HEAP_BEGIN, (void *)STM32_SRAM_END)是对堆heap的初始化,HEAP_BEGIN是从

Image$$RW_IRAM1$$ZI$$Limit

开始,到指定大小后结束。

然后回到rtthread_startup()对RTT系统定时器,调度器,信号量等功能初始化,再调用rt_application_init()创建main()进程以回到用户自己的main()中,后面开启调度器,进入main()函数中。rt_application_init()程序如下:

oid rt_application_init(void)
{
    rt_thread_t tid;

#ifdef RT_USING_HEAP
    tid = rt_thread_create("main", main_thread_entry, RT_NULL,
                           RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
    RT_ASSERT(tid != RT_NULL);
#else
    rt_err_t result;

    tid = &main_thread;
    result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,
                            main_stack, sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20);
    RT_ASSERT(result == RT_EOK);
	
    /* if not define RT_USING_HEAP, using to eliminate the warning */
    (void)result;
#endif

    rt_thread_startup(tid);
}

2.创建自己的进程

在main()可以先对模块功能初始化,然后创建进程。main()函数运行完自己会把自己(注销?)挂起,反正不会运行自己了。程序如下:

/***************************************************************************************
 备注:
 *
***************************************************************************************/
	
#include "stm32f10x.h"	
#include "stm32f10x_gpio.h"
#include "w5500.h"
#include "24c02.h" 
#include "spi.h"
#include "cd4051.h"
#include "adc.h"
#include "bsp_485.h"
#include "ioinput.h"
#include 
#include "led.h"
#include "oled.h"
#include "HT16K33.h"
#include "display.h"
#include "bsp_adc.h"
#include "pt100.h"
#include 
#include "rtthread.h"  
//#include "application.h"
extern float Tem[8];
extern u8 number[20];
extern unsigned char Read_W5500_1Byte(unsigned short reg);

u8   flag_usart =0 ;   //串口1接收标志位
u8 key[6];
extern __IO uint16_t ADC_ConvertedValue[4]; 
float ADC_ConvertedValueLocal[4];  
void AD2(void);
void VibAndTem(void);

static rt_thread_t thread1=RT_NULL;
static rt_thread_t thread2=RT_NULL;
static rt_thread_t thread3=RT_NULL;
static rt_thread_t thread4=RT_NULL;
static rt_thread_t thread5=RT_NULL;
static rt_thread_t thread6=RT_NULL;
static void thread1_entry (void *parameter);
static void thread2_entry (void *parameter);
static void thread3_entry (void *parameter);
static void thread4_entry (void *parameter);
static void thread5_entry (void *parameter);
static void thread6_entry (void *parameter);
 /* 定时器的控制块 */
static rt_timer_t timer1;
static rt_timer_t timer2;
u8 cnt;
u8 Y_num[8];
u8 R_num[8];

/* 定时器1超时函数 */
static void timeout1(void *parameter)
{
  
	 // if (   thread3 != RT_NULL)  
       rt_thread_resume (thread3);
			rt_schedule();	


    /* 运行第10次,停止周期定时器 */
/*    if (cnt++ >= 9)
    {
        rt_timer_stop(timer1);
        rt_kprintf("periodic timer was stopped! \n");
    }
	*/
}

/* 定时器2超时函数 */
static void timeout2(void *parameter)
{
   			 rt_thread_resume (thread6);
			rt_schedule();	
}

int timer_sample(void)
{
    /* 创建定时器1  周期定时器 */
    timer1 = rt_timer_create("timer1", timeout1,
                             RT_NULL, 10,
                             RT_TIMER_FLAG_PERIODIC);

    /* 启动定时器1 */
    if (timer1 != RT_NULL) 
			rt_timer_start(timer1);
	    /* 创建定时器2  周期定时器 */
    timer2 = rt_timer_create("timer2", timeout2,
                             RT_NULL, 10,
                             RT_TIMER_FLAG_PERIODIC);

    /* 启动定时器1 */
    if (timer2 != RT_NULL) 
	//		rt_timer_start(timer2);
		
		
    return 0;
}

static void thread1_entry(void* parameter)  
{
while(1)  
 WEB();
}
  
static void thread2_entry(void* parameter)  
{  
   while(1){
        //点亮LED
        GPIO_ResetBits(GPIOB,GPIO_Pin_12);
        //延时0.5s
        rt_thread_delay(RT_TICK_PER_SECOND);
        //关闭LED
        GPIO_SetBits(GPIOB,GPIO_Pin_12);
        //延时0.5s
        rt_thread_delay(RT_TICK_PER_SECOND);
		 cnt++;
		// analogArry[1]=cnt;
	//	 Tem[0]=(float)cnt;
    }

}  
 static void thread3_entry(void* parameter)  
{  
  while(1)
	{
   VibAndTem();
	 DISPLAYfloat(Tem[0],Tem[1],Tem[2],Tem[3],Tem[4],Tem[5],Tem[6],Tem[7]);

		 rt_thread_suspend(thread3);
		 rt_thread_resume (thread6);
		 rt_schedule();
	} 
}   

 static void thread4_entry(void* parameter)  
{  
   while(1){
		 AD();
		 
	 }
} 
 static void thread5_entry(void* parameter)  
{  
   while(1){
		 AD2();
		 
	 }
} 
 static void thread6_entry(void* parameter)  
{  
   while(1)
	{
		 
				u8 y_num[8]={1,1,1,1};
				u8 r_num[8]={0,0,0,0,1,1,1,1};
				display_led(y_num,r_num);
		 		rt_thread_suspend(thread6);
				rt_schedule();
		 
	 }
} 



int rt_application_init1()  
{  

    thread1 = rt_thread_create("thread1",  
        thread1_entry,   
        RT_NULL,  
        512, 10, 10);  
    if (thread1 != RT_NULL)  
        rt_thread_startup(thread1);  
  //进程2初始化
    thread2 = rt_thread_create("thread2",  
        thread2_entry, 
				RT_NULL,  
        512, 10, 10);  
  if (   thread2 != RT_NULL)
        rt_thread_startup(thread2); 
	//进程3初始化
		thread3 = rt_thread_create("thread3",  
        thread3_entry, 
				RT_NULL,  
        1024, 8, 20);  
	  if (   thread3 != RT_NULL) 
        rt_thread_startup(thread3); 
	//进程4初始化
		thread4 = rt_thread_create("thread4",  
        thread4_entry, 
				RT_NULL,  
        1024, 10, 10);  
  if (   thread4 != RT_NULL) 
        rt_thread_startup(thread4); 

	//进程5初始化
		thread5 = rt_thread_create("thread5",  
        thread5_entry, 
				RT_NULL,  
        512, 10, 10);  
  if (   thread5 != RT_NULL) 
        rt_thread_startup(thread5); 

		thread6 = rt_thread_create("thread6",  
        thread6_entry, 
				RT_NULL,  
        512, 7, 10);  
  if (   thread6 != RT_NULL) 
        rt_thread_startup(thread6); 



	
    return 0;  
}  
  
/*******************************************************************************
* 函数名  : main
* 描述    : 主函数,用户程序从main函数开始运行
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
int main(void)
{ 
	
I2C_INIT();		 //IIC初始化
uart_lora_init();
Load_Net_Parameters();		//装载网络参数	
System_Initialization();	//STM32系统初始化函数(初始化STM32时钟及外设)
W5500_Hardware_Reset();		//硬件复位W5500
W5500_Initialization();		//W5500初始货配置	
	InitCD4051(); //4051初始化
	bsp_InitSPIBus();	//SPI初始化	 	
  InitTM7705();		  		//ADC初始化
  TM7705_CalibSelf(1);		 /*自校准,?180ms */	
	TM7705_CalibSelf(2);		 /*自校准,?180ms */	
	//Lora_config();
	ADC1_Init();
  DISPLAY_INIT();
	
rt_application_init1();
	timer_sample();
rt_schedule();
 
//	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	

////	Io_Init();//IO初始化
//	RFS_GPIO_init();//恢复出厂设置按键初始化函数

////	//Modbus_Init();//modbus初始化
////	//RS485_Init();//测试
////	TIM4_Init();

//	Timer5_enable(99);

//while(1)
//{
//		//AD();
//		VibAndTem();
//		//AD2();
//		//DISPLAY(1,2,3,4,5,6,7,8);
//		
//}
//		
		
	
}



void VibAndTem(void)
{
	uint16_t Tem_ADC[6]; 
	float V1,V2,R1,R2;
			//AD();
			Tem_ADC[0]=(analogArry[0]<<8)|analogArry[1];
			Tem_ADC[1]=(analogArry[2]<<8)|analogArry[3];
			Tem_ADC[2]=(analogArry[4]<<8)|analogArry[5];
			Tem_ADC[3]=(analogArry[6]<<8)|analogArry[7];
			Tem_ADC[4]=(analogArry[8]<<8)|analogArry[9];
			Tem_ADC[5]=(analogArry[10]<<8)|analogArry[11];
			

	
	V1 =(float) (Tem_ADC[4])/65535*2.5/51;
	V2 =(float) (Tem_ADC[5])/65535*2.5/51;
	R1=(V1*14000+2000)/(20-V1*7);
	R2=(V2*14000+2000)/(20-V2*7);
	//Tem[4]=CalculateTemperature(R1);
//	Tem[5]=CalculateTemperature(R2);
	Tem[0]=(float) (Tem_ADC[0])/65535*1000/50;
	Tem[1]=(float) (Tem_ADC[1])/65535*1000/50;
	Tem[2]=(float) (Tem_ADC[2])/65535*1000/50;
	Tem[3]=(float) (Tem_ADC[3])/65535*1000/50;
}

void AD2(void)
{ u8 i;
	uint16_t My_ADC[4][30]; 
	for(i=0;i<30;i++)  
	{
      My_ADC[0][i]=ADC_ConvertedValue[0];
			My_ADC[1][i]=ADC_ConvertedValue[1];
			My_ADC[2][i]=ADC_ConvertedValue[2];
			My_ADC[3][i]=ADC_ConvertedValue[3];
   }
	
	ADC_ConvertedValueLocal[0] =(float) GetDelExtremeAndAverage(My_ADC[0],30,5,5)/4096*3;
	ADC_ConvertedValueLocal[1] =(float) GetDelExtremeAndAverage(My_ADC[1],30,5,5)/4096*3;
	ADC_ConvertedValueLocal[2] =(float) GetDelExtremeAndAverage(My_ADC[2],30,5,5)/4096*3;
	ADC_ConvertedValueLocal[3] =(float) GetDelExtremeAndAverage(My_ADC[3],30,5,5)/4096*3;

}




在这个程序中创建了两个定时器,6个线程。定时器2暂时没用,定时器1用于启动线程3进行数码管扫描;进程1进行网络通讯;进程2控制继电器;进程3进行计算和显示;进程4进行AD7705读取;进程5进行STM32自带AD读取;进程6进行LED灯显示。其中,LED灯显示与数码管显示冲突,两个进程不可以同时运行,因此让进程3调度进程6。

你可能感兴趣的:(STM32)