目录

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 <string.h>
#include "led.h"
#include "oled.h"
#include "HT16K33.h"
#include "display.h"
#include "bsp_adc.h"
#include "pt100.h"
#include <stdbool.h>
#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。
————————————————

RTT移植STM32之创建进程相关推荐

  1. Linux下创建进程简介

    在博文https://blog.csdn.net/fengbingchun/article/details/108940548中简单介绍了Windows下通过函数CreateProcess创建进程的过 ...

  2. Windows下创建进程简介

    正在执行的应用程序称为进程,进程不仅仅是指令和数据,它还有状态.状态是保存在处理器寄存器中的一组值,如当前执行指令的地址.保存在内存中的值,以及唯一定义进程在任一时刻任务的所有其他值.进程与应用程序的 ...

  3. 从创建进程到进入 main 函数,发生了什么?

    作者 | 轩辕之风O 来源 | 编程技术宇宙(ID:xuanyuancoding) 头图 |  CSDN 下载自东方IC 前几天,读者群里有小伙伴提问:从进程创建后,到底是怎么进入我写的 main 函 ...

  4. 小实验:用创建进程()打开计算器,然后关闭进程句柄。再用打开进程(进程ID),使用两次,得到两个进程句柄。实验目的:这两个进程句柄都能控制这个进程吗?通过该试验加深对句柄的理解!!...

    小实验:用创建进程()打开计算器,然后关闭进程句柄.再用打开进程(进程ID),使用两次,得到两个进程句柄.实验目的:这两个进程句柄都能控制这个进程吗? .版本 2 .程序集 窗口程序集1 .子程序 _ ...

  5. 使用Native API 创建进程

    使用 Native API 创建进程 最近几个星期一直在研究这个题目.因为关于方面的资料比较多(可以看下面的参考文章),所以开始时以为很快就结束了.谁知道真正动起手来才发现有很多要考虑的地方,不过还好 ...

  6. python之multiprocessing创建进程

    python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录. multiprocessing创建多进程在windows和linux系统下的 ...

  7. 遍历创建进程、创建线程、加载模块的回调函数

    今天我们首先来看一下最简单的,关于遍历PspCreateProcessNotifyRoutine数组,PspLoadImageNotifyRoutine也同理 这两个数组保存了两组函数地址,它们将在有 ...

  8. linux创建进程读共享写复制,Linux下进程的创建、执行和终止

    1)进程的创建和执行 许多操作系统提供的都是产生进程的机制,也就是说,首先在新的地址空间里创建进程.读入可执行文件,后再开始执行.Linux中进程的创建很特别,它把上述步骤分解到两个单独的函数中去执行 ...

  9. 循环中fork创建进程的个数

    linux下创建进程的系统调用是fork.其定义如下 #include <sys/types.h> #include <unistd.h> pid_t fork(); 在循环中 ...

  10. 【Linux 内核】进程管理 ( 进程状态 | 进程创建 | 进程终止 | 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 )

    文章目录 一.进程状态 二.进程创建 三.进程终止 ( 调用 exit 系统调用函数主动退出 | main 函数返回自动退出 | kill 杀死进程 | 执行异常退出 ) 一.进程状态 Linux 进 ...

最新文章

  1. UVa 11000 - Bee
  2. Codeforces Global Round 4 题解
  3. 来吧!我教你画真正的流程图
  4. Java黑皮书课后题第10章:*10.19(Mersenne素数)
  5. 简化路径Python解法
  6. Docker 第四章 访问容器
  7. 初阶和高阶产品之间的核心差距
  8. DCL 管理用户 mysql
  9. 05 ansible剧本编写
  10. 第二章--电商设计表-商品模块--mysql电商项目设计
  11. Coding the Matrix Week 1 The vector 作业
  12. android联系人源码分析,android 联系人源码分析 新字段的添加流程
  13. 以教务管理的成绩单查询为例,SSM整合开发过程详解(spring、springmvc、mybatis)
  14. mysql flush tables_MySQL 清理缓存—flush tablesFlush tables的影响
  15. 攻防世界Web新手区题解
  16. VTK读取序列DCM格式医学图像
  17. echarts自定义主题构建
  18. 贪心算法——区间选点问题
  19. 搜一下导航完整程序源码+亲测可用
  20. IDEA登录账户报错:Certificate used to sign the license is not signed by JetBrains root certificate

热门文章

  1. Micropython——基于PYB的霍尔编码器电机的PID控制
  2. arduino霍尔编码器蓝牙小车代码
  3. 远程控制工具ToDesk测评
  4. 2020年高压电工模拟考试题库及高压电工作业模拟考试
  5. java 类的对象是什么意思_java中类和对象的概念
  6. Django 点击刷新验证码
  7. fcitx-configtool
  8. 控制寄存器(CR0,CR1,CR2,CR3)和CR4
  9. 安装Oracle中文乱码
  10. STM32驱动SG90舵机与HC_SR04超声波模块