在内嵌模式中,用户程序和系统程序运行在同一处理器上,但是它是独立编译和链接的,它们之间通过消息进行交互, 如下图所示

事件驱动模型
系统程序需要处理无线协议,有严格的时序要求,用户程序不能影响这种节奏,它采用的编程模式采用事件驱动模型,该模型原理如下图所示,程序由事件处理handle构成,它们响应的事件输入,避免长时间轮询(大于1ms)等待,这样好处是提高系统反应速度。

事件/消息的来源主要有三类:
- 系统程序产生的消息
- 中断程序产生的消息
- 用户程序自己的消息
消息处理接口
系统程序和用户程序分别提供自己的消息处理接口,通过这个接口双方进行消息交互,接口的原型定义下
wipc_result_t wipc_msg_proc(wipc_msg_type_t type, void *in, void *out, void *ctx);
参数说明如下
名称 | 类型 | 描述 |
---|---|---|
type | wipc_msg_type_t | 详见消息描述表 |
in | void* | 输入数据 |
out | void* | 输出数据 |
ctx | void* | 用户程序数据空间,用来保存它的运行环境,是由系统程序预分配的,每次传递消息时候,都会传入这个空间 |
编程注意事项
需要注意用户程序和常规的编程模式稍微有点区别,因为RESET中断和主程序入口均由系统程序接管,内嵌模式的入口就是消息处理函数,由于它和系统程序是分别编译和链接的,导致它的.bss和.data均未被初始化,需要避免使用自定义全局变量,但全局数据可以保存在系统程序传入的ctx空间中,函数定义中局部变量可以自由使用的,这个原则同样适用它调用的库函数。总之一句话,就是不要使用全局变量。
库名 | 使用方法 |
---|---|
glibc | 使用可重入的函数,或者函数的可重入接口,这些信息可以再库函数手册中查到 |
stm32 driver | 使用 LL (Low-Level)Driver 库,避免使用HAL Driver |
我们提供基于IAR, Keil和GCC程序模板,还提供了多种传感器的总线驱动和应用场景的例程供参考。