当前位置: 首页 > news >正文

自动优化网站建设电话wordpress 加文章列表

自动优化网站建设电话,wordpress 加文章列表,网站建设费一般多少,搜索引擎营销的主要模式在之前写的另外一篇文章——从0到1写RT-Thread内核——线程定义及切换的实现中线程体内的延时使用的是软件延时#xff0c;即还是让CPU空等来达到延时的效果。RTOS中的延时叫阻塞延时#xff0c;即线程需要延时的时候#xff0c;线程会放弃CPU的使用权#xff0c;C…       在之前写的另外一篇文章——从0到1写RT-Thread内核——线程定义及切换的实现中线程体内的延时使用的是软件延时即还是让CPU空等来达到延时的效果。RTOS中的延时叫阻塞延时即线程需要延时的时候线程会放弃CPU的使用权CPU可以去干其他的事情当线程延时时间到重新获取CPU使用权线程继续运行这样就充分利用了CPU的资源而不是干等着。 当某个线程需要延时进入阻塞状态如果没有其他线程可以运行RTOS都会为CPU创建一个空闲线程这个时候CPU就运行空闲线程。在RT-Thread中空闲线程是系统在初始化的时候创建的优先级最低的线程空闲线程主要是做一些系统内存的清理工作。但为了简单起见这里我们的空闲线程只对一个全局变量进行计数。在实际应用中当系统进入空闲线程的时候可在空闲线程中让单片机进入休眠或者低功耗等操作。 我们把空闲线程与阻塞延时的实现分为以下两大步 一.实现空闲线程 1.定义空闲线程的栈 #include rtthread.h #include rthw.h #define IDLE_THREAD_STACK_SIZE 512 ALIGN(RT_ALIGN_SIZE) static rt_uint8_t rt_thread_stack[IDLE_THREAD_STACK_SIZE]; 2.定义空闲线程控制块 struct rt_thread idle; 3.定义空闲线程函数 rt_ubase_t rt_idletask_ctr 0;void rt_thread_idle_entry(void *parameter) {parameter parameter;while (1){rt_idletask_ctr ;/* 进行系统调度这个是我自己后来加的野火官方的例程是没有调用rt_schedule *我觉得那样是错误的因为这里不加rt_schedule的话程序执行到空闲线程就回不去了*///rt_schedule();//这里补充一下野火的例程并没有错每次产生滴答定时器中断都会调用调度器所以这里不需要调用调度器的} } 4.空闲线程初始化 /*** ingroup SystemInit** 初始化空闲线程启动空闲线程** note 当系统初始化的时候该函数必须被调用*/ void rt_thread_idle_init(void) {/* 初始化线程 */rt_thread_init(idle,idle,rt_thread_idle_entry,RT_NULL,rt_thread_stack[0],sizeof(rt_thread_stack));/* 将空闲线程插入到就绪列表中优先级最低的链表中 */rt_list_insert_before( (rt_thread_priority_table[RT_THREAD_PRIORITY_MAX-1]),(idle.tlist) ); } 以上4步在之前的文章——从0到1写RT-Thread内核——线程定义及切换的实现有详细介绍过了这里就不再过多解释。 二.实现阻塞延时 阻塞延时的阻塞是指线程调用该延时函数后线程会被剥离CPU使用权然后进入阻塞状态直到延时结束线程会重新获取CPU使用权才可继续运行在线程阻塞的这段时间CPU可以去执行其他的线程如果其他的线程也在延时状态那么CPU就将运行空闲线程。我们定义一个延时函数rt_thread_delay函数其代码清单如下图 上面的代码中我们通过thread-remaining_tick来判断某个线程的延时是否结束thread-remaining_tick是在SysTick_Handler中递减的其代码如下 void SysTick_Handler(void) {/* 进入中断 */rt_interrupt_enter();rt_tick_increase();/* 离开中断 */rt_interrupt_leave(); } /* * rt_interrupt_nest为中断计数器是一个全局变量用来记录中断嵌套次数。* 每进入一个中断函数就会加一* 每离开一个中断函数就会减一*/ volatile rt_uint8_t rt_interrupt_nest;/*** 当BSP文件的中断服务函数进入时会调用该函数* * note 请不要在应用程序中调用该函数** see rt_interrupt_leave*/ void rt_interrupt_enter(void) {rt_base_t level;/* 关中断 */level rt_hw_interrupt_disable();/* 中断计数器 */rt_interrupt_nest ;/* 开中断 */rt_hw_interrupt_enable(level); }/*** 当BSP文件的中断服务函数离开时会调用该函数** note 请不要在应用程序中调用该函数** see rt_interrupt_enter*/ void rt_interrupt_leave(void) {rt_base_t level;/* 关中断 */level rt_hw_interrupt_disable();/* 中断计数器-- */rt_interrupt_nest --;/* 开中断 */rt_hw_interrupt_enable(level); } //rt_tick 为系统时基计数器是一个全局变量用来记录产生了多少次SysTick中断 static rt_tick_t rt_tick 0; extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];void rt_tick_increase(void) {rt_ubase_t i;struct rt_thread *thread;rt_tick ;/* 扫描就绪列表中所有线程的remaining_tick如果不为0则减1 */for(i0; iRT_THREAD_PRIORITY_MAX; i){thread rt_list_entry( rt_thread_priority_table[i].next,struct rt_thread,tlist);if(thread-remaining_tick 0){thread-remaining_tick --;}}/* 系统调度 */rt_schedule(); } 下面我们来看一下main函数和线程1和线程2的函数体在main函数中我们分别初始化了空闲线程、线程1和线程2并将它们插入到对应就绪列表的链表中去然后就开始了系统调度rt_system_scheduler_start先从线程1开始执行这里不理解的话可以看另外一篇博客从0到1写RT-Thread内核——线程定义及切换的实现如果某个因为线程调用了rt_thread_delay函数而被阻塞了的话就运行另外的线程此时线程阻塞剩余时长remaining_tick在SysTick_Handler中不断递减如果非空闲线程都被阻塞了才运行空闲线程如果某个线程的remaining_tick递减到为0了则又继续运行该线程。 /************************************************************************* brief main函数* param 无* retval 无** attention*********************************************************************** */ int main(void) { /* 硬件初始化 *//* 将硬件相关的初始化放在这里如果是软件仿真则没有相关初始化代码 *//* 关中断在程序开始的时候把中断关闭是一个好习惯等系统初始化完毕线程创建完毕启动系统 * 调度的时候会重新打开中断在rt_hw_context_switch_to函数中会再开启中断并设置中断标位。* 如果一开始不关闭中断接下来SysTick初始化完成然后再初始化系统和创建线程如果系统初始化* 和线程创建的时间大于SysTick中断周期的话那么就会出现系统或者线程还没准备好的情况下就先执* 行了SysTick中断服务函数在该函数中进行了系统调度显示这是不合理的。*/rt_hw_interrupt_disable();/* 初始化SysTick调用固件库函数SysTick_Config来实现* 配置中断周期为10ms为100中断优先级为最低*/SysTick_Config( SystemCoreClock / RT_TICK_PER_SECOND );/* 调度器初始化 */rt_system_scheduler_init();/* 初始化空闲线程 */ rt_thread_idle_init(); /* 初始化线程1 */rt_thread_init( rt_flag1_thread, /* 线程控制块 */rt_flag1_thread, /* 线程名字字符串形式 */flag1_thread_entry, /* 线程入口地址 */RT_NULL, /* 线程形参 */rt_flag1_thread_stack[0], /* 线程栈起始地址 */sizeof(rt_flag1_thread_stack) ); /* 线程栈大小单位为字节 *//* 将线程插入到就绪列表 */rt_list_insert_before( (rt_thread_priority_table[0]),(rt_flag1_thread.tlist) );/* 初始化线程2 */rt_thread_init( rt_flag2_thread, /* 线程控制块 */rt_flag2_thread, /* 线程名字字符串形式 */flag2_thread_entry, /* 线程入口地址 */RT_NULL, /* 线程形参 */rt_flag2_thread_stack[0], /* 线程栈起始地址 */sizeof(rt_flag2_thread_stack) ); /* 线程栈大小单位为字节 *//* 将线程插入到就绪列表 */rt_list_insert_before( (rt_thread_priority_table[1]),(rt_flag2_thread.tlist) );/* 启动系统调度器 */rt_system_scheduler_start(); } /* 线程1 */ void flag1_thread_entry( void *p_arg ) {for( ;; ){ #if 0flag1 1;delay( 100 ); flag1 0;delay( 100 );/* 线程切换这里是手动切换 */ rt_schedule(); #elseflag1 1;rt_thread_delay(2); flag1 0;rt_thread_delay(2); #endif } }/* 线程2 */ void flag2_thread_entry( void *p_arg ) {for( ;; ){ #if 0flag2 1;delay( 100 ); flag2 0;delay( 100 );/* 线程切换这里是手动切换 */rt_schedule(); #elseflag2 1;rt_thread_delay(2); flag2 0;rt_thread_delay(2); #endif } } 程序运行结果如下其实这种阻塞延时的原理和我们在单片机裸机中采用的前后台轮询是非常相似的。 最后声明一下我这里只是对学习的知识点进行总结本文章的大多数知识来自于野火公司出版的《RT-Thread 内核实现与应用开发实战—基于STM32》这本书非常不错有志学习RT-Thread物联网操作系统的人可以考虑一下。
http://wiki.neutronadmin.com/news/305043/

相关文章:

  • 宁波网站建设首选品牌艺点意创官网
  • 有链接的网站怎么做定制微信小程序多少钱
  • 国外做兼职网站有哪些深圳做网站的网
  • 网站主办单位负责人2019做网站需要营业执照吗
  • 网站建设的栏目策划石家庄招聘求职信息网
  • 淘宝购物网站的建设现在外贸推广做哪个平台
  • 旅游网站源码 wordpress模板 v1.0html语言做的网站和asp的区别
  • 北京网站建设最便宜的公司哪家好兰州建设网站的网站
  • 网站项目根据什么开发百度信息流优化
  • 西安建网站的公司广告设计制作服务方案
  • 有做企业网站的吗运营推广seo招聘
  • 开源 企业网站一元域名注册永久
  • 吴江区建设局网站网站如何做中英文效果
  • 外贸婚纱网站 侵权郑州市建设厅网站
  • 网站设计的书网站建设公司源码
  • 北京大兴网站建设公司咨询php怎样做网站管理后台
  • 制作网站的图片素材做防腐木网站
  • 网站关键词代码怎么做wordpress 代码位置
  • 网站建设需要用软件asp程序设计做网站
  • 域名备案和网站备案西乡做网站的公司
  • 常州建设银行网站首页大型购物网站建站
  • 邢台微信网站网站设计一般什么字体
  • 湖南官网网站推广软件智慧门店管理服务平台
  • 做设计排版除了昵图网还有什么网站怎么做一个网站出来
  • 网站建设工作进度wordpress 浮动留言框
  • 网站由哪几个部分组成信阳专业做网站公司
  • 郑州微科网站建设微山网站建设多少钱
  • 深圳建立网站的公司做网站比较专业的公司
  • 网站建设与设计开题报告抖音小程序在哪里
  • 常州网站建设运营网页设计与制作教程书电子版