1、线程通信
邮箱
消息队列
信号
2、线程同步
2.1 信号量
rt_sem_creat
rt_sem_release: value=0, 有其它线程等待,让其它线程获取
否则,信号量加1
rt_sem_take: value>0, 线程获取信号量,信号量减1
value=0,1)等待永久;2)返回挂起,直到其它线程或中断释放信号量;3)超时,返回timeout
2.2 互斥量
2.3 事件集
rt_event_init
rt_event_send
rt_event_recv
rt_event_detach
3、example
邮箱与信号量的结合使用:
static struct rt_mailbox eth_tx_thread_mb;
static struct rt_thread eth_tx_thread;
static char eth_tx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
static char eth_tx_thread_stack[RT_LWIP_ETHTHRE
初始化邮箱:
/* initialize Tx thread /
/ initialize mailbox and create Ethernet Tx thread */
result = rt_mb_init(ð_tx_thread_mb, “etxmb”,ð_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/4,RT_IPC_FLAG_FIFO);
RT_ASSERT(result == RT_EOK);
result = rt_thread_init(ð_tx_thread, "etx", eth_tx_thread_entry, RT_NULL,ð_tx_thread_stack[0],
sizeof(eth_tx_thread_stack),RT_ETHERNETIF_THREAD_PREORITY, 16);
发送邮件:等待信号量
struct eth_tx_msg msg;
struct eth_device* enetif;
RT_ASSERT(netif != RT_NULL);
printf("11111\r\n");
enetif = (struct eth_device*)netif->state;
/* send a message to eth tx thread /
printf(“2222\r\n”);
msg.netif = netif;
printf(“33333\r\n”);
msg.buf = p;
printf(“4444\r\n”);
if (rt_mb_send(ð_tx_thread_mb, (rt_uint32_t) &msg) == RT_EOK)
{
printf(“55555\r\n”);
/ waiting for ack */
rt_sem_take(&(enetif->tx_ack), RT_WAITING_FOREVER);
}
接收邮件:释放信号量
struct eth_tx_msg* msg;
while (1)
{
if (rt_mb_recv(ð_tx_thread_mb, (rt_ubase_t )&msg, RT_WAITING_FOREVER) == RT_EOK)
{
struct eth_device enetif;
RT_ASSERT(msg->netif != RT_NULL);
RT_ASSERT(msg->buf != RT_NULL);
printf("5555\r\n");
enetif = (struct eth_device*)msg->netif->state;
printf("66666\r\n");
if (enetif != RT_NULL)
{
/* call driver's interface */
printf("77777\r\n");
if (enetif->eth_tx(&(enetif->parent), msg->buf) != RT_EOK)
}
/* send ACK */
rt_sem_release(&(enetif->tx_ack));
}
}
4、线程状态切换
tips:
1)线程不能陷入死循环操作,必须要有让出cpu使用权的动作(延时函数、主动挂起);
2)设计无限循环的目的,是为了让这个线程一直被系统循环调度运行,永不删除;
3)无循环,一次性线程,执行完毕后,系统自动删除;
5、线程退出
可能1:系统挂死
可能2:退出while
可能3:没有任务