Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
DIY综合交流区
[RealTouch例程]邮箱的基本使用
发布于 2012-08-17 22:19:44 浏览:5563
订阅该版
实验目的 ? 了解邮箱的基本使用 ? 熟练使用邮箱相关API实现多个线程间通信 硬件说明 本实验使用RT-Thread官方的Realtouch开发板作为实验平台。涉及到的硬件主要为: ? 串口3,作为rt_kprintf输出 需要连接JTAG扩展板,具体请参见《Realtouch开发板使用手册》 实验原理及程序结构 实验设计 本实验的主要设计目的是帮助读者快速了解邮箱相关API,包括静态邮箱初始化/脱离,发送/接受邮件。本实验中使用静态邮箱控制块,动态邮箱的使用就交给读者测试。 本实验中创建一个邮箱,两个线程,线程2以一定周期发送邮箱,线程1以一定周期从邮箱中取出邮件。当线程2中发送20封邮件之后,发送一封特殊的邮件通知其他线程,自己已经运行结束。线程1取出邮件后,检查邮件是否是特殊邮件,如果是,则线程1也退出。 源程序说明 本实验对应kernel_mailbox_basic。 系统依赖 在rtconfig.h中需要开启 ``` #define RT_USING_HEAP``` 此项可选,开启此项可以创建动态线程和动态邮箱,如果使用静态线程和静态信号量,则此项不是必要的 ``` #define RT_USING_MAILBOX``` 此项必须,开启此项后才可以使用邮箱相关API。 ``` #define RT_USING_CONSOLE``` 此项必须,本实验使用rt_kpriintf向串口打印按键信息,因此需要开启此项 主程序说明 在applications/application.c中定义静态邮箱控制块、存放邮件的缓冲区,以及一些字符串用来作为邮件。如下所示 定义全局变量代码 ```/* 邮箱控制块 */ static struct rt_mailbox mb; /* 用于放邮件的内存池 */ static char mb_pool[128]; static char mb_str1[] = "I'm a mail!"; static char mb_str2[] = "this is another mail!"; static char mb_str3[] = "over"; 在applications/application.c中的 int rt_application_init()函数中,初始化邮箱。 初始化邮箱代码 rt_err_t result; /* 初始化一个mailbox */ result = rt_mb_init(&mb, "mbt", /* 名称是mbt */ &mb_pool[0], /* 邮箱用到的内存池是mb_pool */ sizeof(mb_pool)/4, /* 邮箱中的邮件数目,因为一封邮件占4字节 */ RT_IPC_FLAG_FIFO); /* 采用FIFO方式进行线程等待 */ if (result != RT_EOK) { rt_kprintf("init mailbox failed. "); return -1; } ```在int rt_application_init()初始化名为”thread1”的thread1的静态线程,如下所示。 初始化线程1代码 ``` rt_thread_init(&thread1, "thread1", thread1_entry, RT_NULL, &thread1_stack[0], sizeof(thread1_stack),10,5); rt_thread_startup(&thread1); ```其线程入口函数如下所示,线程1以10个tick的间隔不停地从邮箱中取出邮件,并打印每每封邮件的内容,并对每封邮件进行检查。当检测邮件为特殊的邮件(mb_str3)这表明这是线程2发送的最后一封邮件,则线程1不再循环接收邮件,从while循环中调出,线程函数运行结束。 线程1代码 ```ALIGN(RT_ALIGN_SIZE) //设置下一句线程栈数组为对齐地址 static char thread1_stack[1024]; //设置线程堆栈为1024Bytes struct rt_thread thread1; //定义静态线程数据结构 /* 线程1入口 */ static void thread1_entry(void* parameter) { char* str; while (1) { rt_kprintf("thread1: try to recv a mail "); /* 从邮箱中收取邮件 */ if (rt_mb_recv(&mb, (rt_uint32_t*)&str, RT_WAITING_FOREVER) == RT_EOK) { rt_kprintf("thread1: get a mail from mailbox, the content:%s ", str); if (str == mb_str3) break; /* 延时10个OS Tick */ rt_thread_delay(10); } } /* 执行邮箱对象脱离 */ rt_mb_detach(&mb); } ```在int rt_application_init()初始化名为”thread2”的thread2的静态线程,如下所示。 初始化线程2代码 ``` rt_thread_init(&thread2, "thread2", thread2_entry, RT_NULL, &thread2_stack[0], sizeof(thread2_stack),10,5); rt_thread_startup(&thread2); ```其线程入口函数如下所示,线程2以20个tick的间隔不停地向邮箱中发送邮件,并使用变量count进行计数,奇数次发送数组mb_str1首地址作为邮件,偶数次发送数组mb_str2首地址作为邮件,累计发送20封邮件后,将发送数组mb_str3首地址作为邮件发送,这是线程2发送的最后一封邮件,线程函数运行结束。 线程2代码 ```ALIGN(RT_ALIGN_SIZE) //设置下一句线程栈数组为对齐地址 static char thread2_stack[1024]; //设置线程堆栈为1024Bytes struct rt_thread thread2; //定义静态线程数据结构 /* 线程2入口 */ static void thread2_entry(void* parameter) { rt_uint8_t count; count = 0; while (count < 10) { count ++; if (count & 0x1) { /* 发送mb_str1地址到邮箱中 */ rt_mb_send(&mb, (rt_uint32_t)&mb_str1[0]); } else { /* 发送mb_str2地址到邮箱中 */ rt_mb_send(&mb, (rt_uint32_t)&mb_str2[0]); } /* 延时20个OS Tick */ rt_thread_delay(20); } /* 发送邮件告诉线程1,线程2已经运行结束 */ rt_mb_send(&mb, (rt_uint32_t)&mb_str3[0]); } ```编译调试及观察输出信息 编译请参见《RT-Thread配置开发环境指南》完成编译烧录,参考《Realtouch开发板使用手册》完成硬件连接,连接扩展板上的串口和jlink。 运行后可在串口上看到如下信息: 串口输出 | / - RT - Thread Operating System / | 1.1.0 build Aug 9 2012 2006 - 2012 Copyright by rt-thread team thread1: try to recv a mail thread1: get a mail from mailbox, the content:I'm a mail! thread1: try to recv a mail thread1: get a mail from mailbox, the content:this is another mail! thread1: try to recv a mail thread1: get a mail from mailbox, the content:I'm a mail! thread1: try to recv a mail thread1: get a mail from mailbox, the content:this is another mail! thread1: try to recv a mail thread1: get a mail from mailbox, the content:I'm a mail! thread1: try to recv a mail thread1: get a mail from mailbox, the content:this is another mail! thread1: try to recv a mail thread1: get a mail from mailbox, the content:I'm a mail! thread1: try to recv a mail thread1: get a mail from mailbox, the content:this is another mail! thread1: try to recv a mail thread1: get a mail from mailbox, the content:I'm a mail! thread1: try to recv a mail thread1: get a mail from mailbox, the content:this is another mail! thread1: try to recv a mail thread1: get a mail from mailbox, the content:over 结果分析 整个程序运行过程中各个线程的状态变化: rt_application_init中创建线程thread1和thread2,两者具有相同的优先级,由于先使用rt_thread_startup(&thread1),故线程1优先运行,首先执行: rt_kprintf("thread1: try to recv a mail "); 无法确定此语句执行时间大致是多少个tick,这个跟RT_TICK_PERSECOND的设定、系统的主频、以串口驱动的实现有关。不过庆幸的是,这些不确定因素并不影响程序最终的运行结果。 当线程1试图从邮箱中获取邮件时,如果邮箱中没有邮件,则线程1被挂起直到邮箱中填充了邮件。此时线程2就会运行,向邮件中发送邮件,之后休眠20个tick,线程2挂起,线程1继续调度运行。线程1从邮箱中收到邮件后,打印邮件内容,检查邮件是否是最后一封,若是,则线程1跳出循环,脱离静态邮箱控制块,线程函数运行结束;若否,则线程1挂起10个tick。如果此时线程2也在挂起,则内核执行IDLE线程。当线程2发送20封邮件后,发送最后一封邮件,线程函数处理结束。 在IDLE线程中将两个线程脱离。 总结 本实验演示了RT-Thread中邮箱/邮件作为多线程通信的用法,以静态邮箱控制块为例,动态邮箱的用法类似,只是创建/删除需要使用 rt_mb_create/rt_mb_delete函数,读者可以使用动态邮箱重复本实验。 [attach]0[/attach] 下载附件 [实验2_7邮箱基本使用.pdf](https://oss-club.rt-thread.org/uploads/88_fce851d2c9a6f24165e83e625ee78cd4.pdf) 下载附件 [1_kernel_mailbox_basic.zip](https://oss-club.rt-thread.org/uploads/3089_da0872d13e9db6753f63f92ddeb064dd.zip)
查看更多
3
个回答
默认排序
按发布时间排序
bloom5
2012-09-05
这家伙很懒,什么也没写!
添加例程 [attach]1280[/attach]
nongxiaoming
2012-09-10
rt-thread大师兄
不错啊,学习了~呵呵,手上正好有F407+RA8875的板子,跟着学习了~
撰写答案
登录
注册新账号
关注者
0
被浏览
5.6k
关于作者
shaolin
这家伙很懒,什么也没写!
提问
115
回答
444
被采纳
0
关注TA
发私信
相关问题
1
[项目]搞个开源的硬件项目
2
硬件计划贴,及时更新,欢迎提意见
3
软件计划贴,及时更新,欢迎提意见::WMA,MOUNT,LWIP等问题急需解决.
4
MMS协议
5
定点的wma解压库-libwma
6
QQ群记录 [20090821]
7
STM32网络收音机PCB报名征集
8
第一版调试记录
9
第二版硬件讨论
10
RADIO项目相关模块规格--欢迎大家自己做板时规格与此兼容,减少重复劳动
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
ulog 日志 LOG_HEX 输出时间改为本地日期时间
2
在RT-Thread Studio中构建前执行python命令
3
研究一了一段时间RTT,直接标准版上手太难,想用nano,但又舍不得组件
4
CherryUSB开发笔记(一):FSDEV USB IP核的 HID Remote WakeUp (USB HID 远程唤醒) 2025-01-18 V1.1
5
RT-thread 缩写字典
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
1
个答案
2
次被采纳
用户名由3_15位
7
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
xusiwei1236
4
个答案
1
次被采纳
张世争
1
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
15
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
2
次点赞
Ghost_Girls
1
篇文章
6
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部