摘要 :对于单片机程序来说,大家都不陌生,但是真正使用架构,考虑架构的恐怕并不多,随着程序开发的不断增多,架构是非常必要的。
应用程序的架构大致有三种:
1、 简单的前后台顺序执行程序 ,这类写法是大多数人使用的方法,不需用思考程序的具体架构,直接通过执行顺序编写应用程序即可。
2、 时间片轮询法 ,此方法是介于顺序执行与 *** 作系统之间的一种方法。
3、 *** 作系统 ,此法应该是应用程序编写的最高境界。
1、前后台顺序执行法
这是初学者们常用的程序框架设计方案,不用考虑太多东西,代码简单,或者对系统的整体实时性和并发性要求不高;初始化后通过 while(1){} 或 for(;;) {}`循环不断调用自己编写完成的函数,也基本不考虑每个函数执行所需要的时间,大部分情况下函数中或多或少都存在毫秒级别的延时等待。
以下是在校期间做的寝室防盗系统的部分代码(当时也存在部分BUG,没有解决。现在再看,其实很多问题,而且比较严重,比如中断服务函数内竟然有3000ms延时,这太可怕了,还有串口发送等等;由于实时性要求不算太高,因此主函数中的毫秒级别延时对系统运行没有多大影响,当然除BUG外;若是后期需要维护,那就是一个大工程,还不如推翻重写 ):
介于 前后台顺序执行法 和 *** 作系统 之间的一种程序架构设计方案。该设计方案需能帮助嵌入式软件开发者更上一层楼,在嵌入式软件开发过程中,若遇到以下几点,那么该设计方案可以说是最优选择,适用于程序较复杂的嵌入式系统;
该设计方案需要使用一个定时器,一般情况下定时1ms即可(定时时间可随意定,但中断过于频繁效率就低,中断太长,实时性差),因此需要考虑到每个任务函数的执行时间,建议不能超过1ms(能通过程序优化缩短执行时间则最好优化,如果不能优化的,则必须保证该任务的执行周期必须远大于任务所执行的耗时时间),同时要求主循环或任务函数中不能存在毫秒级别的延时。
以下介绍两种不同的实现方案,分别针对无函数指针概念的朋友和想进一步学习的朋友。
1、无函数指针的设计方式
2、含函数指针的设计方式
嵌入式 *** 作系统EOS( Embedded OperatingSystem )是一种用途广泛的系统软件,过去它主要应用于工业控制和国防系统领域,而对于单片机来说,比较常用的有UCOS、FreeRTOS、 RT-Thread Nano和RTX 等多种抢占式 *** 作系统(其他如Linux等 *** 作系统不适用于单片机)
*** 作系统和“ 时间片论法 ”,在任务执行方面来说, *** 作系统对每个任务的耗时没有过多的要求,需要通过设置每个任务的优先级,在高优先级的任务就绪时,会抢占低优先级的任务; *** 作系统相对复杂,因此这里没有详细介绍了。
关于如何选择合适的 *** 作系统( uCOS 、 FreeRTOS 、 RTThread 、 RTX 等RTOS的对比之特点:
借网上一张对比图:
从上述的对比中可以看出,时间片轮询法的优势还是比较大的,它既有前后台顺序执行法的优点,也有 *** 作系统的优点。结构清晰,简单,非常容易理解,所以这种是比较常用的单片机设计框架。
C语言中没有什么框架的概念,几乎只有Windows的某些工作,例如窗口要用到比较规范的框架,其他的几乎一个程序一个样,完全属于原创概念。C语言本身就可以用来作为一款程序的框架,用来承载诸多API来实现外设控制,多媒体编程等目的,所以C语言不只可以用来编写底层,他的强大就在于强大的数据处理能力上,它比较靠近汇编,又比汇编高级,C写出来的软件,几乎不会收到语言的能力的限制而失去某些功能,但是C的移植性是代码完全可移植,就是说同样的代码,在不同的机器上都正常,但是成品不一定,这一点和java有点不同,再有就是C是面向过程的,它对语言的封装相对比较少,大部分的事情有程序员自己控制,这样的设计有好有坏,总之,任何一种语言,用的顺手了,那就是神器!!
RT-Thread4G断网频繁可能由以下几个原因导致:
1、SIM卡信号不稳定或者信号弱。建议更换位置或者更换其他运营商的SIM卡来尝试。
2、模块或者线路老化或损坏。可以考虑更换模块或线路进行尝试。
3、硬件电路噪声干扰。可以考虑在硬件电路上加入滤波器。
4、软件程序问题。可以根据程序日志来查找出错原因,并进行修复。
1 在stm32f4xx_itc文件里面删除如下程序 / @brief This function handles Hard fault interrupt / void HardFault_Handler(void)
2 加入下面两句 / USER CODE BEGIN PTD / extern void rt_exit_critical(void); extern void rt_enter_critical(void); /
3 加入串口打印函数 / USER CODE BEGIN 4 / //
如何编写Linux设备驱动程序 回想学习Linux *** 作系统已经有近一年的时间了,前前后后,零零碎碎的一路学习过来,也该试着写的东西了。也算是给自己能留下一点记忆和回忆吧!由于完全是自学的,以下内容若有不当之处,还请大家多指教。
RTT在空闲的时候可以使用钩子函数执行些简单的任务,例如LED闪烁之类的程序,利用这个功能我们可以做个工作状态指示灯
要使用钩子必须在配置里打开钩子的配置,在rt-configh里添加HOOK宏定义(如果没有的话)
#define
RT_USING_HOOK
然后在应用程序里设置钩子函数
#ifdef
RT_USING_HOOK
rt_thread_idle_sethook(rt_hw_led_flash);
#endif
下面就是该怎样实现这个函数了
void
rt_hw_led_flash(void)
{
rt_uint32_t
i;
rt_hw_led_init();
while
(1)
{
for(i
=
0;
i
<
2700000;
i++);
//500ms
GPIO_WriteBit(state_led_gpio,
state_led_pin,
(BitAction)(1-GPIO_ReadOutputDataBit(state_led_gpio,
state_led_pin)));
}
}
这样写过之后,在系统空闲的时候就会执行这个函数,当然,如果系统繁忙的时候是不会进入这个idel任务的,不过如果系统一直处于繁忙的状态就是有问题了
另外一点记住,在这个函数里不能调用系统提供的使线程挂起的函数
例如:
rt
thread
delay,
rt
sem
take
等
while
(1)
{
for(i
=
0;
i
<
2700000;
i++);
//500ms
GPIO_WriteBit(state_led_gpio,
state_led_pin,
(BitAction)(1-GPIO_ReadOutputDataBit(state_led_gpio,
state_led_pin)));
}
关键是这个while(1)没跳出的,所以全部在这里执行了。
好像还有同学对其中一些并不是完全清楚,所以继续解析下,当做结贴:
1
idle线程是系统中最后一道防线,它将是系统中,如果无其他事可干时的最后能够运行的线程。
--
所以idle线程不应该被阻塞。如果你有自己的线程能够成为这最后一道防线,那么这个限制将不存在。而对于一些原来系统中放在idle线程中做的工作(例如原来的最终的线程删除动作),在04x中,可以手工调用rt_thread_idle_excute函数来执行。
2
当系统空闲的时候,idle线程将执行这个钩子函数。
假设钩子函数一次运行会执行1ms,如果idle线程有机会运行200ms,那么钩子函数将被调用200次。
3
钩子函数运行时,不应该把idle线程总是纠结在这个函数中运行,必须要让idle线程有机会去运行rt_thread_idle_excute函数(因为还有一些事情等待idle线程去处理)。
--
所以在钩子函数中,不应该使用while(1);的方式。
while(1)
{
if
(
indicator
==
RT_TRUE)
{
do
something
}
else
delay(20ms)
}
这样那20ms会执行idle线程吧,问题是idle
20ms够吗,如果我改20ms为5ms呢
如果没有其他线程处理事务,将转换到idle线程去,通常idle线程中的系统任务会在0xx
ms以内执行完毕
以上就是关于嵌入式软件开发常用的三种架构你知道吗全部的内容,包括:嵌入式软件开发常用的三种架构你知道吗、C语言会像Java一样有很多私人开发的框架么、rtthread4g断网频繁等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)