This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Extending RTX with I/O api

I am trying to add an api like osOpen, osClose, osRead, osWrite, osSelect to CMSIS-RTOS, specifically to RTX (4.79). I am fairly new to embedded, but have Unix experience where my apps read from many I/O devices and use select+read in a loop rather than threads, which I view as evil. In the Cortex M3 arena, I am using EFM32GG parts.

In Unix, a read(fd) would block until any data was available in kernel space. A read from user space entails just one trap to the kernel. Inside that trap, there could possibly be a block, then a copy of data to userspace and then a return.

I cannot achieve this with RTX and the CMSIS-RTOS api. I have extended rt_CMSIS.c with say my osRead, whose guts is this:

while( !__svcReadable( fd ) ) { // A READ that blocks is woken by single explicit signal, matching fd osEvent ev = osSignalWait( 1 << fd, 0xFFFF ); if( ev.status != osEventSignal ) return -1; } return __svcRead( fd, buf, count );
}

The problem is that this does not one but TWO trips into handler mode (kernel space in Unix), one for the osSignalWait and one for my svcRead.

Yet if I try to 'postpone' my 'is there data or would we block?' check to handler mode, it won't work. This below is what I want, a svcRead WITH the block check in it, but doesn't work:

int32_t svcRead( int32_t fd, void* buf, int32_t count ) { DeviceControlBlock* dcb = DCBS[fd];

if( !svcReadable( fd ) ) { svcSignalWait( 1 << fd, 0xFFFF ); } // now copy the data to buf...

The reason is that svcSignalWait does not actually 'block' but always returns. I can see that it's ONLY the SVC Handler (the assembler code for my GNU toolchain) which can EVER context switch (block one thread and ready another). Therefore, you can't do 'more work' after svcSignalWait returns, since it Expects to return to the SVC handler.

So, is the best I can do the 'two trips to handler mode'? That smells of a race condition where some state could change in between the two, and a thread that THOUGHT the read would return actually does NOT return.

Any help appreciated, esp any pointers from anyone doing RTX extensions.

Stuart