ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
3 декабря
1466873 Топик полностью
klen (02.10.2024 12:05, просмотров: 279) ответил klen на завел такое вот интересное - С++20 Coroutine на К1948ВК018, прикольно. оно работает. можно делать несложне шедуллеры не выбегая за средства языка. миленько компактненько простенько. Для контроллеров с озу 2к флеша 8к просто огонь!
сделал сферического коня в вакуме - чистый проект. без crt , без обработки прерываний по таймеру для событй, без cout. только прыжок в main по ресету, и код шедуллинга четырех корутин для удобного наблюдения без шелухи. 940 байт кода и 32 байта данных. листинги символов и асма. цикловая работа задач - выполнить одн nop. 

обрезанный код прилагухи


#include "appdefs.h"

co_task_t task0()
{
  for(;;)
      {
  	     if ( !co_await event0)  continue ;
             nop();
      }
}
co_task_t task1() { for(;;) { if ( !co_await event1) continue ; nop(); } } co_task_t task2() { for(;;) { if ( !co_await event2) continue ; nop(); } } co_task_t task3() { for(;;) { if ( !co_await event3) continue ; nop(); } } int main() { const auto tasks = {task0() , task1(), task2(),task3()}; co_scheduller_t::start(tasks); } namespace mik32v2 { __attribute__((aligned(4),interrupt,used,section(".trap"))) void trap_handler() noexcept { } }





листинг символов прошивки

800002f0 000000ba T main
80000264 0000007e t task3(_Z5task3v.Frame*) [clone .actor]
800001d8 0000007e t task2(_Z5task2v.Frame*) [clone .actor]
80000150 0000007a t task1(_Z5task1v.Frame*) [clone .actor]
800000c8 0000007a t task0(_Z5task0v.Frame*) [clone .actor]
80000008 0000001e T reset_handler
800002e2 0000000e t task3(_Z5task3v.Frame*) [clone .destroy]
80000256 0000000e t task2(_Z5task2v.Frame*) [clone .destroy]
800001ca 0000000e t task1(_Z5task1v.Frame*) [clone .destroy]
80000142 0000000e t task0(_Z5task0v.Frame*) [clone .destroy]
80000000 00000008 T reset_jump
02000000 00000008 b event3
02000008 00000008 b event2
02000010 00000008 b event1
02000018 00000008 b event0
800000c0 00000004 T mik32v2::trap_handler()



листинг асм кода, тут я выделил код nop'пов чтоб было видно где же работает тело корутин, а где все остальная ннфраструктурная обвязка которую генерит компиялтор по сохранению и подъему фремов сотояния корутин при переключении




.././../out/image.elf: формат файла elf32-littleriscv Дизассемблирование раздела .text: 80000000 <reset_jump>: #endif // переход по корректному адресу области команд (не отмапленному на облость загрузки) extern "C" constexpr __attribute__((noreturn,naked,used,section(".reset_jump"))) void reset_jump() { asm volatile ( 80000000: 800000b7 lui ra,0x80000 80000004: 008080e7 jalr 8(ra) # 80000008 <reset_handler> 80000008 <reset_handler>: template<typename T> __ais__ void nop_wait ( const T (*calle)() ) { while ( static_cast<bool>(calle()) ) { nop();} } template<typename T> __ais__ void nop_nwait ( const T (*calle)() ) { while ( !static_cast<bool>(calle()) ) { nop();} } __ais__ uint32_t sp() { register uint32_t res asm("sp"); return res; } __ais__ void sp(const void* val) { asm volatile ( "la sp, %[val]" : : [val]"i"(val) : ) ; } 80000008: 82004117 auipc sp,0x82004 8000000c: ff810113 addi sp,sp,-8 # 2004000 <__main_stack_end__> __ais__ uint32_t gp() { register uint32_t res asm("gp"); return res; } __ais__ void gp(const void* val) { asm volatile ( ".option push; .option norelax; la gp, %[val]; ; .option pop;" : : [val]"i"(val) : ) ; } 80000010: 82000197 auipc gp,0x82000 80000014: 7f018193 addi gp,gp,2032 # 2000800 <__global_pointer$> template<const uint32_t csr_reg> __ais__ void csrw (const uint32_t rs1) { asm volatile ("csrw %[csr], %[rs1]" : : [csr] "i" (csr_reg), [rs1]"r"(rs1) : ); } 80000018: 800007b7 lui a5,0x80000 8000001c: 0c078293 addi t0,a5,192 # 800000c0 <mik32v2::trap_handler()> 80000020: 30529073 csrw mtvec,t0 #ifdef __CRT_IMPL_PREMAIN_ENABLE__ __premain() ; #endif // __CRT_IMPL_PREMAIN_ENABLE__ main() ; 80000024: 24f1 jal 800002f0 <main> ... 800000c0 <mik32v2::trap_handler()>: namespace mik32v2 { __attribute__((aligned(4),interrupt,used,section(".trap"))) void trap_handler() noexcept { } 800000c0: 30200073 mret 800000c4: 0001 nop ... 800000c8 <task0(_Z5task0v.Frame*) [clone .actor]>: } 800000c8: 01055783 lhu a5,16(a0) 800000cc: 0017f713 andi a4,a5,1 800000d0: ,-- cf01 beqz a4,800000e8 <task0(_Z5task0v.Frame*) [clone .actor]+0x20> 800000d2: | 4f15 li t5,5 800000d4: ,--|-- 00ff6963 bltu t5,a5,800000e6 <task0(_Z5task0v.Frame*) [clone .actor]+0x1e> 800000d8: | | 02a00f93 li t6,42 800000dc: | | 00ffd7b3 srl a5,t6,a5 800000e0: | | 0017f713 andi a4,a5,1 800000e4: ,-----|--|-- ef31 bnez a4,80000140 <task0(_Z5task0v.Frame*) [clone .actor]+0x78> co_task_t task0() 800000e6: | >--|-> 9002 ebreak } 800000e8: | | '-> 4289 li t0,2 800000ea: | | ,-- 02578663 beq a5,t0,80000116 <task0(_Z5task0v.Frame*) [clone .actor]+0x4e> 800000ee: | | | 4691 li a3,4 800000f0: | ,--|--|-- 00d78763 beq a5,a3,800000fe <task0(_Z5task0v.Frame*) [clone .actor]+0x36> 800000f4: | | '--|-- fbed bnez a5,800000e6 <task0(_Z5task0v.Frame*) [clone .actor]+0x1e> 800000f6: | | | c548 sw a0,12(a0) 800000f8: | | | 00551823 sh t0,16(a0) 800000fc: | | | 8082 ret co_event_t& event; co_handle_t handle = nullptr; __ai__ awaiter(co_event_t& val) noexcept : event(val) {} __ai__ bool await_ready() const noexcept { return event.state(); } __ai__ bool await_resume() noexcept { return event.reset(); } 800000fe: | >-----|-> 01852303 lw t1,24(a0) public: // yстановка (активации) события __ai__ void set() noexcept { s = true; } // сброс события, возврат значения перед сбросом __ai__ bool reset () noexcept { auto const rv = s ; s = false; return rv;} 80000102: | | | 00434383 lbu t2,4(t1) 80000106: | | | 00030223 sb zero,4(t1) if ( !co_await event0) continue ; 8000010a: | | | 0013c593 xori a1,t2,1 8000010e: | | | 00b50a23 sb a1,20(a0) 80000112: | | +-- e191 bnez a1,80000116 <task0(_Z5task0v.Frame*) [clone .actor]+0x4e> __ais__ void nop() { asm volatile ("nop" ::: "memory"); } 80000114: | | | 0001 nop 80000116: | | '-> 81818813 addi a6,gp,-2024 # 2000018 <event0> } 8000011a: | | 00484883 lbu a7,4(a6) if ( !co_await event0) continue ; 8000011e: | | 01052c23 sw a6,24(a0) 80000122: | | 00052e23 sw zero,28(a0) } 80000126: | '-------- fc089ce3 bnez a7,800000fe <task0(_Z5task0v.Frame*) [clone .actor]+0x36> handle = val; 8000012a: | 00c52e83 lw t4,12(a0) 8000012e: | 4e11 li t3,4 80000130: | 01c51823 sh t3,16(a0) 80000134: | 01d52e23 sw t4,28(a0) if ( !co_await event0) continue ; 80000138: | 0561 addi a0,a0,24 // проверка состояния события __ai__ bool state() const noexcept { return s; } // Метод регистрации потребителя // Можно реализовать целый список потребителей __ai__ void set_awaiter(awaiter* val) noexcept { consumer = val; } 8000013a: | 00a82023 sw a0,0(a6) 8000013e: | 8082 ret } 80000140: '----------> 8082 ret 80000142 <task0(_Z5task0v.Frame*) [clone .destroy]>: co_task_t task0() 80000142: 01055783 lhu a5,16(a0) 80000146: 0017e293 ori t0,a5,1 8000014a: 00551823 sh t0,16(a0) 8000014e: bfad j 800000c8 <task0(_Z5task0v.Frame*) [clone .actor]> 80000150 <task1(_Z5task1v.Frame*) [clone .actor]>: } 80000150: 01055783 lhu a5,16(a0) 80000154: 0017f713 andi a4,a5,1 80000158: ,-- cf01 beqz a4,80000170 <task1(_Z5task1v.Frame*) [clone .actor]+0x20> 8000015a: | 4f15 li t5,5 8000015c: ,--|-- 00ff6963 bltu t5,a5,8000016e <task1(_Z5task1v.Frame*) [clone .actor]+0x1e> 80000160: | | 02a00f93 li t6,42 80000164: | | 00ffd7b3 srl a5,t6,a5 80000168: | | 0017f713 andi a4,a5,1 8000016c: ,-----|--|-- ef31 bnez a4,800001c8 <task1(_Z5task1v.Frame*) [clone .actor]+0x78> co_task_t task1() 8000016e: | >--|-> 9002 ebreak } 80000170: | | '-> 4289 li t0,2 80000172: | | ,-- 02578663 beq a5,t0,8000019e <task1(_Z5task1v.Frame*) [clone .actor]+0x4e> 80000176: | | | 4691 li a3,4 80000178: | ,--|--|-- 00d78763 beq a5,a3,80000186 <task1(_Z5task1v.Frame*) [clone .actor]+0x36> 8000017c: | | '--|-- fbed bnez a5,8000016e <task1(_Z5task1v.Frame*) [clone .actor]+0x1e> 8000017e: | | | c548 sw a0,12(a0) 80000180: | | | 00551823 sh t0,16(a0) 80000184: | | | 8082 ret __ai__ bool await_resume() noexcept { return event.reset(); } 80000186: | >-----|-> 01852303 lw t1,24(a0) __ai__ bool reset () noexcept { auto const rv = s ; s = false; return rv;} 8000018a: | | | 00434383 lbu t2,4(t1) 8000018e: | | | 00030223 sb zero,4(t1) if ( !co_await event1) continue ; 80000192: | | | 0013c593 xori a1,t2,1 80000196: | | | 00b50a23 sb a1,20(a0) 8000019a: | | +-- e191 bnez a1,8000019e <task1(_Z5task1v.Frame*) [clone .actor]+0x4e> 8000019c: | | | 0001 nop 8000019e: | | '-> 81018813 addi a6,gp,-2032 # 2000010 <event1> } 800001a2: | | 00484883 lbu a7,4(a6) if ( !co_await event1) continue ; 800001a6: | | 01052c23 sw a6,24(a0) 800001aa: | | 00052e23 sw zero,28(a0) } 800001ae: | '-------- fc089ce3 bnez a7,80000186 <task1(_Z5task1v.Frame*) [clone .actor]+0x36> handle = val; 800001b2: | 00c52e83 lw t4,12(a0) 800001b6: | 4e11 li t3,4 800001b8: | 01c51823 sh t3,16(a0) 800001bc: | 01d52e23 sw t4,28(a0) if ( !co_await event1) continue ; 800001c0: | 0561 addi a0,a0,24 __ai__ void set_awaiter(awaiter* val) noexcept { consumer = val; } 800001c2: | 00a82023 sw a0,0(a6) 800001c6: | 8082 ret } 800001c8: '----------> 8082 ret 800001ca <task1(_Z5task1v.Frame*) [clone .destroy]>: co_task_t task1() 800001ca: 01055783 lhu a5,16(a0) 800001ce: 0017e293 ori t0,a5,1 800001d2: 00551823 sh t0,16(a0) 800001d6: bfad j 80000150 <task1(_Z5task1v.Frame*) [clone .actor]> 800001d8 <task2(_Z5task2v.Frame*) [clone .actor]>: } 800001d8: 01055783 lhu a5,16(a0) 800001dc: 0017f713 andi a4,a5,1 800001e0: ,-- cf01 beqz a4,800001f8 <task2(_Z5task2v.Frame*) [clone .actor]+0x20> 800001e2: | 4f15 li t5,5 800001e4: ,--|-- 00ff6963 bltu t5,a5,800001f6 <task2(_Z5task2v.Frame*) [clone .actor]+0x1e> 800001e8: | | 02a00f93 li t6,42 800001ec: | | 00ffd7b3 srl a5,t6,a5 800001f0: | | 0017f713 andi a4,a5,1 800001f4: ,-----|--|-- e325 bnez a4,80000254 <task2(_Z5task2v.Frame*) [clone .actor]+0x7c> co_task_t task2() 800001f6: | >--|-> 9002 ebreak } 800001f8: | | '-> 4289 li t0,2 800001fa: | | ,-- 02578663 beq a5,t0,80000226 <task2(_Z5task2v.Frame*) [clone .actor]+0x4e> 800001fe: | | | 4691 li a3,4 80000200: | ,--|--|-- 00d78763 beq a5,a3,8000020e <task2(_Z5task2v.Frame*) [clone .actor]+0x36> 80000204: | | '--|-- fbed bnez a5,800001f6 <task2(_Z5task2v.Frame*) [clone .actor]+0x1e> 80000206: | | | c548 sw a0,12(a0) 80000208: | | | 00551823 sh t0,16(a0) 8000020c: | | | 8082 ret __ai__ bool await_resume() noexcept { return event.reset(); } 8000020e: | >-----|-> 01852303 lw t1,24(a0) __ai__ bool reset () noexcept { auto const rv = s ; s = false; return rv;} 80000212: | | | 00434383 lbu t2,4(t1) 80000216: | | | 00030223 sb zero,4(t1) if ( !co_await event2) continue ; 8000021a: | | | 0013c593 xori a1,t2,1 8000021e: | | | 00b50a23 sb a1,20(a0) 80000222: | | +-- e191 bnez a1,80000226 <task2(_Z5task2v.Frame*) [clone .actor]+0x4e> 80000224: | | | 0001 nop 80000226: | | '-> 02000637 lui a2,0x2000 8000022a: | | 00860813 addi a6,a2,8 # 2000008 <event2> } 8000022e: | | 00484883 lbu a7,4(a6) if ( !co_await event2) continue ; 80000232: | | 01052c23 sw a6,24(a0) 80000236: | | 00052e23 sw zero,28(a0) } 8000023a: | '-------- fc089ae3 bnez a7,8000020e <task2(_Z5task2v.Frame*) [clone .actor]+0x36> handle = val; 8000023e: | 00c52e83 lw t4,12(a0) 80000242: | 4e11 li t3,4 80000244: | 01c51823 sh t3,16(a0) 80000248: | 01d52e23 sw t4,28(a0) if ( !co_await event2) continue ; 8000024c: | 0561 addi a0,a0,24 __ai__ void set_awaiter(awaiter* val) noexcept { consumer = val; } 8000024e: | 00a82023 sw a0,0(a6) 80000252: | 8082 ret } 80000254: '----------> 8082 ret 80000256 <task2(_Z5task2v.Frame*) [clone .destroy]>: co_task_t task2() 80000256: 01055783 lhu a5,16(a0) 8000025a: 0017e293 ori t0,a5,1 8000025e: 00551823 sh t0,16(a0) 80000262: bf9d j 800001d8 <task2(_Z5task2v.Frame*) [clone .actor]> 80000264 <task3(_Z5task3v.Frame*) [clone .actor]>: } 80000264: 01055783 lhu a5,16(a0) 80000268: 0017f713 andi a4,a5,1 8000026c: ,-- cf01 beqz a4,80000284 <task3(_Z5task3v.Frame*) [clone .actor]+0x20> 8000026e: | 4f15 li t5,5 80000270: ,--|-- 00ff6963 bltu t5,a5,80000282 <task3(_Z5task3v.Frame*) [clone .actor]+0x1e> 80000274: | | 02a00f93 li t6,42 80000278: | | 00ffd7b3 srl a5,t6,a5 8000027c: | | 0017f713 andi a4,a5,1 80000280: ,-----|--|-- e325 bnez a4,800002e0 <task3(_Z5task3v.Frame*) [clone .actor]+0x7c> co_task_t task3() 80000282: | >--|-> 9002 ebreak } 80000284: | | '-> 4289 li t0,2 80000286: | | ,-- 02578663 beq a5,t0,800002b2 <task3(_Z5task3v.Frame*) [clone .actor]+0x4e> 8000028a: | | | 4691 li a3,4 8000028c: | ,--|--|-- 00d78763 beq a5,a3,8000029a <task3(_Z5task3v.Frame*) [clone .actor]+0x36> 80000290: | | '--|-- fbed bnez a5,80000282 <task3(_Z5task3v.Frame*) [clone .actor]+0x1e> 80000292: | | | c548 sw a0,12(a0) 80000294: | | | 00551823 sh t0,16(a0) 80000298: | | | 8082 ret __ai__ bool await_resume() noexcept { return event.reset(); } 8000029a: | >-----|-> 01852303 lw t1,24(a0) __ai__ bool reset () noexcept { auto const rv = s ; s = false; return rv;} 8000029e: | | | 00434383 lbu t2,4(t1) 800002a2: | | | 00030223 sb zero,4(t1) if ( !co_await event3) continue ; 800002a6: | | | 0013c593 xori a1,t2,1 800002aa: | | | 00b50a23 sb a1,20(a0) 800002ae: | | +-- e191 bnez a1,800002b2 <task3(_Z5task3v.Frame*) [clone .actor]+0x4e> 800002b0: | | | 0001 nop 800002b2: | | '-> 02000637 lui a2,0x2000 800002b6: | | 00060813 mv a6,a2 } 800002ba: | | 00484883 lbu a7,4(a6) if ( !co_await event3) continue ; 800002be: | | 01052c23 sw a6,24(a0) 800002c2: | | 00052e23 sw zero,28(a0) } 800002c6: | '-------- fc089ae3 bnez a7,8000029a <task3(_Z5task3v.Frame*) [clone .actor]+0x36> handle = val; 800002ca: | 00c52e83 lw t4,12(a0) 800002ce: | 4e11 li t3,4 800002d0: | 01c51823 sh t3,16(a0) 800002d4: | 01d52e23 sw t4,28(a0) if ( !co_await event3) continue ; 800002d8: | 0561 addi a0,a0,24 __ai__ void set_awaiter(awaiter* val) noexcept { consumer = val; } 800002da: | 00a82023 sw a0,0(a6) 800002de: | 8082 ret } 800002e0: '----------> 8082 ret 800002e2 <task3(_Z5task3v.Frame*) [clone .destroy]>: co_task_t task3() 800002e2: 01055783 lhu a5,16(a0) 800002e6: 0017e293 ori t0,a5,1 800002ea: 00551823 sh t0,16(a0) 800002ee: bf9d j 80000264 <task3(_Z5task3v.Frame*) [clone .actor]> 800002f0 <main>: { 800002f0: 1101 addi sp,sp,-32 800002f2: ce06 sw ra,28(sp) 800002f4: cc22 sw s0,24(sp) 800002f6: ca26 sw s1,20(sp) 800002f8: c84a sw s2,16(sp) co_task_t task0() 800002fa: 4485 li s1,1 800002fc: 800007b7 lui a5,0x80000 80000300: 80000337 lui t1,0x80000 80000304: 547d li s0,-1 80000306: 0c878293 addi t0,a5,200 # 800000c8 <task0(_Z5task0v.Frame*) [clone .actor]> 8000030a: 14230393 addi t2,t1,322 # 80000142 <task0(_Z5task0v.Frame*) [clone .destroy]> 8000030e: 009008a3 sb s1,17(zero) # 11 <__linker_section_align_size__+0xd> 80000312: 00542023 sw t0,0(s0) 80000316: 00742223 sw t2,4(s0) 8000031a: 8522 mv a0,s0 8000031c: 000017a3 sh zero,15(zero) # f <__linker_section_align_size__+0xb> 80000320: 3365 jal 800000c8 <task0(_Z5task0v.Frame*) [clone .actor]> co_task_t task1() 80000322: 80000637 lui a2,0x80000 const auto tasks = {task0() , task1(), task2(),task3()}; 80000326: c022 sw s0,0(sp) co_task_t task1() 80000328: 80000537 lui a0,0x80000 8000032c: 15050593 addi a1,a0,336 # 80000150 <task1(_Z5task1v.Frame*) [clone .actor]> 80000330: 009008a3 sb s1,17(zero) # 11 <__linker_section_align_size__+0xd> 80000334: 1ca60693 addi a3,a2,458 # 800001ca <task1(_Z5task1v.Frame*) [clone .destroy]> 80000338: c00c sw a1,0(s0) 8000033a: c054 sw a3,4(s0) 8000033c: 8522 mv a0,s0 8000033e: 000017a3 sh zero,15(zero) # f <__linker_section_align_size__+0xb> 80000342: 3539 jal 80000150 <task1(_Z5task1v.Frame*) [clone .actor]> co_task_t task2() 80000344: 80000737 lui a4,0x80000 const auto tasks = {task0() , task1(), task2(),task3()}; 80000348: c222 sw s0,4(sp) co_task_t task2() 8000034a: 800008b7 lui a7,0x80000 8000034e: 009008a3 sb s1,17(zero) # 11 <__linker_section_align_size__+0xd> 80000352: 1d870813 addi a6,a4,472 # 800001d8 <task2(_Z5task2v.Frame*) [clone .actor]> 80000356: 25688913 addi s2,a7,598 # 80000256 <task2(_Z5task2v.Frame*) [clone .destroy]> 8000035a: 01042023 sw a6,0(s0) 8000035e: 01242223 sw s2,4(s0) 80000362: 8522 mv a0,s0 80000364: 000017a3 sh zero,15(zero) # f <__linker_section_align_size__+0xb> 80000368: 3d85 jal 800001d8 <task2(_Z5task2v.Frame*) [clone .actor]> co_task_t task3() 8000036a: 80000e37 lui t3,0x80000 const auto tasks = {task0() , task1(), task2(),task3()}; 8000036e: c422 sw s0,8(sp) co_task_t task3() 80000370: 80000f37 lui t5,0x80000 80000374: 009008a3 sb s1,17(zero) # 11 <__linker_section_align_size__+0xd> 80000378: 264e0e93 addi t4,t3,612 # 80000264 <task3(_Z5task3v.Frame*) [clone .actor]> 8000037c: 2e2f0f93 addi t6,t5,738 # 800002e2 <task3(_Z5task3v.Frame*) [clone .destroy]> 80000380: 01d42023 sw t4,0(s0) 80000384: 01f42223 sw t6,4(s0) 80000388: 000017a3 sh zero,15(zero) # f <__linker_section_align_size__+0xb> 8000038c: 8522 mv a0,s0 8000038e: 3dd9 jal 80000264 <task3(_Z5task3v.Frame*) [clone .actor]> struct co_scheduller_t { template <typename T> __ains__ void start(const T& tasks) noexcept { for(;;) [[likely]] { for (auto& task : tasks) [[likely]] task.resume(); } 80000390: 44c1 li s1,16 const auto tasks = {task0() , task1(), task2(),task3()}; 80000392: c622 sw s0,12(sp) { 80000394: ,-> 4401 li s0,0 __ai__ void resume() const noexcept { handle.resume(); } 80000396: ,--|-> 008107b3 add a5,sp,s0 8000039a: | | 4388 lw a0,0(a5) bool done() const noexcept { return __builtin_coro_done(_M_fr_ptr); } // [coroutine.handle.resumption], resumption void operator()() const { resume(); } void resume() const { __builtin_coro_resume(_M_fr_ptr); } 8000039c: | | 0411 addi s0,s0,4 8000039e: | | 00052303 lw t1,0(a0) 800003a2: | | 9302 jalr t1 for(;;) [[likely]] { for (auto& task : tasks) [[likely]] task.resume(); } 800003a4: | '-- fe9408e3 beq s0,s1,80000394 <main+0xa4> 800003a8: '----- b7fd j 80000396 <main+0xa6> ...