做招投标有哪些网站,crm软件免费,网站界面设计案例,谷歌关键词搜索排名队列(queue)可以用于任务到任务、 任务到中断、 中断到任务直接传输信息。
1、队列的特性
1、1常规操作
队列的简化操如下图所示#xff0c;从此图可知#xff1a;
队列中可以包含若干数据#xff1a;队列中有若干项#xff0c;这…
队列(queue)可以用于任务到任务、 任务到中断、 中断到任务直接传输信息。
1、队列的特性
1、1常规操作
队列的简化操如下图所示从此图可知
队列中可以包含若干数据队列中有若干项这被称为“长度”每个数据大小固定创建队列时就要指定长度、数据大小数据的操作采用先进先出的方法写数据时放入尾部读数据时从头部读也可以强制写队列头部覆盖头部数据。 1、2 数据传输的两种方式
使用队列传输数据时有两种方法
拷贝把数据、变量的值复制进队列里
引用把数据、变量的地址复制进队列里。 FreeRTOS 使用拷贝值的方法这更简单 ⚫ 局部变量的值可以发送到队列中后续即使函数退出、局部变量被回收也不会影响队列中的数据 ⚫ 无需分配 buffer 来保存数据队列中有 buffer ⚫ 局部变量可以马上再次使用 ⚫ 发送任务、接收任务解耦接收任务不需要知道这数据是谁的、也不需要发送任务来释放数据 ⚫ 如果数据实在太大你还是可以使用队列传输它的地址 ⚫ 队列的空间有 FreeRTOS 内核分配无需任务操心 ⚫ 对于有内存保护功能的系统如果队列使用引用方法也就是使用地址必须确保双方任务对这个地址都有访问权限。使用拷贝方法时则无此限制内核有足够的权限把数据复制进队列、再把数据复制出队列。
1、3队列的阻塞访问 只要知道队列的句柄谁都可以读、写该队列。任务、 ISR 都可读、写队列。可以多个任务读写队列。 任务读写队列时简单地说如果读写不成功则阻塞可以指定超时时间。口语化地说就是可以定个闹钟如果能读写了就马上进入就绪态否则就阻塞直到超时。 某个任务读队列时如果队列没有数据则该任务可以进入阻塞状态还可以指定阻塞的时间。如果队列有数据了则该阻塞的任务会变为就绪态。如果一直都没有数据则时间到之后它也会进入就绪态。 既然读取队列的任务个数没有限制那么当多个任务读取空队列时这些任务都会进入阻塞状态有多个任务在等待同一个队列的数据。当队列中有数据时哪个任务会进入就绪态 ⚫ 优先级最高的任务 ⚫ 如果大家的优先级相同那等待时间最久的任务会进入就绪态 跟读队列类似一个任务要写队列时如果队列满了该任务也可以进入阻塞状态还可以指定阻塞的时间。如果队列有空间了则该阻塞的任务会变为就绪态。如果一直都没有空间则时间到之后它也会进入就绪态。既然写队列的任务个数没有限制那么当多个任务写满队列时这些任务都会进入阻塞状态有多个任务在等待同一个队列的空间。当队列中有空间时哪个任务会进入就绪态 ⚫ 优先级最高的任务 ⚫ 如果大家的优先级相同那等待时间最久的任务会进入就绪态 2、队列函数
使用队列的流程创建队列、写队列、读队列、删除队列。
2.1创建
队列的创建有两种方法动态分配内存、静态分配内存
1、动态分配内存 xQueueCreate队列的内存在函数内部动态分配
QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize ); 2、静态分配内存 xQueueCreateStatic队列的内存要事先分配好 函数原型如下
QueueHandle_t xQueueCreateStatic(UBaseType_t uxQueueLength,UBaseType_t uxItemSize,uint8_t *pucQueueStorageBuffer,StaticQueue_t *pxQueueBuffer
) 示例代码
// 示例代码
#define QUEUE_LENGTH 10
#define ITEM_SIZE sizeof( uint32_t )// xQueueBuffer 用来保存队列结构体
StaticQueue_t xQueueBuffer;// ucQueueStorage 用来保存队列的数据
// 大小为 队列长度 * 数据大小
uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];void vATask( void *pvParameters )
{QueueHandle_t xQueue1;// 创建队列: 可以容纳 QUEUE_LENGTH 个数据每个数据大小是 ITEM_SIZExQueue1 xQueueCreateStatic( QUEUE_LENGTH,ITEM_SIZE,ucQueueStorage,xQueueBuffer );
}
2.2 复位 队列刚被创建时里面没有数据使用过程中可以调用 xQueueReset()把队列恢复为初始状态此函数原型为
/* pxQueue : 复位哪个队列;
* 返回值: pdPASS(必定成功)
*/
BaseType_t xQueueReset( QueueHandle_t pxQueue);
2.3删除 删除队列的函数为 vQueueDelete()只能删除使用动态方法创建的队列它会释放内存。 原型如下
void vQueueDelete( QueueHandle_t xQueue );
2.4写队列 可以把数据写到队列头部也可以写到尾部这些函数有两个版本在任务中使用、在ISR 中使用。函数原型如下
/* 等同于xQueueSendToBack
* 往队列尾部写入数据如果没有空间阻塞时间为xTicksToWait
*/
BaseType_t xQueueSend(
QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait
);/*
* 往队列尾部写入数据如果没有空间阻塞时间为xTicksToWait
*/
BaseType_t xQueueSendToBack(
QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait
);/*
* 往队列尾部写入数据此函数可以在中断函数中使用不可阻塞
*/
BaseType_t xQueueSendToBackFromISR(
QueueHandle_t xQueue,
const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
);/*
* 往队列头部写入数据如果没有空间阻塞时间为xTicksToWait
*/
BaseType_t xQueueSendToFront(
QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait
);/*
* 往队列头部写入数据此函数可以在中断函数中使用不可阻塞
*/
BaseType_t xQueueSendToFrontFromISR(
QueueHandle_t xQueue,
const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
); 2.5读队列 使用 xQueueReceive()函数读队列读到一个数据后队列中该数据会被移除。这个 函数有两个版本在任务中使用、在 ISR 中使用。函数原型如下
BaseType_t xQueueReceive( QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait );BaseType_t xQueueReceiveFromISR(
QueueHandle_t xQueue,
void *pvBuffer,
BaseType_t *pxTaskWoken
); 2.6查询
可以查询队列中有多少个数据、有多少空余空间。函数原型如下
/*
* 返回队列中可用数据的个数
*/
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
/*
* 返回队列中可用空间的个数
*/
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
2.7覆盖 or偷看
当队列长度为 1 时可以使用 xQueueOverwrite()或 xQueueOverwriteFromISR() 来覆盖数据。 注意队列长度必须为 1。当队列满时这些函数会覆盖里面的数据这也以为着这 些函数不会被阻塞
/* 覆盖队列
* xQueue: 写哪个队列
* pvItemToQueue: 数据地址
* 返回值: pdTRUE表示成功, pdFALSE表示失败
*/
BaseType_t xQueueOverwrite(
QueueHandle_t xQueue,
const void * pvItemToQueue
);
BaseType_t xQueueOverwriteFromISR(
QueueHandle_t xQueue,
const void * pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
);
如果想让队列中的数据供多方读取也就是说读取时不要移除数据要留给后来人。那 么可以使用窥视也就是xQueuePeek()或xQueuePeekFromISR()。这些函数会从队列中 复制出数据但是不移除数据。这也意味着如果队列中没有数据那么偷看时会导致阻 塞一旦队列中有数据以后每次偷看都会成功。
/* 偷看队列
* xQueue: 偷看哪个队列
* pvItemToQueue: 数据地址, 用来保存复制出来的数据
* xTicksToWait: 没有数据的话阻塞一会
* 返回值: pdTRUE表示成功, pdFALSE表示失败
*/
BaseType_t xQueuePeek(
QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait
);
BaseType_t xQueuePeekFromISR(
QueueHandle_t xQueue,
void *pvBuffer,
);
3、传输大数据
FreeRTOS的队列使用拷贝传输也就是要传输uint32_t时把4字节的数据拷贝进队列 要传输一个8字节的结构体时把8字节的数据拷贝进队列。 如果要传输1000字节的结构体呢写队列时拷贝1000字节读队列时再拷贝1000字节 不建议这么做影响效率 这时候我们要传输的是这个巨大结构体的地址把它的地址写入队列对方从队列得 到这个地址使用地址去访问那1000字节的数据。 使用地址来间接传输数据时这些数据放在RAM里对于这块RAM要保证这几点 ⚫ RAM 的所有者、操作者必须清晰明了 这块内存就被称为共享内存。要确保不能同时修改 RAM。比如在写队列之 前只有由发送者修改这块 RAM在读队列之后只能由接收者访问这块 RAM。 ⚫ RAM 要保持可用 这块 RAM 应该是全局变量或者是动态分配的内存。对于动然分配的内存要 确保它不能提前释放要等到接收者用完后再释放。 另外不能是局部变量。
实例
程序会创建一个队列然后创建1个发送任务、 1个接收任务 ⚫ 创建的队列长度为 1用来传输char *指针 ⚫ 发送任务优先级为 1在字符数组中写好数据后把它的地址写入队列 ⚫ 接收任务优先级为 2读队列得到char *值把它打印出来 这个程序故意设置接收任务的优先级更高在它访问数组的过程中接收任务无法执行、无法写这个数组。
main函数中创建了队列、创建了发送任务、接收任务代码如下
/* 定义一个字符数组 */
static char pcBuffer[100];
/* vSenderTask被用来创建2个任务用于写队列
* vReceiverTask被用来创建1个任务用于读队列
*/
static void vSenderTask( void *pvParameters );
static void vReceiverTask( void *pvParameters );
/*-----------------------------------------------------------*/
/* 队列句柄, 创建队列时会设置这个变量 */
QueueHandle_t xQueue;
int main( void )
{
prvSetupHardware();
/* 创建队列: 长度为1数据大小为4字节(存放一个char指针) */
xQueue xQueueCreate( 1, sizeof(char *) );
if( xQueue ! NULL )
{
/* 创建1个任务用于写队列
* 任务函数会连续执行构造buffer数据把buffer地址写入队列
* 优先级为1
*/
xTaskCreate( vSenderTask, Sender, 1000, NULL, 1, NULL );
/* 创建1个任务用于读队列
* 优先级为2, 高于上面的两个任务
* 这意味着读队列得到buffer地址后本任务使用buffer时不会被打断
*/
xTaskCreate( vReceiverTask, Receiver, 1000, NULL, 2, NULL );
/* 启动调度器 */
vTaskStartScheduler();
}
else
{
/* 无法创建队列 */
}
/* 如果程序运行到了这里就表示出错了, 一般是内存不足 */
return 0;
}
发送任务的函数中现在全局大数组pcBuffer中构造数据然后把它的地址写入队列 代码如下
static void vSenderTask( void *pvParameters )
{BaseType_t xStatus;static int cnt 0;char *buffer;/* 无限循环 */for( ;; ){sprintf(pcBuffer, www.100ask.net Msg %d\r\n, cnt);buffer pcBuffer; // buffer变量等于数组的地址, 下面要把这个地址写入队列/* 写队列* xQueue: 写哪个队列* pvParameters: 写什么数据? 传入数据的地址, 会从这个地址把数据复制进队列* 0: 如果队列满的话, 即刻返回*/xStatus xQueueSendToBack( xQueue, buffer, 0 ); /* 只需要写入4字节, 无需写入整个buffer */if( xStatus ! pdPASS ){printf( Could not send to the queue.\r\n );}}
}
接收任务的函数中读取队列、得到buffer的地址、打印代码如下
static void vReceiverTask( void *pvParameters )
{/* 读取队列时, 用这个变量来存放数据 */char *buffer;const TickType_t xTicksToWait pdMS_TO_TICKS( 100UL );BaseType_t xStatus;/* 无限循环 */for( ;; ){/* 读队列* xQueue: 读哪个队列* xReceivedStructure: 读到的数据复制到这个地址* xTicksToWait: 没有数据就阻塞一会*/xStatus xQueueReceive( xQueue, buffer, xTicksToWait); /* 得到buffer地址只是4字节 */if( xStatus pdPASS ){/* 读到了数据 */printf(Get: %s, buffer);}else{/* 没读到数据 */printf( Could not receive from the queue.\r\n );}}
} 文章转载自: http://www.morning.lwcgh.cn.gov.cn.lwcgh.cn http://www.morning.cyfsl.cn.gov.cn.cyfsl.cn http://www.morning.rmlz.cn.gov.cn.rmlz.cn http://www.morning.ncrk.cn.gov.cn.ncrk.cn http://www.morning.ykmkz.cn.gov.cn.ykmkz.cn http://www.morning.xcbnc.cn.gov.cn.xcbnc.cn http://www.morning.nylbb.cn.gov.cn.nylbb.cn http://www.morning.sjbty.cn.gov.cn.sjbty.cn http://www.morning.zqmdn.cn.gov.cn.zqmdn.cn http://www.morning.qnzk.cn.gov.cn.qnzk.cn http://www.morning.trhlb.cn.gov.cn.trhlb.cn http://www.morning.tnjff.cn.gov.cn.tnjff.cn http://www.morning.yhwyh.cn.gov.cn.yhwyh.cn http://www.morning.rjrnx.cn.gov.cn.rjrnx.cn http://www.morning.fpbj.cn.gov.cn.fpbj.cn http://www.morning.lpqgq.cn.gov.cn.lpqgq.cn http://www.morning.trjr.cn.gov.cn.trjr.cn http://www.morning.lbpfl.cn.gov.cn.lbpfl.cn http://www.morning.prznc.cn.gov.cn.prznc.cn http://www.morning.rnhh.cn.gov.cn.rnhh.cn http://www.morning.rhzzf.cn.gov.cn.rhzzf.cn http://www.morning.bnpn.cn.gov.cn.bnpn.cn http://www.morning.dqcpm.cn.gov.cn.dqcpm.cn http://www.morning.bhdyr.cn.gov.cn.bhdyr.cn http://www.morning.tlrxp.cn.gov.cn.tlrxp.cn http://www.morning.yskhj.cn.gov.cn.yskhj.cn http://www.morning.cwtrl.cn.gov.cn.cwtrl.cn http://www.morning.ptqbt.cn.gov.cn.ptqbt.cn http://www.morning.rlbg.cn.gov.cn.rlbg.cn http://www.morning.gxcit.com.gov.cn.gxcit.com http://www.morning.kpwdt.cn.gov.cn.kpwdt.cn http://www.morning.ghcfx.cn.gov.cn.ghcfx.cn http://www.morning.ie-comm.com.gov.cn.ie-comm.com http://www.morning.wdhzk.cn.gov.cn.wdhzk.cn http://www.morning.nrll.cn.gov.cn.nrll.cn http://www.morning.jbmbj.cn.gov.cn.jbmbj.cn http://www.morning.xbbrh.cn.gov.cn.xbbrh.cn http://www.morning.tfwr.cn.gov.cn.tfwr.cn http://www.morning.tgqzp.cn.gov.cn.tgqzp.cn http://www.morning.zlqyj.cn.gov.cn.zlqyj.cn http://www.morning.mpngp.cn.gov.cn.mpngp.cn http://www.morning.xqgtd.cn.gov.cn.xqgtd.cn http://www.morning.czgfn.cn.gov.cn.czgfn.cn http://www.morning.xnltz.cn.gov.cn.xnltz.cn http://www.morning.ykxnp.cn.gov.cn.ykxnp.cn http://www.morning.jppb.cn.gov.cn.jppb.cn http://www.morning.fmrwl.cn.gov.cn.fmrwl.cn http://www.morning.rfxg.cn.gov.cn.rfxg.cn http://www.morning.c7510.cn.gov.cn.c7510.cn http://www.morning.rfdqr.cn.gov.cn.rfdqr.cn http://www.morning.pbbzn.cn.gov.cn.pbbzn.cn http://www.morning.xdqrz.cn.gov.cn.xdqrz.cn http://www.morning.grbgn.cn.gov.cn.grbgn.cn http://www.morning.trsdm.cn.gov.cn.trsdm.cn http://www.morning.hwlmy.cn.gov.cn.hwlmy.cn http://www.morning.sbpt.cn.gov.cn.sbpt.cn http://www.morning.cnqdn.cn.gov.cn.cnqdn.cn http://www.morning.jfxdy.cn.gov.cn.jfxdy.cn http://www.morning.cfjyr.cn.gov.cn.cfjyr.cn http://www.morning.tjkth.cn.gov.cn.tjkth.cn http://www.morning.hhpbj.cn.gov.cn.hhpbj.cn http://www.morning.xnlj.cn.gov.cn.xnlj.cn http://www.morning.qcygd.cn.gov.cn.qcygd.cn http://www.morning.gzxnj.cn.gov.cn.gzxnj.cn http://www.morning.ntkpc.cn.gov.cn.ntkpc.cn http://www.morning.qlsyf.cn.gov.cn.qlsyf.cn http://www.morning.kxscs.cn.gov.cn.kxscs.cn http://www.morning.znqmh.cn.gov.cn.znqmh.cn http://www.morning.lhrcr.cn.gov.cn.lhrcr.cn http://www.morning.wtcbl.cn.gov.cn.wtcbl.cn http://www.morning.jrhmh.cn.gov.cn.jrhmh.cn http://www.morning.kdnrp.cn.gov.cn.kdnrp.cn http://www.morning.ftsmg.com.gov.cn.ftsmg.com http://www.morning.qrlsy.cn.gov.cn.qrlsy.cn http://www.morning.fqklt.cn.gov.cn.fqklt.cn http://www.morning.lpnpn.cn.gov.cn.lpnpn.cn http://www.morning.ygrkg.cn.gov.cn.ygrkg.cn http://www.morning.qkqgj.cn.gov.cn.qkqgj.cn http://www.morning.ghwtn.cn.gov.cn.ghwtn.cn http://www.morning.kjrlp.cn.gov.cn.kjrlp.cn