搜索
bottom↓
回复: 163

[LIB][ICC][IAR][GCC] 8K ~ 4K 小flash芯片专用架构

  [复制链接]

出0入296汤圆

发表于 2010-3-10 17:39:55 | 显示全部楼层 |阅读模式
本帖最后由 Gorgon_Meducer 于 2013-1-29 14:02 编辑


[ 使用说明 ]


    这是一个专门针对 8~4K flash 小存储器单片机准备的工程模板,内嵌了
一个迷你的状态机调度器,以及一些基本的垮平台宏(ICC,IAR,GCC)。我
就不做太多说明了,有兴趣的人可以直接看代码哈。毕竟,不看代码你也肯定
用不好……呵呵,特别是针对小flash的情况。

    另外,这个工程模板里面使用了修正后的编码规范。这里简单说一下,
最早的,也就是在论坛上存在很久的那个编码规范(及相关模板)主要基于ICC
我把它视作 傻孩子编码规范1.0;前一段时间发布的,基于三平台(ICC,IAR
GCC)的版本,我视作 傻孩子编码规范2.0;而今天所公布的这个代码,完整
的展示了2.0规范的一个修正,不妨命名为2.1。呵呵。

    欢迎讨论哈。基于2.x版本的编码规范,我计划推出一个辅助性的集成开发
环境。当然,现在还停留在大脑里面……什么时候能拿出来,我也不敢说。


<font color=red> [ 追加新特性 ]

    和2.0版本不同,现在所有模块可以随意移动位置,只要保证顶层的app_cfg.h
中包含了正确引用utilities目录下所有头文件即可。也就是说假设顶层app_cfg.h
和utilities目录在同一个文件夹下,则顶层app_cfg.h中应该包含以下内容:

#include ".\utilities\compiler.h"
#include ".\utilities\signal.h"
#include ".\utilities\error.h"
#include ".\utilities\usebits.h"

    这样,所有模块都可以随意移动位置,而不用担心对以上4个头文件的引用
出现错误。所有的新建立的.c文件只要包含本模块的app_cfg.h就可以完成对以
上4个头文件的正确引用。


[ 编码规范核心原则 ]

    1、一个模块的所有文件必须包含在一个同名的文件夹里面
   
    2、一个模块总是包含至少三个文件:
       app_cfg.h
       xxxxx.h
       xxxxx.c
       这里 "xxxxx"是模块的名称,同时也是文件夹的名称

    3、xxxxx.c 里面 强烈建议不要包含 xxxxx.h 当我们具体要使用某个头文件的
       时候,应该通过 “相对路径来添加”
   
    4、xxxxx.h里面只放置外界调用该模块所需的最小信息,必要的时候甚至要“欺骗”
       (比如使用掩码结构体,或者指针类型欺骗,等等)

    5、app_cfg.h 通常采用以下的模板
      
       #include "..\app_cfg.h"      //!< 引用上一级的app_cfg.h

       #ifndef _USE_XXXXXXXX_CFG_H_
       #define _USE_XXXXXXXX_CFG_H_
      
       这里放置一些本地化的配置信息,不要放任何实体代码

       #endif


    6、使用 stdint.h 里面定义的数据类型(参考compiler.h);在牵涉到与外界进行通讯的
       模块里面,避免使用 位段,同时要注意数据的大小端以及对齐方式(byte / half-word
       / word / dword)。

       C-99 标准推荐的类型
       uint8_t int8_t
       uint16_t int16_t
       uint32_t int32_t
       bool

    7、坚决不使用绝对路径; 避免使用编译器工程选项中的路径搜索设置。


本贴工程模板中提到的调度器推荐用http://www.amobbs.com/thread-5509424-1-1.html 来替代



[ 相关下载 ]


点击此处下载工程模板 ourdev_553981.rar(文件大小:23K) <font color=green>(原文件名:Template.rar)


点击此处下载培训PPT ourdev_626094JKZJQ9.rar(文件大小:410K) (原文件名:Trainning.rar)

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入296汤圆

 楼主| 发表于 2010-3-10 17:40:06 | 显示全部楼层

出0入296汤圆

 楼主| 发表于 2010-3-10 17:40:22 | 显示全部楼层

出0入0汤圆

发表于 2010-3-10 18:10:06 | 显示全部楼层
这个模板还真不错!

出10入210汤圆

发表于 2010-3-10 18:38:53 | 显示全部楼层
强!
好好学习一下.

出0入296汤圆

 楼主| 发表于 2010-3-10 18:40:35 | 显示全部楼层
再次更新,增加模块可以随意移动的特性……嘿嘿^_^
关键就在 每个目录里面 app_cfg.h

出0入0汤圆

发表于 2010-3-10 18:49:43 | 显示全部楼层
niu

出0入0汤圆

发表于 2010-3-10 20:15:52 | 显示全部楼层
niu

出0入0汤圆

发表于 2010-3-10 20:37:11 | 显示全部楼层
强烈关注

出0入0汤圆

发表于 2010-3-10 20:44:39 | 显示全部楼层
傻孩子对这种OS,底层框架性软件非常非常感兴趣。。

出0入0汤圆

发表于 2010-3-10 20:49:08 | 显示全部楼层
有空得好好学习下

出0入0汤圆

发表于 2010-3-10 21:25:26 | 显示全部楼层
虽然不懂,但还是要支持。

出0入0汤圆

发表于 2010-3-10 21:46:23 | 显示全部楼层
顶傻孩子,

出0入0汤圆

发表于 2010-3-10 22:00:43 | 显示全部楼层
傻孩子 能不能讲讲你这个调度器的一个大概的工作过程啊。。

最近正好有个项目的空间只有6k,而且状态切换比较多,想借用下你的模板看下,,用keil 软件来编译的

出0入0汤圆

发表于 2010-3-10 22:04:48 | 显示全部楼层
好帖,好好学习,天天向上

出0入0汤圆

发表于 2010-3-10 22:16:22 | 显示全部楼层
值得我们这些个编程不规范的学习

出0入0汤圆

发表于 2010-3-10 22:43:19 | 显示全部楼层
高手

mark

出0入0汤圆

发表于 2010-3-10 22:49:54 | 显示全部楼层
typedef bool MINI_FSM_TASK_HANDLER(void);

//! \name mini FSM task structure
//! @{
typedef struct
{
#if MCU_MEM_LITTLE_ENDIAN
    unsigned Available      : 1;            //!< avaliable flag
    unsigned IsAlive        : 1;            //!< alive flag
   
    unsigned Period         : 7;            //!< task working period
    unsigned TimeTicker     : 7;            //!< task time ticker
#else
    unsigned TimeTicker     : 7;            //!< task time ticker
    unsigned Period         : 7;            //!< task working period
   
    unsigned IsAlive        : 1;            //!< alive flag
    unsigned Available      : 1;            //!< avaliable flag
#endif
    MINI_FSM_TASK_HANDLER *fnTaskRoutine;   //!< task routine
}MINI_FSM_TASK;


能否解释下这部分定义的意思是什么啊?

谢谢!

出0入0汤圆

发表于 2010-3-10 23:01:08 | 显示全部楼层
oid mini_FSM_task_schedule(void)
{
    #ifdef MINI_FSM_IDLE_TASK
    bool bIfIdle = true;
    #endif
   
    uint8_t n = 0;
   
    for (n = 0; n < UBOUND(s_fsmTasks); n++)
    {
        if (
                (0x03 == (((volatile uint8_t *)&s_fsmTasks[n])[0] & 0x03))
            &&  (NULL != s_fsmTasks[n].fnTaskRoutine)   //还有这部分的代码,既然s_fsmTasks 已经是一个结构体数组了,
                                                       //取出第n个元素后在强制转化成char 型的指针后怎么还要在取第0 个元
                                                   //素呢?不是很明白,还有好像这个project 里面没有加入其它的task 吧?

           )
        {
            bool result = s_fsmTasks[n].fnTaskRoutine();
            
            ATOM_CODE
            (
                s_fsmTasks[n].IsAlive = result;
            )
            
            bIfIdle = false;
        }
    }
   
    #ifdef MINI_FSM_IDLE_TASK
    if (bIfIdle)
    {
        MINI_FSM_IDLE_TASK;
    }
    #endif
}


谢谢!

出0入296汤圆

 楼主| 发表于 2010-3-10 23:17:59 | 显示全部楼层
(0x03 == (((volatile uint8_t *)&s_fsmTasks[n])[0] & 0x03))
等效于:
  ((s_fsmTasks[n].Available) && (s_fsmTasks[n].IsAlive))

出0入0汤圆

发表于 2010-3-11 02:00:37 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-3-11 03:38:06 | 显示全部楼层
学习!

出0入4汤圆

发表于 2010-3-11 08:22:35 | 显示全部楼层
不错

出0入296汤圆

 楼主| 发表于 2010-3-11 09:36:52 | 显示全部楼层
to 【13楼】 reynold520
    这个调度器是一个合作式调度器。
    每一个顶层的task都要满足
    bool XXXXXXXXXXXXXXXXX(void) 这样的函数形式

    其中,如果函数返回false,那么这个task下次就不会被执行了,
如果返回true,则该函数还会保持运行。

    ……

    由此我们发现……还缺少一个激活某个task的库函数……晕……漏掉了……
特此补上……

bool mini_FSM_set_task_ready(uint8_t chTaskID)
{
    if (chTaskID < UBOUND(s_fsmTasks))
    {
        SAFE_ATOM_CODE
        {
            s_fsmTasks[chTaskID].IsAlive = true;
        }
        return true;
    }

    return false;
}

一般情况下,应该设计task自己关闭自己,而不应该用强制设定IsAlive = false
的方式来关闭他,就好比 PC 多线程系统中不提倡用 suspend方法来暂停一个线
程一样。当然,你可以使用 mini_FSM_Release_Task 方法将一个任务强制杀死。
基于以上考虑,不提供函数
void mini_FSM_suspend_task(uint8_t chTaskID)

出0入0汤圆

发表于 2010-3-11 12:47:25 | 显示全部楼层
下来在好好研究下,感谢傻孩子 的回复。。。

有问题我在跟贴请教哈!

出0入0汤圆

发表于 2010-3-11 14:12:21 | 显示全部楼层
做个记号,谢谢

出0入0汤圆

发表于 2010-3-11 14:24:06 | 显示全部楼层
学习了

出0入0汤圆

发表于 2010-3-11 14:27:52 | 显示全部楼层
mark,谢谢

出0入296汤圆

 楼主| 发表于 2010-3-11 15:29:44 | 显示全部楼层
再次更新,增加基于 时间片调度 的算法。


<font color=brown>

//! \name mini FSM task structure
//! @{
typedef struct
{
#if MCU_MEM_LITTLE_ENDIAN
    //! little-endian
    unsigned Available      : 1;            //!< avaliable flag
    unsigned IsAlive        : 1;            //!< alive flag
    #if MINI_FSM_TIMER_BASED == ES_ENABLED
    unsigned Period         : 14;           //!< task working period
    uint16_t TimeTicker;                    //!< task time ticker
    #else
    unsigned Reserved       : 14;     
    #endif
    MINI_FSM_TASK_HANDLER *fnTaskRoutine;   //!< task routine  
#else
    //! big-endian
    MINI_FSM_TASK_HANDLER *fnTaskRoutine;   //!< task routine  
    #if MINI_FSM_TIMER_BASED == ES_ENABLED
    uint16_t TimeTicker;                    //!< task time ticker
    unsigned Period         : 14;           //!< task working period
    #else
    unsigned Reserved       : 14;  
    #endif
    unsigned IsAlive        : 1;            //!< alive flag
    unsigned Available      : 1;            //!< avaliable flag
#endif
}MINI_FSM_TASK;
//! @}








#if MINI_FSM_TIMER_BASED == ES_ENABLED

volatile uint16_t s_hwFSMTimerCounter = 0;

/*! \note mini FSM time based task manager, this function should  
*!       be put into any timer service routine or just the  
*!       superloop of the main()
*!
*! \param none
*!
*! \return none
*/
void mini_FSM_time_based_task_manager(void)
{
    uint8_t n = 0;
     
    s_hwFSMTimerCounter++;
     
    //! scan each task control block
    for (n = 0; n < UBOUND(s_fsmTasks); n++)
    {
        if (
                (!s_fsmTasks[n].Available)  
            ||  (0 == s_fsmTasks[n].Period)
           )
        {
            continue;
        }
        else if (s_fsmTasks[n].TimeTicker == s_hwFSMTimerCounter)
        {
            //! it's the time  
            s_fsmTasks[n].TimeTicker += s_fsmTasks[n].Period;       //!< set next timestamp            
            s_fsmTasks[n].IsAlive = true;                           //!< mark task alive
        }
    }
}

#endif

出0入36汤圆

发表于 2010-3-11 17:57:29 | 显示全部楼层
"也就是在论坛上存在很久的那个编码规范(及相关模板)主要基于ICC
  我把它视作 傻孩子编码规范1.0;前一段时间发布的"???????????????????????

    版主这个"傻孩子编码规范1.0"哪里有下啊????????????是否比<<深入浅出>>书中的详细些.
  十分想下来学习下,搞定1.0再来研究2.1  或者发一份给我啊 P15980288598@126.COM

出0入296汤圆

 楼主| 发表于 2010-3-11 18:15:47 | 显示全部楼层
代码就是文档……

1.0看 傻孩子常用基础头文件
2.0看置顶的其他库
2.1看这个帖子

出0入36汤圆

发表于 2010-3-12 08:03:04 | 显示全部楼层
回复【30楼】Gorgon Meducer 傻孩子
代码就是文档……
1.0看 傻孩子常用基础头文件
2.0看置顶的其他库
2.1看这个帖子
-----------------------------------------------------------------------

在坛子里搜不到“傻孩子常用基础头文件 ”啊?

出0入296汤圆

 楼主| 发表于 2010-3-12 09:31:29 | 显示全部楼层
to 【31楼】 GZZXB

在我专栏的置顶贴里面。

http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=903562&bbs_page_no=1&bbs_id=1038

出0入0汤圆

发表于 2010-3-12 09:57:30 | 显示全部楼层
呵呵,很漂亮的代码。
Doxygen里面,我建议结构成员不要用如下的方式:
//!< alive flag
建议用:
//! alive flag

像//!< alive flag 用在枚举里面比较合适。

出0入296汤圆

 楼主| 发表于 2010-3-12 10:19:33 | 显示全部楼层
to 【33楼】 oldtom
    哦? //!< alive flag和//! alive flag 的区别不仅仅是注释最后的位置不同么?

出0入0汤圆

发表于 2010-3-12 11:00:53 | 显示全部楼层
好~~~~~~

出0入0汤圆

发表于 2010-3-12 14:49:20 | 显示全部楼层
回复【34楼】Gorgon Meducer 傻孩子
-----------------------------------------------------------------------

官方文档推荐这么干的。呵呵。

出0入0汤圆

发表于 2010-3-12 15:52:44 | 显示全部楼层
任务中能开中断不?

出0入296汤圆

 楼主| 发表于 2010-3-14 18:11:51 | 显示全部楼层
to 【36楼】 oldtom  
    谢谢,下次我会注意的。

to 【37楼】 savagex
    当然可以。默认情况下,任务处理函数是在 主循环的 超级循环中运行的。
所以全局中断本来就是开启的。而通常我们需要保证某些操作是原子操作的时候,
应该用
SAFE_ATOM_CODE
(
    代码
)
的结构来处理。如果在括号中需要临时退出,则使用EXIT_SAFE_ATOM_CODE

例如

SAFE_ATOM_CODE
(
    ...
    if (xxx)
    {
        ....
        EXIT_SAFE_ATOM_CODE();
        return ;
    }
    ...
)

出0入0汤圆

发表于 2010-3-16 09:54:11 | 显示全部楼层
直接将上面工程模板进行GCC编译。报错:


(原文件名:未命名.jpg)

出0入296汤圆

 楼主| 发表于 2010-3-16 09:59:13 | 显示全部楼层
你用下面的版本看看,在build目录里面有一个gcc的工程
点击此处下载 ourdev_538606.rar(文件大小:23K) (原文件名:Project.rar)

出0入0汤圆

发表于 2010-3-23 20:21:00 | 显示全部楼层
新作挺起

出0入0汤圆

发表于 2010-3-23 20:33:22 | 显示全部楼层
只有GCC的工程文件,没有建立IAR的工程文件呢??

出0入296汤圆

 楼主| 发表于 2010-3-23 20:56:30 | 显示全部楼层
自己建立一个?反正很快……

出0入0汤圆

发表于 2010-3-23 21:02:03 | 显示全部楼层
哎,真杯具啊!!一直用IAR
GCC这个版本的工程文件我竟然不会打开~~
没用过GCCAVR
好像又和AVR Studio 有点关系?
请 版主发个IAR版本的工程吧!!
期待!!

出0入0汤圆

发表于 2010-3-23 21:39:42 | 显示全部楼层
一句话的事儿!!

出0入296汤圆

 楼主| 发表于 2010-3-23 22:31:42 | 显示全部楼层
to 楼上
开一个IAR的工程,把所有.c文件全部加入进去,选芯片,编译……OK……

出0入0汤圆

发表于 2010-3-25 00:32:39 | 显示全部楼层
不错

出0入59汤圆

发表于 2010-3-25 05:40:53 | 显示全部楼层
楼主就是...套用一句朋友的话:“好习惯成就幸福人生!”

出0入0汤圆

发表于 2010-4-8 16:35:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-8 16:50:53 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-13 16:58:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-14 08:31:13 | 显示全部楼层
o(∩_∩)o...

出0入0汤圆

发表于 2010-4-14 08:40:13 | 显示全部楼层
顶一个

出0入0汤圆

发表于 2010-4-19 13:58:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-19 16:15:50 | 显示全部楼层
不错,mark

出0入0汤圆

发表于 2010-4-19 16:47:39 | 显示全部楼层
MARK
THX

出0入0汤圆

发表于 2010-5-7 20:23:24 | 显示全部楼层
写得很好,获益良多,不过有些问题请教。

1、
--------------
3、xxxxx.c 里面 强烈建议不要包含 xxxxx.h 当我们具体要使用某个头文件的
       时候,应该通过 “相对路径来添加”
--------------
你的实现确实如你所说:miniFSM.c没有包含miniFSM.h,但两个文件却都有MINI_FSM_TASK的定义,这使得需要
维护两份相同的代码,这样做有什么好处呢?

2、
---------------
typedef struct
{
#if MCU_MEM_LITTLE_ENDIAN
    //! little-endian
    unsigned Available      : 1;            //!< avaliable flag
    unsigned IsAlive        : 1;            //!< alive flag
    #if MINI_FSM_TIMER_BASED == ES_ENABLED
    unsigned Period         : 14;           //!< task working period
    uint16_t TimeTicker;                    //!< task time ticker
    #else
    unsigned Reserved       : 14;   
    #endif
    MINI_FSM_TASK_HANDLER *fnTaskRoutine;   //!< task routine
#else
    //! big-endian
    MINI_FSM_TASK_HANDLER *fnTaskRoutine;   //!< task routine
    #if MINI_FSM_TIMER_BASED == ES_ENABLED
    uint16_t TimeTicker;                    //!< task time ticker
    unsigned Period         : 14;           //!< task working period
    #else
    unsigned Reserved       : 14;
    #endif
    unsigned IsAlive        : 1;            //!< alive flag
    unsigned Available      : 1;            //!< avaliable flag
#endif
}MINI_FSM_TASK;
------------
在MINI_FSM_TASK的定义中,你用了位域,这样做的目的应该是节约RAM的占有,但相反为了生成处理位域的代码会不会反过来
增加对flash的占用呢,有实验数据吗?

3、
-------------
还有你在楼主发的工程确定是通过编译了的吗?工程中有如下的代码:
void mini_FSM_Release_Task(uint8_t chTaskID)
{
    if (chTaskID < UBOUND(s_fsmTasks))
    {
        SAFE_ATOM_CODE
        {
            s_fsmTasks[chTaskID].Available = false;
        }
    }
}

   SAFE_ATOM_CODE
    (
        if (s_bLocker)
        {
            EXIT_SAFE_ATOM_CODE();
            return NULL;
        }
        s_bLocker = true;
    }
两个地方SAFE_ATOM_CODE用的括号不一致,甚至后面的用的是"("和“}”配对。

4、
-------------
在你的调度算法中
if (
                (0x03 == (((volatile uint8_t *)&s_fsmTasks[n])[0] & 0x03))
            &&  (NULL != s_fsmTasks[n].fnTaskRoutine)
           )
        {
            bool result = s_fsmTasks[n].fnTaskRoutine();
            
            ATOM_CODE
            (
                s_fsmTasks[n].IsAlive = result;
            )
            
            bIfIdle = false;
        }
应该是根据IsAlive、Available两个bool值来决定任务是否执行的,没有体现“状态”调度吧?

出0入296汤圆

 楼主| 发表于 2010-5-7 21:41:22 | 显示全部楼层
to 【57楼】 ifree64
    1、好处自己体会,主要体现在封装上。
    2、很多编译器会生成对应的与或操作,你自己用变量进行与或操作效果一致。
    3、这个帖子贴出来很久了,我这里的代码已经更新很多了,但是很多人只是
       mark,让我误认为仔细阅读的人并不多,所以,没有动力去更新这个帖子。
       我电脑上的副本已经在实际工程中测试和应用了。
    4、这个调度器同时兼容状态机以及非状态机的情况;对于状态机来说,返回
       true或者false就表示状态机是否需要继续执行。具体的状态实现,要依靠
       状态机本身来处理。

出0入0汤圆

发表于 2010-5-7 21:49:01 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-5-7 22:54:42 | 显示全部楼层
to 【58楼】 Gorgon Meducer 傻孩子

第1点,如果是最小界面,我认为miniFSM.h甚至不需要声明MINI_FSM_TASK结构体。因为作为使用调度服务的模块而言
需要的只是注册、删除任务而已,根本不需要知道这个结构体的实现细节。

第2点,我的意思是,直接用字符变量,“浪费”点RAM,可不可以换来节约flash,毕竟你是用在小flash的片子上的。

第4点,我现在在关注如何使用“时间触发”调度来编写实际工程,而不是书上的示例程序,而你的调度算法,我看来和时间触发没有
本质区别,因为采用时间触发,每一个任务就必须在时标时间内完成,对于一些长时间的任务要在很短的时标时间内完成就必须对
任务进行基于状态机的分解。你的默认调度算法只是没有加上时间触发这个特性而已,但每个任务仍然是要求必须在足够短的时间内
完成的,因为调度中没有实现抢占。
基于以上理由,我只是有点学究的认为你的调度不能算是“状态机调度器”,而是必须采用状态机的思想来编写每个任务,
当然叫什么不伤大雅。
对时间触发或你的这种调度方式,我有一个疑问是,是否能对大部分需要长时间的任务进行基于状态机的分解呢?这关系到这种调度
算法的适用范围。比如读取sd卡上的fat32文件系统,严格依赖时序的

另,能否帮忙解答下我在这个帖子中的问题?我对电机控制实在不在行,谢谢!
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4020691&bbs_page_no=1&search_mode=3&search_text=ifree64&bbs_id=9999

出0入296汤圆

 楼主| 发表于 2010-5-7 23:08:09 | 显示全部楼层
to 【60楼】 ifree64
    1、另外一个测试版本的调度器完全屏蔽了对应的控制块结构体
    2、RAM往往也很紧张
    3、你所理解的,必须用状态机的思想来编写每个任务恰恰是我一直
       强调的前提。所以你这么想,真得让我觉得自己的设计很到位。
       所以,这个调度器就是“状态机”的调度器。
       另外,所有程序都可以拆解为状态机,如果你能画出流程图,那么
       你把每一个流程图上的方框写成一个状态,或者某几个方框作为一
       个状态,就可以把所有程序都拆解为状态机。
   
    从计算机科学的角度看,有限状态机(FSM)是描述所有计算问题的
核心方法。计算机科学把所有问题都可以看作对某种字符串的处理,而
解决问题就可以看作是判断某个输入的字符串是否在某个已知的字符串
集合中。描述或者判断字符串问题可以使用FSM或者PDA(Pushdown automaton)
或者图灵机(Turing Machine)。所以,状态机可以描述所有可以用程序
描述的处理过程。而PDA(带栈的FSM)以及其他代队列或者复杂数据结构
的FSM可以解决我们日常生活中大部分的应用问题。图灵机本身也是以FSM
为核心进行描述的。以上的内容是我在学习计算机基础理论的过程中学到
得,正在深入的体会。希望对大家有用,同时别说我掉书袋。

出0入0汤圆

发表于 2010-5-7 23:50:54 | 显示全部楼层
to 【61楼】 Gorgon Meducer 傻孩子
你在多个帖子里都提到过这几个术语:
FSM、PDA(Pushdown automaton) 、Turing Machine
我曾经想在计算机的理论书籍里找关于状态机、图灵机的正式讲述,翻过《算法导论》、《编译原理》(龙书,这个太难了,还没弄懂)
看到的好像也没有专门正式讨论状态机、图灵机的理论。请问你看的是什么资料,或在什么资料上有这些概念较为详尽的阐述。

出0入296汤圆

 楼主| 发表于 2010-5-8 00:37:36 | 显示全部楼层
Automata, Computability and Complexity Theory and Applications

出0入0汤圆

发表于 2010-5-8 00:44:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-8 07:59:11 | 显示全部楼层
mark,学习

出0入0汤圆

发表于 2010-5-8 08:26:53 | 显示全部楼层
mark,楼主辛苦了

出0入8汤圆

发表于 2010-5-8 11:45:07 | 显示全部楼层
傻大侠辛苦了
下载了大致看了
一、给两个例子,如按键、led、uart通讯,可能更便于理解;
二、编码风格既有下划线又有大小写,我认为有些乱,个人喜欢小写加下划线的方式,如rt-thread的编码风格很规整

出0入296汤圆

 楼主| 发表于 2010-5-8 17:36:29 | 显示全部楼层
to 【67楼】 rube 永丰庵
    谢谢你的建议,大写只用于宏或者缩写字符。

出0入0汤圆

发表于 2010-5-8 23:53:19 | 显示全部楼层
to【63楼】 Gorgon Meducer 傻孩子

Automata, Computability and Complexity Theory and Applications

该书有国内的影印版或中文版吗?用$来买书买不起。

出0入0汤圆

发表于 2010-5-9 07:04:26 | 显示全部楼层
我也先MARK,呵呵

出0入296汤圆

 楼主| 发表于 2010-5-9 11:26:50 | 显示全部楼层
to 【69楼】 ifree64
    各大新华书店均有销售。而且我这里还有电子版本。

出0入0汤圆

发表于 2010-5-9 19:44:11 | 显示全部楼层
呵呵,既然有电子版本,可否发一本给我。
ifree64@gmail.com

出0入296汤圆

 楼主| 发表于 2010-5-9 20:52:50 | 显示全部楼层
to 【72楼】 ifree64
    100多M……庞然大物,你可以到www.ppurl.com取下载

出0入0汤圆

发表于 2010-5-9 22:42:07 | 显示全部楼层
谢谢傻孩子介绍的网站。不过没找到你提到的那本书。
china-pub上用Automat作为关键字只搜索到一本
Addison-Wesley - Introduction to Automata Theory, Languages and Computation

出0入0汤圆

发表于 2010-5-9 23:23:36 | 显示全部楼层
MARK 调度器
MARK 状态机
MARK 设计思想

出0入0汤圆

发表于 2010-5-10 00:43:52 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-11 09:21:30 | 显示全部楼层
回复【58楼】Gorgon Meducer 傻孩子
to 【57楼】 ifree64  
    1、好处自己体会,主要体现在封装上。
    2、很多编译器会生成对应的与或操作,你自己用变量进行与或操作效果一致。
    3、这个帖子贴出来很久了,我这里的代码已经更新很多了,但是很多人只是
       mark,让我误认为仔细阅读的人并不多,所以,没有动力去更新这个帖子。
       我电脑上的副本已经在实际工程中测试和应用了。
    4、这个调度器同时兼容状态机以及非状态机的情况;对于状态机来说,返回
       true或者false就表示状态机是否需要继续执行。具体的状态实现,要依靠
       状态机本身来处理。
-----------------------------------------------------------------------

能讲一下具体的更新么?

出0入0汤圆

发表于 2010-5-14 08:40:47 | 显示全部楼层
学习

出0入296汤圆

 楼主| 发表于 2010-5-14 09:30:58 | 显示全部楼层
Design module main task<font color=brown>
In this chapter we will describe some key principles which should be aware
in the design of the module main task function.
First, all code in a module main task function should be written in none-block
fashion. Or we should say, the function should be written as a finite state
machine. There are thousands ways to write a FSM, and a recommended
style could be seen in file “service\communication\protocol_engine.c”.
Please refer to the function COM_protocol_parser_task() and related states
macros defined in the same file.
Second, if a task function returns a false value, it means this task completes
its own work and don’t care whether the system enter some sleep model or
not. Meanwhile, to return a false value dose not guarantees that this task will
not be called even it wants itself to be in a blocked model. In fact, if a task
want to enter some blocked / paused / dead / states, it should keep its words:
return false all the time unless it changes its mind. For example, if a task
wants itself to be called only once every 100ms, it should return false after
its first called when a 100ms coming. See figure E-1:



Third, if a task tries to return a false value to release its control, it should
register/request a maximum allowed sleep level by call a function named
es_request_sleep() which could be found in the head file
“hal/bsp/es_sleep/es_sleep.h”. This function require a nonnegative integer
value as its input parameter, which zero means no sleep is allowed, and
0xFFmeans the task don’t care.
In the schedule’s point of view, if all tasks return a false value, system enters
an idle mode and a idle task should be called. According to current design,
idle task will check the minimum sleep level requested by tasks and some
services routines, uses it to enter related MCU sleep mode. If a task
requests a no sleep model irresponsible, there is no way to enter any sleep
model, and the system power consumption will be maintained at a higher
level. So, for most of the time, we should use 0xFF as often as possible.



<font color=red>最新更新


点击此处下载 ourdev_553981.rar(文件大小:23K) (原文件名:Template.rar)

出0入0汤圆

发表于 2010-5-14 13:22:48 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-6-8 13:20:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-9 00:39:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-14 11:35:25 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-29 01:39:34 | 显示全部楼层
好像才自认为 搞定1.0的结构 看到2.x的先 马克一下
等两天再搞定 要考试了!
谢谢傻孩子!
支持!

出0入0汤圆

发表于 2010-8-18 10:04:17 | 显示全部楼层
( ^_^ )/~~拜拜傻孩子,认真学习

出0入0汤圆

发表于 2010-8-18 13:02:04 | 显示全部楼层
MARK!

出0入0汤圆

发表于 2010-8-18 14:23:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-30 20:07:19 | 显示全部楼层

出0入264汤圆

发表于 2010-10-17 11:40:20 | 显示全部楼层
精彩。

出0入0汤圆

发表于 2010-10-18 17:37:29 | 显示全部楼层
回复【79楼】Gorgon Meducer 傻孩子
-----------------------------------------------------------------------

<Design module main task>是那一本书?

出0入296汤圆

 楼主| 发表于 2010-10-18 19:58:03 | 显示全部楼层
给老外写的用户手册的一个部分……

出0入0汤圆

发表于 2010-12-7 23:15:12 | 显示全部楼层
先收藏 慢慢研究

出0入0汤圆

发表于 2011-3-16 11:51:58 | 显示全部楼层
大的思路算是搞懂了,剩下慢慢研究~

  是不是 MINI_FSM_TIMER_BASED ==ES_ENABLED

  就要在中断程序里面跑mini_FSM_time_based_task_manager?

  运行一个任务 mini_FSM_Register_Task &mini_FSM_start_task 不就可以了吗?为什么还要单独mini_FSM_set_task_ready ?
  
  这个东西不错,我也有一个类似的程序,比较简单,实际也是在中断里面完成时间处理~

出0入4汤圆

发表于 2011-3-16 11:52:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-16 12:24:33 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-3-16 12:38:51 | 显示全部楼层
mark

出0入296汤圆

 楼主| 发表于 2011-3-16 13:40:04 | 显示全部楼层
to 【95楼】 embeddev
     “运行一个任务 mini_FSM_Register_Task &mini_FSM_start_task 不就可以了吗?为什么还要单独mini_FSM_set_task_ready ? ”
   ——请问这个函数“mini_FSM_set_task_ready”在什么地方……我貌似没有找到……

出0入0汤圆

发表于 2011-3-17 19:40:41 | 显示全部楼层
我还有两个疑问

  1 是我看了下,感觉要不就选择MINI_FSM_TIMER_BASED 基于时间模式的,要不就选择立即执行的模式(我自己起的名),但是实际情况是两种一般都会存在啊?
  
  2 那个时间模式的定时器计算定时到会不会有bug?

出0入296汤圆

 楼主| 发表于 2011-3-17 19:47:55 | 显示全部楼层
1、为啥不能同时存在呢?
2、什么样的BUG?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-14 09:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表