文章主要讲解如何创建和使用队列。
消息队列浅析:
一个或者多个任务可以通过 RTOS 内核服务从队列中得到消息,通常先进入消息队列的消息先传
给任务,即先进先出的原则(FIFO),FreeRTOS 的消息队列支持 FIFO 和 LIFO 两种数据存取方式。
相比消息队列,使用全局数组主要有如下四个问题:
a、使用消息队列可以让 RTOS 内核有效地管理任务,而全局数组是无法做到的,任务的超时等机制需要用户自己去实现
b、使用全局数组需要防止多任务的访问冲突,而使用消息队列则处理好了这个问题,用户无需担心
c、使用消息队列可以有效地解决中断服务程序与任务之间消息传递的问题
d、FIFO 机制更有利于数据的处理
任务间消息队列
该消息队列可以存放 10 个消息:
创建 2 个任务 Task1 和 Task2,任务 Task1 向消息队列放数据,任务 Task2 从消息队列取数据。
FreeRTOS 的消息存取采用 FIFO 方式,运行过程主要有以下两种情况:
a、放数据的速度快于取数据的速度
会出现消息队列存放满的情况,FreeRTOS 的消息存放函数 xQueueSend 支持超时等待,用户可以设置超时等待,直到有空间可以存放消息或者设置的超时时间溢出。
b、放数据的速度慢于取数据的速度
会出现消息队列为空的情况,FreeRTOS 的消息获取函数 xQueueReceive 支持超时等待,用户可以设置超时等待,直到消息队列中有消息或者设置的超时时间溢出。
中断方式消息队列
该消息队列可以存放 10 个消息:
创建任务 Task1 和一个串口接收中断,运行过程主要有以下两种情况:
a、中断服务程序向消息队列放数据,任务 Task1 从消息队列取数据,如果放数据的速度快于取数据的速度,那么会出现消息队列存放满的情况。
由于中断服务程序里面的消息队列发送函数 xQueueSendFromISR 不支持超时设置,所以发送前要通过函数 xQueueIsQueueFullFromISR 检测消息队列是否满。
b、中断服务程序向消息队列放数据,任务 Task1 从消息队列取数据,如果放数据的速度慢于取数据的速度,那么会出现消息队列存为空的情况。
在 FreeRTOS 的任务中可以通过函数 xQueueReceive 获取消息,因为此函数可以设置超时等待,直到消息队列中有消息存放或者设置的超时时间溢出。
实际应用中,中断方式的消息机制要注意以下几个问题:
a、中断函数的执行时间越短越好,防止其它低于这个中断优先级的异常不能得到及时响应;
b、实际应用中,建议不要在中断中实现消息处理,用户可以在中断服务程序里面发送消息通知任务,在任务中实现消息处理,这样可以有效地保证中断服务程序的实时响应。同时此任务也需要设置为高优
先级,以便退出中断函数后任务可以得到及时执行;
c、中断服务程序中一定要调用专用于中断的消息队列函数,即以 FromISR 结尾的函数。
1、头文件定义和任务启动
include "FreeRTOS.h"
include "task.h"
include "queue.h"
include "supporting_functions.h"
// 定义队列数据收发任务函数
static void vSenderTask( void *pvParameters );
static void vReceiverTask( void *pvParameters );
// 定义队列变量
QueueHandle_t xQueue;
int main( void )
{
// 创建队列
xQueue = xQueueCreate( 5, sizeof( int32_t ) );
if( xQueue != NULL )
{
xTaskCreate( vSenderTask, "Sender1", 1000, ( void * ) 100, 1, NULL );
xTaskCreate( vSenderTask, "Sender2", 1000, ( void * ) 200, 1, NULL );
xTaskCreate( vReceiverTask, "Receiver", 1000, NULL, 2, NULL );
vTaskStartScheduler();
}
for( ;; );
return 0;
}
2、队列数据发送任务
static void vSenderTask( void *pvParameters )
{
int32_t lValueToSend;
BaseType_t xStatus;
lValueToSend = ( int32_t ) pvParameters;
for( ;; )
{
// 参数1:队列
// 参数2:发送的数据地址
// 参数3:block 时间
xStatus = xQueueSendToBack( xQueue, &lValueToSend, 0 );
if( xStatus != pdPASS )
{
vPrintString( "Could not send to the queue.\r\n" );
}
}
}
3、队列数据接收任务
static void vReceiverTask( void *pvParameters )
{
int32_t lReceivedValue;
BaseType_t xStatus;
const TickType_t xTicksToWait = pdMS_TO_TICKS( 100UL );
for( ;; )
{
if( uxQueueMessagesWaiting( xQueue ) != 0 )
{
vPrintString( "Queue should have been empty!\r\n" );
}
// 参数1:队列
// 参数2:接收数据地址
// 参数3:block 时间
xStatus = xQueueReceive( xQueue, &lReceivedValue, xTicksToWait );
if( xStatus == pdPASS )
{
vPrintStringAndNumber( "Received = ", lReceivedValue );
}
else
{
vPrintString( "Could not receive from the queue.\r\n" );
}
}
}
从《天道》的角度谈谈产品规划
原创2023-02-24 21:05·产品人卫朋
今天主要借用《天道》中丁元英的商业案例来谈谈产品规划这个话题。
《天道》这部被众人追捧的影视剧来源于豆豆的成名作《遥远的救世主》。
如果没有全局做过产品或者市场的规划,而且是初次接触这部剧。
你就会惊叹于主人公的组局、布局,以及成局的能力。
从互联网拥簇的评论声中,也可见一斑。
剧中的丁元英甚至都有一种被神化的趋势。
而随着个人知识和阅历的增加,再加上每年也都要做产品规划。
也逐渐对这部剧或者这本书有了一些新的认识。
究其本质,这是一种战略性的思维,也是一种规划的能力。
更是一种市场与内部能力的匹配过程。
笔者之前也分享过这块的内容,也看到了一些质疑。
怎么能用虚拟的案例做讲解呢?
其实这么做的原因主要有两点考虑:
首先,这部剧中的商业案例的整体逻辑是自洽的,而且也符合当时的商业环境。
其次,整部剧将整个商业案例完整地呈现了出来,也包括其中很多的决策细节。
这就要比分析现实案例直观得多,也更加有指导意义。
再回到产品规划这个话题上来。
产品规划从本质上来说是一种推演能力,也就是根据第一性原则推演产品从0到1、从1到100的一个过程。
如果说一款产品是一个点的话,那产品规划便是通过构造一种系统能力以达成企业最终的商业目的。
第一性原理是埃隆·马斯克非常推崇的一种思维模型。
通常来说,企业愿景对应的便是企业的第一性原则。
围绕第一性原则可以激发资源优势、制定细分市场目标,最终实现企业目标。
下面以影视剧中丁元英操盘的格律诗音响项目为例,谈谈产品规划。
格律诗音响公司的企业愿景是实现王庙村生产力和市场的对接,最终实现农户脱贫。
这是企业的愿景,同时也是丁元英承诺要给红颜知己芮小丹创造的神话。
启动一个项目或产品,资源和人力配置是你首先要考虑的。
企业在不同的发展周期,对人的要求是有很大差异的。
丁元英在分析完这些人的本质之后,并没有把自己的全套计划完整地告诉原始这些人。
而是通过市场的变化来淘汰掉一部分人。
因为这部分人现在不淘汰掉,在以后的市场变化中,可能会给公司带来毁灭性的灾难。
下面就先梳理一下其中的关键人物:
丁元英作为格律诗音响项目的唯一操盘手,全局规划了整个项目。
他的优势是自己在欧洲的人脉和战略规划能力,以及在欧阳雪等人心中的影响力。
同时,作为发烧级音乐玩家,他对音箱的独特见解也为他们打造差异化的产品起到了关键助力作用。
差异化的意思是相比于竞争对手,你的独特优势或者护城河,没有这个前提,整个策略也就无从谈起,这为他们赢得了时间上的先机。
在音响这个市场,竞品已经很成功了,而且他们提供的价值点已经被用户接受。
如果按照他们的价值点去做产品,你就永远只能跟在他们身后。
这时候就需要找一个跟他们不一样的价值点,做差异化。
欧阳雪这个人呢,做事很踏实,很讲义气,不贪心。优势是人脉、资金和社会地位。
这个人的价值在于她对格律诗的绝对控股,这样就可以确保关键决策权的归属。
由于每个人的认知水平的限制,很多时候不同个体看到的终局是有极大差异的,这个时候你就需要考虑如何增加成事的确定性。
如果开公司的话,股权的分配问题是你优先要考虑的。
不赚钱的时候,大家还都能力出一孔。一旦公司有起色,每个人就开始有自己的诉求,不确定性也就随之而来。
肖亚文见过世面,知道公司怎么运行,知道商务谈判和商务合作的事情,是很精明的职场人物。
而冯世杰和叶晓明想成就一番事业,但没有机会,能够脚踏实地的做事情,但眼光欠缺。刘冰是小人物,唯利是图,关键时刻不能顶上,迟早会被淘汰。
叶晓明,冯世杰,刘冰这三个人的优势就是懂音乐,会组装,可以作为高级技术工。
同时,这三人和王庙村农民有一定的关系,可以作为连接的纽带,核心竞争力是技术和人脉。
乐圣公司的掌舵人是林雨峰(竞争对手),但太过刚硬,只知道进攻,不懂防守,考虑问题存在漏洞。
这就有点类似竞争分析了,通过分析竞争对手的漏洞,找到破局点,制定商业竞争策略。
接下来就需要统一思想了:
想要以小博大,达成乐圣跟王庙村合作的目的,就必须把优势发挥到最大效果。
这才有几次股东开会,召集农民兄弟一起开会等,就是为了统一思想。
市场的生存竞争非常残酷,胜负往往就在毫厘之间,微弱的优势都可能成为关键一环,你比他多一口气,你就是赢家。
最后,丁元英就把这些人的优势资源整合起来,按照需要组建公司,精心规划。
详细案例分析可以参阅笔者之前的文章。
卫朋
人人都是产品经理受邀专栏作家,CSDN 嵌入式领域新星创作者、资深技术博主。2020 年 8 月开始写产品相关内容,截至目前,人人都是产品经理单渠道阅读 56 万+,鸟哥笔记单渠道阅读200 万+,CSDN 单渠道阅读 210 万+,51CTO单渠道阅读 180 万+。
卫朋入围2021/2022年人人都是产品经理平台年度作者,光环国际学习社区首批原创者、知识合作伙伴,商业新知 2021 年度产品十佳创作者,腾讯调研云2022年达人榜第三名。
文章被人人都是产品经理、CSDN、华为云、运营派、产品壹佰、鸟哥笔记、光环国际、商业新知、腾讯调研云等头部垂直类媒体转载。文章见仁见智,各位看官可策略性选择对于自己有用的部分。