As an embedded engineer, I like schematic, layout, coding, debugging. I also except to understand various concepts of OS, for example, task, semaphore, message queue, scheduling, etc.

So OSCUS is coming. It's a hackable OS for hardware hobbyists. It's neat and tiny.
The code line is about 1K and just need a little amount of RAM about 100bytes to run. 
So it is very easy to understand and use for those who are interesting in OS concept. 

It features:
- Co-operative multitasking, without complex stack management
- Two-level scheduling mechanics, priority-based(maximum eq 0x04)
- and round-robin in each priority level(maximum eq 0x04)
- Maximum task number eq 16
- Rapid task switch, time complexity O(1)

Task Model:
- Task priority ranges from 0x00 to 0x0F
- When there are no tasks in the higher priority level group, controller will be give to tasks in the lower priority
- When two or more tasks have the same priority, controller will be given to the next after the previous run-to-completion
- Task 0 as idle routine, must be defined
**      Round-robin scheduling in each group
**      --->
**      | F | E | D | C |    - priority level 3  - highest    | Priority-based 
**      | B | A | 9 | 8 |    - priority level 2               V scheduling
**      | 7 | 6 | 5 | 4 |    - priority level 1               
**      | 3 | 2 | 1 | 0 |    - priority level 0  - lowest   

=======================

Here is the schedule lookup table and routine for 4x4 tasks. 

First we search the highest priority group, then each ready-to-run task in the group will be invoked round by round.

So we can implement the schedule time complexity O(1).

 crByte const crDskTbl[][CR_RR_PPL_NUM]={
            0x00,0x00,0x00,0x00, /*0:0000*/

            0x00,0x00,0x00,0x00, /*1:0001*/

            0x01,0x01,0x01,0x01, /*2:0010*/

            0x01,0x00,0x01,0x01, /*3:0011*/

            0x02,0x02,0x02,0x02, /*4:0100*/

            0x02,0x00,0x00,0x02, /*5:0101*/

            0x02,0x02,0x01,0x02, /*6:0110*/

            0x02,0x00,0x01,0x02, /*7:0111*/

            0x03,0x03,0x03,0x03, /*8:1000*/

            0x03,0x00,0x00,0x00, /*9:1001*/

            0x03,0x03,0x01,0x01, /*A:1010*/

            0x03,0x00,0x01,0x01, /*B:1011*/

            0x03,0x03,0x03,0x02, /*C:1100*/

            0x03,0x00,0x00,0x02, /*D:1101*/

            0x03,0x03,0x01,0x02, /*E:1110*/

            0x03,0x00,0x01,0x02};/*F:1111*/ 

 
 void crTaskSched()
 {
    crByte BitX,BitY;    
    //crAssert("crTskSched begin:0x%02x\r\n", crRdyTskGrp != 0x00);

    BitY = CR_DBIT_FSB(crRdyTskGrp);
    BitX = CR_DBIT_NXT(crRdyTskRow[BitY], crRdyTskCol[BitY]);
    crRdyTskCol[BitY] = BitX;  
    crRdyTskIdx = CR_BIT_OR(CR_BIT_LSHIFT(BitY,2), BitX);
     
    //crAssert("crTskSched end:%d\r\n", crTskTbl[crRdyTskIdx].entry != (void*)0x00 );
 }


===========================