mirror of
https://github.com/google/pebble.git
synced 2025-03-21 03:11:21 +00:00
127 lines
3.8 KiB
C
127 lines
3.8 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "fake_queue.h"
|
|
|
|
#include "util/circular_buffer.h"
|
|
|
|
#include "FreeRTOS.h"
|
|
#include "queue.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
typedef struct {
|
|
uint16_t item_size;
|
|
bool is_semph;
|
|
|
|
//! @return ticks spent executing the callback
|
|
TickType_t (*yield_cb)(QueueHandle_t);
|
|
CircularBuffer circular_buffer;
|
|
uint8_t storage[];
|
|
} FakeQueue;
|
|
|
|
signed portBASE_TYPE xQueueGenericReceive(QueueHandle_t xQueue, void * const pvBuffer,
|
|
TickType_t xTicksToWait, portBASE_TYPE xJustPeeking) {
|
|
FakeQueue *q = (FakeQueue *) xQueue;
|
|
TickType_t ticks_waited = 0;
|
|
while (true) {
|
|
uint16_t read_space = circular_buffer_get_read_space_remaining(&q->circular_buffer);
|
|
if (read_space >= q->item_size) {
|
|
circular_buffer_consume(&q->circular_buffer, q->item_size);
|
|
return pdTRUE;
|
|
} else {
|
|
if (!xTicksToWait || !q->yield_cb) {
|
|
return pdFALSE;
|
|
} else {
|
|
ticks_waited += q->yield_cb(xQueue);
|
|
if (ticks_waited >= xTicksToWait) {
|
|
return pdFALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
signed portBASE_TYPE xQueueGenericSend(QueueHandle_t xQueue, const void * const pvItemToQueue,
|
|
TickType_t xTicksToWait, portBASE_TYPE xCopyPosition) {
|
|
FakeQueue *q = (FakeQueue *) xQueue;
|
|
TickType_t ticks_waited = 0;
|
|
while (true) {
|
|
uint16_t write_space = circular_buffer_get_write_space_remaining(&q->circular_buffer);
|
|
if (write_space >= q->item_size) {
|
|
// Just write a zero for a semaphore
|
|
const uint8_t semph_data = 0;
|
|
const uint8_t *data = q->is_semph ? &semph_data : (const uint8_t *) pvItemToQueue;
|
|
circular_buffer_write(&q->circular_buffer, data, q->item_size);
|
|
return pdTRUE;
|
|
} else {
|
|
if (!xTicksToWait || !q->yield_cb) {
|
|
return pdFALSE;
|
|
} else {
|
|
ticks_waited += q->yield_cb(xQueue);
|
|
if (ticks_waited >= xTicksToWait) {
|
|
return pdFALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
QueueHandle_t xQueueGenericCreate(unsigned portBASE_TYPE uxQueueLength,
|
|
unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType) {
|
|
uint16_t item_size;
|
|
const bool is_semph = (ucQueueType == queueQUEUE_TYPE_BINARY_SEMAPHORE);
|
|
if (is_semph) {
|
|
item_size = 1;
|
|
} else {
|
|
item_size = uxItemSize;
|
|
}
|
|
const uint16_t storage_size = (item_size * uxQueueLength);
|
|
uint8_t *buffer = malloc(sizeof(FakeQueue) + storage_size);
|
|
FakeQueue *q = (FakeQueue *) buffer;
|
|
*q = (const FakeQueue) {
|
|
.item_size = item_size,
|
|
.is_semph = is_semph,
|
|
};
|
|
circular_buffer_init(&q->circular_buffer, q->storage, storage_size);
|
|
return q;
|
|
}
|
|
|
|
void vQueueDelete(QueueHandle_t xQueue) {
|
|
free(xQueue);
|
|
}
|
|
|
|
QueueHandle_t xQueueCreateMutex(unsigned char ucQueueType) {
|
|
return (QueueHandle_t)1;
|
|
}
|
|
|
|
portBASE_TYPE xQueueTakeMutexRecursive(QueueHandle_t pxMutex, TickType_t xBlockTime) {
|
|
return pdTRUE;
|
|
}
|
|
|
|
portBASE_TYPE xQueueGiveMutexRecursive(QueueHandle_t xMutex) {
|
|
return pdTRUE;
|
|
}
|
|
|
|
BaseType_t xQueueGenericReset(QueueHandle_t xQueue, BaseType_t xNewQueue) {
|
|
return pdTRUE;
|
|
}
|
|
|
|
void fake_queue_set_yield_callback(QueueHandle_t queue,
|
|
TickType_t (*yield_cb)(QueueHandle_t)) {
|
|
FakeQueue *fake_queue = (FakeQueue *) queue;
|
|
fake_queue->yield_cb = yield_cb;
|
|
}
|