Working version
This commit is contained in:
parent
f28aba370b
commit
394794cce0
@ -13,13 +13,25 @@ add_executable(card-os
|
|||||||
src/card-os.c
|
src/card-os.c
|
||||||
src/usb_descriptors.c
|
src/usb_descriptors.c
|
||||||
src/display.c
|
src/display.c
|
||||||
|
src/ring-buffer.c
|
||||||
)
|
)
|
||||||
target_include_directories(card-os PRIVATE include)
|
target_include_directories(card-os PRIVATE include)
|
||||||
target_link_libraries(card-os PRIVATE pico_stdlib tinyusb_device tinyusb_board pico_unique_id hardware_clocks hardware_spi)
|
target_link_libraries(card-os PRIVATE pico_stdlib tinyusb_device tinyusb_board pico_unique_id hardware_clocks hardware_spi pico_multicore)
|
||||||
pico_set_linker_script(card-os ${CMAKE_CURRENT_SOURCE_DIR}/src/card-os-link.ld)
|
pico_set_linker_script(card-os ${CMAKE_CURRENT_SOURCE_DIR}/src/card-os-link.ld)
|
||||||
pico_add_extra_outputs(card-os)
|
pico_add_extra_outputs(card-os)
|
||||||
|
|
||||||
add_library(card-os-user
|
add_library(card-os-user STATIC
|
||||||
src/card-os-user.c
|
src/card-os-user.c
|
||||||
)
|
)
|
||||||
target_include_directories(card-os-user PUBLIC include/user)
|
target_include_directories(card-os-user PUBLIC include/user)
|
||||||
|
target_link_options(card-os-user PUBLIC -Wl,--script=${CMAKE_CURRENT_SOURCE_DIR}/src/card-os-link-user.ld -nostartfiles)
|
||||||
|
|
||||||
|
function(card_os_finalize_user_program TARGET_NAME)
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${TARGET_NAME} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${TARGET_NAME}> $<TARGET_FILE_DIR:${TARGET_NAME}>/${TARGET_NAME}.bin
|
||||||
|
COMMENT "Generating raw .bin file for ${TARGET_NAME}"
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
add_subdirectory(examples)
|
||||||
|
|||||||
3
examples/CMakeLists.txt
Normal file
3
examples/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
cmake_minimum_required(VERSION 4.0)
|
||||||
|
|
||||||
|
add_subdirectory(first)
|
||||||
8
examples/first/CMakeLists.txt
Normal file
8
examples/first/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
cmake_minimum_required(VERSION 4.0)
|
||||||
|
|
||||||
|
add_executable(first
|
||||||
|
first.c
|
||||||
|
)
|
||||||
|
target_link_libraries(first PUBLIC card-os-user)
|
||||||
|
|
||||||
|
card_os_finalize_user_program(first)
|
||||||
13
examples/first/first.c
Normal file
13
examples/first/first.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <card-os.h>
|
||||||
|
|
||||||
|
static volatile int value;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
card_os_put_rect((card_os_rect){
|
||||||
|
.r = 0, .g = 0, .b = 0, .x = 0, .y = 0, .w = 240, .h = 320 });
|
||||||
|
card_os_put_rect((card_os_rect){
|
||||||
|
.r = 0xFF, .g = 0xFF, .b = 0xFF, .x = 60, .y = 80, .w = 60, .h = 80 });
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
22
include/ring-buffer.h
Normal file
22
include/ring-buffer.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef CARD_OS_RING_BUFFER
|
||||||
|
#define CARD_OS_RING_BUFFER
|
||||||
|
|
||||||
|
#include "user/card-os.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
OS_RING_BUFFER_SIZE = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int write_index;
|
||||||
|
unsigned int read_index;
|
||||||
|
|
||||||
|
os_message buffer[OS_RING_BUFFER_SIZE];
|
||||||
|
} os_ring_buffer;
|
||||||
|
|
||||||
|
int os_ring_buffer_write(volatile os_ring_buffer* ring_buffer,
|
||||||
|
const os_message* message);
|
||||||
|
|
||||||
|
#endif // CARD_OS_RING_BUFFER
|
||||||
@ -3,12 +3,27 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
OS_CMD_TERMINATE_PROGRAM,
|
||||||
|
OS_CMD_SBRK,
|
||||||
|
OS_CMD_DRAW_RECT
|
||||||
|
} os_command;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
os_command command;
|
||||||
|
void* data;
|
||||||
|
} os_message;
|
||||||
|
|
||||||
|
typedef void (*os_call_fn)(os_message*);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t r, g, b;
|
uint8_t r, g, b;
|
||||||
uint16_t x, y, w, h;
|
uint16_t x, y, w, h;
|
||||||
} card_os_rect;
|
} card_os_rect;
|
||||||
|
|
||||||
void card_os_put_rect(const card_os_rect* rect);
|
void card_os_put_rect(card_os_rect rect);
|
||||||
|
|
||||||
#endif // CARD_OS_USER
|
#endif // CARD_OS_USER
|
||||||
|
|||||||
39
src/card-os-link-user.ld
Normal file
39
src/card-os-link-user.ld
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
RAM (rwx) : ORIGIN = 0x20000000 + 192k, LENGTH = 64k
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = ORIGIN(RAM);
|
||||||
|
|
||||||
|
.start : ALIGN(4)
|
||||||
|
{
|
||||||
|
KEEP(*(.start))
|
||||||
|
}
|
||||||
|
|
||||||
|
.text : ALIGN(4)
|
||||||
|
{
|
||||||
|
*(.text*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : ALIGN(4)
|
||||||
|
{
|
||||||
|
*(.rodata*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : ALIGN(4)
|
||||||
|
{
|
||||||
|
*(.data*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end__ = .;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,12 +23,16 @@
|
|||||||
|
|
||||||
FLASH_SIZE = 8m;
|
FLASH_SIZE = 8m;
|
||||||
OSCALL_SIZE = 4k;
|
OSCALL_SIZE = 4k;
|
||||||
|
TOTAL_RAM_SIZE = 256k;
|
||||||
|
USER_RAM_SIZE = 64k;
|
||||||
|
KERNEL_RAM_SIZE = TOTAL_RAM_SIZE - USER_RAM_SIZE;
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = FLASH_SIZE - OSCALL_SIZE
|
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = FLASH_SIZE - OSCALL_SIZE
|
||||||
OSCALL(rx) : ORIGIN = 0x10000000 + FLASH_SIZE - OSCALL_SIZE, LENGTH = OSCALL_SIZE
|
OSCALL(rx) : ORIGIN = 0x10000000 + FLASH_SIZE - OSCALL_SIZE, LENGTH = OSCALL_SIZE
|
||||||
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
|
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = KERNEL_RAM_SIZE
|
||||||
|
USER_RAM(rwx) : ORIGIN = 0x20000000 + KERNEL_RAM_SIZE, LENGTH = USER_RAM_SIZE
|
||||||
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
|
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
|
||||||
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
|
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
|
||||||
}
|
}
|
||||||
@ -145,12 +149,12 @@ SECTIONS
|
|||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
__oscall_start = .;
|
|
||||||
.oscall :
|
.oscall :
|
||||||
{
|
{
|
||||||
|
__oscall_start = .;
|
||||||
KEEP(*(.oscall))
|
KEEP(*(.oscall))
|
||||||
|
__oscall_end = .;
|
||||||
} > OSCALL
|
} > OSCALL
|
||||||
__oscall_end = .;
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
|
||||||
.ram_vector_table (NOLOAD): {
|
.ram_vector_table (NOLOAD): {
|
||||||
@ -290,6 +294,9 @@ SECTIONS
|
|||||||
PROVIDE (_end = __end__);
|
PROVIDE (_end = __end__);
|
||||||
PROVIDE (__llvm_libc_heap_limit = __HeapLimit);
|
PROVIDE (__llvm_libc_heap_limit = __HeapLimit);
|
||||||
|
|
||||||
|
PROVIDE(__user_ram_start = ORIGIN(USER_RAM));
|
||||||
|
PROVIDE(__user_ram_end = ORIGIN(USER_RAM) + LENGTH(USER_RAM));
|
||||||
|
|
||||||
/* Check if data + heap + stack exceeds RAM limit */
|
/* Check if data + heap + stack exceeds RAM limit */
|
||||||
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
|
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,48 @@
|
|||||||
#include <card-os.h>
|
#include <card-os.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
typedef void (*os_call_fn)(int call, const void* inptr, void* outptr);
|
const os_call_fn oscall
|
||||||
|
= (os_call_fn)(0x10000000 + 8 * 1024 * 1024 - 4096 + 1);
|
||||||
|
|
||||||
// address guaranteed by linker script for os
|
int _close(int file) { return -1; }
|
||||||
extern os_call_fn __oscall_start;
|
|
||||||
|
off_t _lseek(int file, off_t ptr, int dir) { return 0; }
|
||||||
|
|
||||||
|
ssize_t _read(int file, void* ptr, size_t len) { return 0; }
|
||||||
|
|
||||||
|
ssize_t _write(int file, const void* ptr, size_t len) { return len; }
|
||||||
|
|
||||||
|
void _exit(int status)
|
||||||
|
{
|
||||||
|
oscall(&(os_message){ .command = OS_CMD_TERMINATE_PROGRAM, .data = NULL });
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* _sbrk(ptrdiff_t incr)
|
||||||
|
{
|
||||||
|
os_message msg = { .command = OS_CMD_SBRK, .data = &incr };
|
||||||
|
oscall(&msg);
|
||||||
|
return msg.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void card_os_put_rect(card_os_rect rect)
|
||||||
|
{
|
||||||
|
oscall(&(os_message){ .command = OS_CMD_DRAW_RECT, .data = &rect });
|
||||||
|
}
|
||||||
|
|
||||||
|
extern uint8_t __bss_start__;
|
||||||
|
extern uint8_t __bss_end__;
|
||||||
|
int main(void);
|
||||||
|
|
||||||
|
__attribute__((section(".start"))) void _start(void)
|
||||||
|
{
|
||||||
|
for (uint8_t* p = &__bss_start__; p < &__bss_end__; p++)
|
||||||
|
{
|
||||||
|
*p = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_exit(main());
|
||||||
|
}
|
||||||
|
|||||||
178
src/card-os.c
178
src/card-os.c
@ -2,9 +2,12 @@
|
|||||||
|
|
||||||
#include "card-os.h"
|
#include "card-os.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
#include "ring-buffer.h"
|
||||||
|
|
||||||
#include <hardware/spi.h>
|
#include <hardware/spi.h>
|
||||||
|
#include <hardware/sync.h>
|
||||||
#include <pico/bootrom.h>
|
#include <pico/bootrom.h>
|
||||||
|
#include <pico/multicore.h>
|
||||||
#include <pico/stdlib.h>
|
#include <pico/stdlib.h>
|
||||||
#include <tusb.h>
|
#include <tusb.h>
|
||||||
|
|
||||||
@ -14,6 +17,15 @@ const uint8_t DISPLAY_CS = 5;
|
|||||||
const uint8_t DISPLAY_DC = 4;
|
const uint8_t DISPLAY_DC = 4;
|
||||||
spi_inst_t* const DISPLAY_SPI = spi0;
|
spi_inst_t* const DISPLAY_SPI = spi0;
|
||||||
|
|
||||||
|
extern uint8_t __user_ram_start;
|
||||||
|
|
||||||
|
typedef int (*user_program_fn)(void);
|
||||||
|
static volatile user_program_fn user_program;
|
||||||
|
|
||||||
|
void core1_entry(void);
|
||||||
|
void os_task(void);
|
||||||
|
void os_handle_message(const os_message* msg, os_message* out);
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
gpio_set_function(DISPLAY_SCK, GPIO_FUNC_SPI);
|
gpio_set_function(DISPLAY_SCK, GPIO_FUNC_SPI);
|
||||||
@ -33,18 +45,146 @@ int main(void)
|
|||||||
|
|
||||||
tud_init(0);
|
tud_init(0);
|
||||||
|
|
||||||
|
user_program = NULL;
|
||||||
|
multicore_launch_core1(core1_entry);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
tud_task();
|
tud_task();
|
||||||
|
os_task();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t program_length;
|
||||||
|
static uint16_t program_write_index;
|
||||||
|
static enum {
|
||||||
|
RECV_WAITING,
|
||||||
|
RECV_HIGH8_LENGTH,
|
||||||
|
RECV_LOW8_LENGTH,
|
||||||
|
RECV_PROGRAM
|
||||||
|
} recv_status = RECV_WAITING;
|
||||||
void tud_vendor_rx_cb(uint8_t itf, const uint8_t* buffer, uint16_t bufsize)
|
void tud_vendor_rx_cb(uint8_t itf, const uint8_t* buffer, uint16_t bufsize)
|
||||||
{
|
{
|
||||||
if (buffer[0] == 0x99)
|
if (buffer[0] == 0x99 && recv_status == RECV_WAITING)
|
||||||
{
|
{
|
||||||
rom_reset_usb_boot(0, 0);
|
rom_reset_usb_boot(0, 0);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int bufidx = 0; bufidx < bufsize; bufidx++)
|
||||||
|
{
|
||||||
|
switch (recv_status)
|
||||||
|
{
|
||||||
|
case RECV_WAITING:
|
||||||
|
program_length = 0;
|
||||||
|
program_write_index = 0;
|
||||||
|
recv_status = RECV_HIGH8_LENGTH;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECV_HIGH8_LENGTH:
|
||||||
|
display_put_rect(0, 0, 0xFF, 0, 0, 240, 320);
|
||||||
|
program_length |= buffer[bufidx];
|
||||||
|
program_length <<= 8;
|
||||||
|
recv_status = RECV_LOW8_LENGTH;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECV_LOW8_LENGTH:
|
||||||
|
display_put_rect(0xFF, 0, 0, 0, 0, 240, 320);
|
||||||
|
program_length |= buffer[bufidx];
|
||||||
|
recv_status = RECV_PROGRAM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECV_PROGRAM:
|
||||||
|
(&__user_ram_start)[program_write_index++] = buffer[bufidx];
|
||||||
|
if (program_write_index == program_length)
|
||||||
|
{
|
||||||
|
display_put_rect(0, 0xFF, 0, 0, 0, 240, 320);
|
||||||
|
__dmb();
|
||||||
|
user_program = (user_program_fn)((uintptr_t)&__user_ram_start | 1);
|
||||||
|
__sev();
|
||||||
|
recv_status = RECV_WAITING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static volatile os_ring_buffer core0_buffer
|
||||||
|
= { .read_index = 0, .write_index = 0 };
|
||||||
|
static volatile os_ring_buffer core1_buffer
|
||||||
|
= { .read_index = 0, .write_index = 0 };
|
||||||
|
|
||||||
|
void core1_entry(void)
|
||||||
|
{
|
||||||
|
display_put_rect(0xFF, 0, 0xFF, 0, 0, 240, 320);
|
||||||
|
|
||||||
|
while (!user_program)
|
||||||
|
{
|
||||||
|
__wfe();
|
||||||
|
}
|
||||||
|
|
||||||
|
user_program();
|
||||||
|
|
||||||
|
// send message to terminate core 1
|
||||||
|
int index = -1;
|
||||||
|
while (index < 0)
|
||||||
|
{
|
||||||
|
index = os_ring_buffer_write(&core1_buffer,
|
||||||
|
&(os_message){ .command = 1, .data = NULL });
|
||||||
|
}
|
||||||
|
multicore_fifo_push_blocking(index);
|
||||||
|
|
||||||
|
// stall until reset
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// runs on core 0
|
||||||
|
void os_task(void)
|
||||||
|
{
|
||||||
|
if (multicore_fifo_rvalid())
|
||||||
|
{
|
||||||
|
uint32_t index = multicore_fifo_pop_blocking();
|
||||||
|
os_message msg = core1_buffer.buffer[index];
|
||||||
|
core1_buffer.read_index
|
||||||
|
= (core1_buffer.read_index + 1) % OS_RING_BUFFER_SIZE;
|
||||||
|
os_message out;
|
||||||
|
os_handle_message(&msg, &out);
|
||||||
|
out.command = msg.command;
|
||||||
|
int wrote_index = -1;
|
||||||
|
while (wrote_index < 0)
|
||||||
|
{
|
||||||
|
wrote_index = os_ring_buffer_write(&core0_buffer, &out);
|
||||||
|
}
|
||||||
|
multicore_fifo_push_blocking(wrote_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern uint8_t __end__;
|
||||||
|
extern uint8_t __StackLimit;
|
||||||
|
|
||||||
|
static uint8_t* heap_end;
|
||||||
|
void os_sbrk(const ptrdiff_t* incr, void** out)
|
||||||
|
{
|
||||||
|
if (!heap_end)
|
||||||
|
{
|
||||||
|
heap_end = &__end__;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* prev = heap_end;
|
||||||
|
uint8_t* next = heap_end + *(ptrdiff_t*)incr;
|
||||||
|
|
||||||
|
if (next >= &__StackLimit || next < &__end__)
|
||||||
|
{
|
||||||
|
*out = (void*)-1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
heap_end = next;
|
||||||
|
*out = prev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void os_put_rect(const card_os_rect* rect)
|
void os_put_rect(const card_os_rect* rect)
|
||||||
@ -53,12 +193,40 @@ void os_put_rect(const card_os_rect* rect)
|
|||||||
rect->h);
|
rect->h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __attribute__((section(".oscall"))) void
|
void os_handle_message(const os_message* msg, os_message* out)
|
||||||
oscall(int call, const void* inptr, void* outptr)
|
|
||||||
{
|
{
|
||||||
switch (call)
|
switch (msg->command)
|
||||||
{
|
{
|
||||||
case 0:
|
case OS_CMD_TERMINATE_PROGRAM:
|
||||||
|
multicore_fifo_drain();
|
||||||
|
multicore_reset_core1();
|
||||||
|
break;
|
||||||
|
case OS_CMD_SBRK:
|
||||||
|
os_sbrk(msg->data, &out->data);
|
||||||
|
break;
|
||||||
|
case OS_CMD_DRAW_RECT:
|
||||||
|
os_put_rect(msg->data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this should run on core 1
|
||||||
|
__attribute__((section(".oscall"), noinline, used)) void
|
||||||
|
oscall(os_message* message)
|
||||||
|
{
|
||||||
|
os_message local_msg = *message;
|
||||||
|
|
||||||
|
// send command
|
||||||
|
int index = -1;
|
||||||
|
while (index < 0)
|
||||||
|
{
|
||||||
|
index = os_ring_buffer_write(&core1_buffer, &local_msg);
|
||||||
|
}
|
||||||
|
multicore_fifo_push_blocking(index);
|
||||||
|
|
||||||
|
// receive response
|
||||||
|
index = multicore_fifo_pop_blocking();
|
||||||
|
*message = core0_buffer.buffer[index];
|
||||||
|
core0_buffer.read_index
|
||||||
|
= (core0_buffer.read_index + 1) % OS_RING_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|||||||
23
src/ring-buffer.c
Normal file
23
src/ring-buffer.c
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "ring-buffer.h"
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
int os_ring_buffer_write(volatile os_ring_buffer* ring_buffer,
|
||||||
|
const os_message* message)
|
||||||
|
{
|
||||||
|
if ((ring_buffer->write_index + 1) % OS_RING_BUFFER_SIZE
|
||||||
|
== ring_buffer->read_index)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__compiler_membar();
|
||||||
|
ring_buffer->buffer[ring_buffer->write_index] = *message;
|
||||||
|
|
||||||
|
int index = ring_buffer->write_index;
|
||||||
|
|
||||||
|
ring_buffer->write_index
|
||||||
|
= (ring_buffer->write_index + 1) % OS_RING_BUFFER_SIZE;
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user