4520|10

750

帖子

3

TA的资源

版主

楼主
 

【LPC54100】在M0上跑事件驱动构架 [复制链接]

初次接触非对称双核MCU,由于之前好多知识不熟悉,这三天遇到不少问题。现在终于把事件驱动在M0核上跑起来了,就发一贴简单介绍下这个事件驱动构架和这几天的5410x芯片学习所得。
关于事件驱动架构,其主要用于低功耗设计,可以很方便的进入休眠模式。一般单片机裸奔都是轮询,如:
  1. void main()
  2. {
  3.     while(1)
  4.     {
  5.         tesk1();
  6.         tesk2();
  7.         tesk3();
  8.     }
  9. }
复制代码
在这种轮询处理中,很难判断在何时休眠,该休眠多长时间,又该使用什么等级的休眠。

而事件驱动的main函数如下(以VSF为例):
  1. while (1)
  2.         {
  3.                 vsfsm_poll();

  4.                 vsf_enter_critical();
  5.                 if (!vsfsm_get_event_pending())
  6.                 {
  7.                         vsf_leave_critical();
  8.                         __WFI();
  9.                 }
  10.                 else
  11.                 {
  12.                         vsf_leave_critical();
  13.                 }
  14.         }
复制代码
VSF在程序中增加了一个事件队列,当这个事件队列为空时,即进行休眠。休眠时间由程序所配置的唤醒定时器决定,当然一些外部硬件中断也可以唤醒。如果需要使用不同的休眠等级,那也需要做一个休眠等级管理器,不同线程要求不同的休眠等级,然后由管理器决定休眠等级。当然这些细化配置会比较麻烦...

其实,事件驱动能干的,在RTOS中都能干,很多事情RTOS可以干的更好,更舒服。但是,事件驱动有一个最大的优点:省RAM,在很多低功耗MCU中,RAM一般比较小,RTOS虽然都能裁剪,但是每个任务所分配的堆栈不能裁剪,当任务一多,ram分配也挺烦心。而事件驱动归根到底还是裸奔,只是将线程(一个函数指针加一个事件状态)放在队列中进行管理,逐个调用而已。每个线程只花费十几个字节RAM。

这次所用的是Simon的事件驱动VSF平台,代码是放在github上的,github.com/versaloon/vsf,21ic也有一些介绍帖,有兴趣自己去看。
下面把示例代码献丑一下,非常非常粗糙的,帖子里的代码额外增加了中文说明
  1. // 线程1
  2. // 定义一个事件状态
  3. #define EVENT_1_USER_LOCAL_SCANF                (VSFSM_EVT_USER_LOCAL + 1)
  4. static struct vsfsm_state_t *
  5. event_1_handler(struct vsfsm_t *sm, vsfsm_evt_t evt);
  6. struct vsfsm_t event_1_sm =
  7. {
  8.         {event_1_handler}, // 初始化handler
  9. };
  10. // 用于产生间隔为5秒的周期事件定时器
  11. static struct vsftimer_timer_t event_1_timer =
  12. {
  13.         5000,        // 间隔为5秒
  14.         &event_1_sm,        // 对应状态机
  15.         EVENT_1_USER_LOCAL_SCANF, // 周期事件
  16. };

  17. struct vsfsm_state_t *
  18. event_1_handler(struct vsfsm_t *sm, vsfsm_evt_t evt)
  19. {
  20.         switch (evt)
  21.         {
  22.         case VSFSM_EVT_INIT: // 初始化事件时,被默认执行
  23.                 vsftimer_register(&event_1_timer);
  24.                 break;
  25.         case EVENT_1_USER_LOCAL_SCANF: // 周期事件处理
  26.                 Board_UARTPutSTR("event 1\r\n"); // 打印出“event 1”
  27.                 print_tick();                                        // 打印出当前系统tick
  28.                 break;
  29.         default:
  30.                 break;
  31.         }
  32.        
  33.         return NULL;
  34. }

  35. // 线程2,将线程间隔改为3秒
  36. #define EVENT_2_USER_LOCAL_SCANF                (VSFSM_EVT_USER_LOCAL + 1)
  37. static struct vsfsm_state_t *
  38. event_2_handler(struct vsfsm_t *sm, vsfsm_evt_t evt);
  39. struct vsfsm_t event_2_sm =
  40. {
  41.         {event_2_handler},
  42. };
  43. static struct vsftimer_timer_t event_2_timer =
  44. {
  45.         3000,
  46.         &event_2_sm,
  47.         EVENT_2_USER_LOCAL_SCANF,
  48. };

  49. struct vsfsm_state_t *
  50. event_2_handler(struct vsfsm_t *sm, vsfsm_evt_t evt)
  51. {
  52.         switch (evt)
  53.         {
  54.         case VSFSM_EVT_INIT:
  55.                 vsftimer_register(&event_2_timer);
  56.                 break;
  57.         case EVENT_2_USER_LOCAL_SCANF:
  58.                 Board_UARTPutSTR("event 2\r\n");
  59.                 print_tick();
  60.                 break;
  61.         default:
  62.                 break;
  63.         }
  64.        
  65.         return NULL;
  66. }


  67. int main(void)
  68. {
  69.         // 串口初始化
  70.         board_uart_init();
  71.         // 使用utick中断唤醒
  72.         board_utick_init();
  73.        
  74.         vsftimer_init();
  75.        
  76.         Board_UARTPutSTR("START!\r\n");
  77.        
  78.         vsfsm_init(&event_1_sm);
  79.         vsfsm_init(&event_2_sm);

  80.         vsf_leave_critical();
  81.         while (1)
  82.         {
  83.                 vsfsm_poll(); // 轮询状态机

  84.                 vsf_enter_critical();
  85.                 if (!vsfsm_get_event_pending()) // 判断是否有未处理事件
  86.                 {
  87.                         vsf_leave_critical();
  88.                         __WFI();
  89.                 }
  90.                 else
  91.                 {
  92.                         vsf_leave_critical();
  93.                 }
  94.         }
  95. }
复制代码
串口输出:


PS: 现在的vsftimer并没有做休眠时间的动态管理,而是简单粗暴的定时唤醒一次,看看有没有事件需要处理。这个功能我会在后面完善。
Simon的架构中还有很多好玩的东西,有兴趣可以去研究下。
此帖出自NXP MCU论坛

最新回复

收藏了,留着以后有时间再看。  详情 回复 发表于 2015-4-8 21:29
点赞 关注(1)
个人签名

要666

 

回复
举报

750

帖子

3

TA的资源

版主

沙发
 
本帖最后由 le062 于 2015-2-16 09:41 编辑

一些新玩意

1.总线矩阵

如下图所示,M4及M0核分别通过各自的总线访问外设,
两个核心所使用的外设地址是相同的,当他们同时访问相同外设时,就会产生竞争,其中一个核心被阻塞。所以最好让一个核心在SRAM0或SRAM1中运行。

2.中断管理

之前玩单核MCU,并没有注意到NVIC是与arm核紧密耦合的,在研究LPC54100时才注意到两个核心各有一个NVIC,用于控制该核心对外设中断的响应。

在LPC54100中,NVIC寄存器的地址是一致的,但是每个核心访问这些基础器时,实际操作的寄存器是不一样的,这一点不同于公用外设。在《LPC5410x User manual》中有下面这句话:


3.启动过程

LPC54102中有一块ROM区域,里面是M4核心的固化代码,复位后,m0核心并不运行,m4核心从rom中启动,之后引导M0核心。

由于这个差异,在单独调试M0核遇到了一些问题,这点需要注意。

这部分可参看《AN11609_LPC54xxx_DualCore_v1.0.pdf》

此帖出自NXP MCU论坛
 
个人签名

要666

 
 

回复

750

帖子

3

TA的资源

版主

板凳
个人签名

要666

 
 

回复

750

帖子

3

TA的资源

版主

4
 
代码地址:git.oschina.net/le062/LPCXpresso54102-leop
此帖出自NXP MCU论坛
 
个人签名

要666

 
 

回复

527

帖子

1

TA的资源

一粒金砂(高级)

5
 
多谢分享
此帖出自NXP MCU论坛
 
 
 

回复

862

帖子

2

TA的资源

纯净的硅(初级)

6
 
这个时间驱动有点意思了,希望楼主多分享经验,我也学习学习!!
此帖出自NXP MCU论坛
 
个人签名水不撩不知深浅 人不拼怎知输赢
 
 

回复

5310

帖子

453

TA的资源

五彩晶圆(高级)

7
 
board_utick_init();

是Micro-tick timer (UTICK)吗?
此帖出自NXP MCU论坛

点评

好像是的把, 最新代码已经换成通用timer了。  详情 回复 发表于 2015-4-4 19:50
 
 
 

回复

750

帖子

3

TA的资源

版主

8
 
蓝雨夜 发表于 2015-4-4 14:10
board_utick_init();

是Micro-tick timer (UTICK)吗?

好像是的把,

最新代码已经换成通用timer了。
此帖出自NXP MCU论坛

点评

board_utick_init(); 不是你自己写的吗? 和lpcopen不同啊  详情 回复 发表于 2015-4-4 23:05
 
个人签名

要666

 
 

回复

5310

帖子

453

TA的资源

五彩晶圆(高级)

9
 
le062 发表于 2015-4-4 19:50
好像是的把,

最新代码已经换成通用timer了。

board_utick_init();

不是你自己写的吗?

和lpcopen不同啊
此帖出自NXP MCU论坛

点评

嗯,写了,然后忘了。代码都在那,看代码吧  详情 回复 发表于 2015-4-5 05:41
 
 
 

回复

750

帖子

3

TA的资源

版主

10
 
蓝雨夜 发表于 2015-4-4 23:05
board_utick_init();

不是你自己写的吗?

和lpcopen不同啊

嗯,写了,然后忘了。代码都在那,看代码吧



此帖出自NXP MCU论坛
 
个人签名

要666

 
 

回复

105

帖子

1

TA的资源

一粒金砂(中级)

11
 
收藏了,留着以后有时间再看。
此帖出自NXP MCU论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表