stm32f4 __wfi
Christian Mauderer
christian.mauderer at embedded-brains.de
Wed Apr 24 08:48:50 UTC 2019
There is the wfi in the Idle body. So as soon as all your tasks are
sleeping (via sleep(), rtems_task_wake_after(), waiting for some signals
or similar functions) wfi will be called.
Note that there most likely is a lot of potential in the drivers to save
power. Also note that the system will wake up every tick. So depending
on your configuration the power consumption will vary.
Am 24.04.19 um 10:44 schrieb Jython:
> i searched it by add -i
>
> 56794:0000d040 <_CPU_Thread_Idle_body>:
> 56795-#ifdef ARM_MULTILIB_HAS_WFI
> 56796-
> 56797:void *_CPU_Thread_Idle_body( uintptr_t ignored )
> 56798-{
> 56799- while ( true ) {
> 56800- __asm__ volatile ("wfi");
> 56801- d040: bf30 wfi
> 56802- }
> 56803: d042: e7fd b.n d040 <_CPU_Thread_Idle_body>
> 56804-
> 56805-0000d044 <rtems_filesystem_default_close>:
> 56806-int rtems_filesystem_default_close(
> 56807- rtems_libio_t *iop
> 56808-)
> 56809-{
> 56810- return 0;
> 56811-}
> 56812- d044: 2000 movs r0, #0
> 56813- d046: 4770 bx lr
>
>
> that's to say when i want to enter low power i just need to call sleep
> or rtems_task_wake_after or just while(1); ?
>
> On Wed, Apr 24, 2019 at 4:36 PM Christian Mauderer
> <christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>> wrote:
>
> For some reason your grep hasn't found the _CPU_Thread_Idle_body. It's
> possible that the stm32f4 uses some other function for that also I don't
> know why.
>
> For example for the xilinx_zynq_a9_qemu BSP the disassembled idle body
> looks like follows:
>
> void *_CPU_Thread_Idle_body( uintptr_t ignored )
> {
> 11d70: b480 push {r7}
> 11d72: b083 sub sp, #12
> 11d74: af00 add r7, sp, #0
> 11d76: 6078 str r0, [r7, #4]
> while ( true ) {
> #ifdef ARM_MULTILIB_HAS_WFI
> __asm__ volatile ("wfi");
> 11d78: bf30 wfi
> 11d7a: e7fd b.n 11d78
> <_CPU_Thread_Idle_body+0x8>
>
> Am 24.04.19 um 10:25 schrieb Jython:
> > arm-rtems4.11-objdump -dS hello.exe | grep idle --color=auto -n -B
> 5 -A 12
> >
> > there is no idle function which calls wfi command
> > // log
> > 508-
> > 509-
> > 510-
> > 511- }
> > 512-
> > 513: if((*USART2_SR) & (1<<4)) // idle
> > 514- 3aa: 4b13 ldr r3, [pc, #76] ; (3f8
> > <USART2_handler+0x94>)
> > 515- 3ac: 681b ldr r3, [r3, #0]
> > 516- 3ae: 681b ldr r3, [r3, #0]
> > 517- 3b0: f003 0310 and.w r3, r3, #16
> > 518- 3b4: 2b00 cmp r3, #0
> > 519- 3b6: d00a beq.n 3ce <USART2_handler+0x6a>
> > 520- {
> > 521: //printk("idle ");
> > 522-
> > 523- temp = (*USART2_SR);
> > 524- 3b8: 4b0f ldr r3, [pc, #60] ; (3f8
> > <USART2_handler+0x94>)
> > 525- 3ba: 681b ldr r3, [r3, #0]
> > 526- 3bc: 681b ldr r3, [r3, #0]
> > 527- 3be: 60fb str r3, [r7, #12]
> > 528- temp = (*USART2_DR);
> > 529- 3c0: 4b0f ldr r3, [pc, #60] ; (400
> > <USART2_handler+0x9c>)
> > 530- 3c2: 681b ldr r3, [r3, #0]
> > 531- 3c4: 681b ldr r3, [r3, #0]
> > 532- 3c6: 60fb str r3, [r7, #12]
> > 533- //temp = temp;
> > --
> > 627-
> > 628-
> > 629-
> > 630- }
> > 631-
> > 632: if((*USART3_SR) & (1<<4)) // idle
> > 633- 44c: 4b12 ldr r3, [pc, #72] ; (498
> > <USART3_handler+0x8c>)
> > 634- 44e: 681b ldr r3, [r3, #0]
> > 635- 450: 681b ldr r3, [r3, #0]
> > 636- 452: f003 0310 and.w r3, r3, #16
> > 637- 456: 2b00 cmp r3, #0
> > 638- 458: d00a beq.n 470 <USART3_handler+0x64>
> > 639- {
> > 640: //printk("idle ");
> > 641-
> > 642- temp = (*USART3_SR);
> > 643- 45a: 4b0f ldr r3, [pc, #60] ; (498
> > <USART3_handler+0x8c>)
> > 644- 45c: 681b ldr r3, [r3, #0]
> > 645- 45e: 681b ldr r3, [r3, #0]
> > 646- 460: 60fb str r3, [r7, #12]
> > 647- temp = (*USART3_DR);
> > 648- 462: 4b0f ldr r3, [pc, #60] ; (4a0
> > <USART3_handler+0x94>)
> > 649- 464: 681b ldr r3, [r3, #0]
> > 650- 466: 681b ldr r3, [r3, #0]
> > 651- 468: 60fb str r3, [r7, #12]
> > 652-
> > --
> > 26329-
> > 26330- if (newTail == tty->rawOutBuf.Head) {
> > 26331- /*
> > 26332- * Buffer has become empty
> > 26333- */
> > 26334: tty->rawOutBufState = rob_idle;
> > 26335- 69a0: f880 5094 strb.w r5, [r0, #148] ; 0x94
> > 26336- (*tty->handler.write) (ctx, NULL, 0);
> > 26337- 69a4: f8d4 30c4 ldr.w r3, [r4, #196] ; 0xc4
> > 26338- 69a8: 4670 mov r0, lr
> > 26339- 69aa: 4629 mov r1, r5
> > 26340- 69ac: 462a mov r2, r5
> > 26341- 69ae: 4798 blx r3
> > 26342- nToSend = 0;
> > 26343-
> > 26344- /*
> > 26345- * check to see if snd wakeup callback was set
> > 26346- */
> > --
> > 26443- 6a12: 2600 movs r6, #0
> > 26444- 6a14: e7ac b.n 6970
> > <rtems_termios_refill_transmitter+0x7c>
> > 26445- /*
> > 26446- * Buffer has become empty
> > 26447- */
> > 26448: tty->rawOutBufState = rob_idle;
> > 26449- (*tty->handler.write) (ctx, NULL, 0);
> > 26450- nToSend = 0;
> > 26451- 6a16: 461d mov r5, r3
> > 26452- 6a18: e7aa b.n 6970
> > <rtems_termios_refill_transmitter+0x7c>
> > 26453- 6a1a: bf00 nop
> > 26454-
> > 26455-00006a1c <rtems_termios_txdaemon>:
> > 26456-
> > 26457-/*
> > 26458- * this task actually processes any transmit events
> > 26459- */
> > 26460-static rtems_task rtems_termios_txdaemon(rtems_task_argument
> argument)
> > --
> > 27083- RTEMS_NO_PRIORITY,
> > 27084- &tty->rawOutBuf.Semaphore);
> > 27085- if (sc != RTEMS_SUCCESSFUL)
> > 27086- 6cc0: 2800 cmp r0, #0
> > 27087- 6cc2: f040 80d6 bne.w 6e72
> > <rtems_termios_open_tty+0x2de>
> > 27088: tty->rawOutBufState = rob_idle;
> > 27089-
> > 27090- /*
> > 27091- * Set callbacks
> > 27092- */
> > 27093- if (device_node != NULL) {
> > 27094- 6cc6: 9b0e ldr r3, [sp, #56] ; 0x38
> > 27095- RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_FIFO,
> > 27096- RTEMS_NO_PRIORITY,
> > 27097- &tty->rawOutBuf.Semaphore);
> > 27098- if (sc != RTEMS_SUCCESSFUL)
> > 27099- rtems_fatal_error_occurred (sc);
> > 27100: tty->rawOutBufState = rob_idle;
> > 27101- 6cc8: f884 0094 strb.w r0, [r4, #148] ; 0x94
> > 27102-
> > 27103- /*
> > 27104- * Set callbacks
> > 27105- */
> > 27106- if (device_node != NULL) {
> > 27107- 6ccc: 2b00 cmp r3, #0
> > 27108- 6cce: f000 80e9 beq.w 6ea4
> > <rtems_termios_open_tty+0x310>
> > 27109- device_node->tty = tty;
> > 27110- tty->handler = *device_node->handler;
> > 27111- 6cd2: f104 0cb8 add.w ip, r4, #184 ; 0xb8
> > 27112- 6cd6: 4666 mov r6, ip
> > --
> > 29226- /* disable interrupts */
> > 29227- rtems_termios_device_lock_acquire (ctx, &lock_context);
> > 29228- tty->flow_ctrl &= ~FL_OSTOP;
> > 29229- 7442: f8d4 30d8 ldr.w r3, [r4, #216] ; 0xd8
> > 29230- /* check for chars in output buffer (or rob_state?) */
> > 29231: if (tty->rawOutBufState != rob_idle) {
> > 29232- 7446: f894 2094 ldrb.w r2, [r4, #148] ; 0x94
> > 29233-
> > 29234- /* has output been stopped due to received XOFF? */
> > 29235- if (tty->flow_ctrl & FL_OSTOP) {
> > 29236- /* disable interrupts */
> > 29237- rtems_termios_device_lock_acquire (ctx, &lock_context);
> > 29238- tty->flow_ctrl &= ~FL_OSTOP;
> > 29239- 744a: f023 0320 bic.w r3, r3, #32
> > 29240- 744e: f8c4 30d8 str.w r3, [r4, #216] ; 0xd8
> > 29241- /* check for chars in output buffer (or rob_state?) */
> > 29242: if (tty->rawOutBufState != rob_idle) {
> > 29243- 7452: 2a00 cmp r2, #0
> > 29244- 7454: f040 80cf bne.w 75f6
> <rtems_termios_ioctl+0x306>
> > 29245- ARM_SWITCH_BACK
> > 29246- : ARM_SWITCH_OUTPUT
> > 29247- : [level] "r" (level)
> > 29248- );
> > 29249-#elif defined(ARM_MULTILIB_ARCH_V7M)
> > 29250- __asm__ volatile (
> > 29251- 7458: f387 8811 msr BASEPRI, r7
> > 29252- /* reenable interrupts */
> > 29253- rtems_termios_device_lock_release (ctx, &lock_context);
> > 29254- }
> > --
> > 29492-
> > 29493- rtems_termios_device_lock_acquire (ctx, &lock_context);
> > 29494- tty->rawOutBuf.Tail = 0;
> > 29495- 7572: f8c4 0084 str.w r0, [r4, #132] ; 0x84
> > 29496- tty->rawOutBuf.Head = 0;
> > 29497: tty->rawOutBufState = rob_idle;
> > 29498- 7576: f884 0094 strb.w r0, [r4, #148] ; 0x94
> > 29499- rtems_termios_device_context *ctx = tty->device_context;
> > 29500- rtems_interrupt_lock_context lock_context;
> > 29501-
> > 29502- rtems_termios_device_lock_acquire (ctx, &lock_context);
> > 29503- tty->rawOutBuf.Tail = 0;
> > 29504- tty->rawOutBuf.Head = 0;
> > 29505- 757a: f8c4 0080 str.w r0, [r4, #128] ; 0x80
> > 29506- ARM_SWITCH_BACK
> > 29507- : ARM_SWITCH_OUTPUT
> > 29508- : [level] "r" (level)
> > 29509- );
> > --
> > 29562-
> > 29563- rtems_termios_device_lock_acquire (ctx, &lock_context);
> > 29564- tty->rawOutBuf.Tail = 0;
> > 29565- 75b0: f8c4 0084 str.w r0, [r4, #132] ; 0x84
> > 29566- tty->rawOutBuf.Head = 0;
> > 29567: tty->rawOutBufState = rob_idle;
> > 29568- 75b4: f884 0094 strb.w r0, [r4, #148] ; 0x94
> > 29569- rtems_termios_device_context *ctx = tty->device_context;
> > 29570- rtems_interrupt_lock_context lock_context;
> > 29571-
> > 29572- rtems_termios_device_lock_acquire (ctx, &lock_context);
> > 29573- tty->rawOutBuf.Tail = 0;
> > 29574- tty->rawOutBuf.Head = 0;
> > 29575- 75b8: f8c4 0080 str.w r0, [r4, #128] ; 0x80
> > 29576- ARM_SWITCH_BACK
> > 29577- : ARM_SWITCH_OUTPUT
> > 29578- : [level] "r" (level)
> > 29579- );
> > --
> > 29629- 75f0: 2301 movs r3, #1
> > 29630- 75f2: 66e3 str r3, [r4, #108] ; 0x6c
> > 29631- 75f4: e77e b.n 74f4
> <rtems_termios_ioctl+0x204>
> > 29632- tty->flow_ctrl &= ~FL_OSTOP;
> > 29633- /* check for chars in output buffer (or rob_state?) */
> > 29634: if (tty->rawOutBufState != rob_idle) {
> > 29635- /* if chars available, call write function... */
> > 29636- (*tty->handler.write)(
> > 29637- ctx, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
> > 29638- 75f6: f8d4 2084 ldr.w r2, [r4, #132] ; 0x84
> > 29639- rtems_termios_device_lock_acquire (ctx, &lock_context);
> > 29640- tty->flow_ctrl &= ~FL_OSTOP;
> > 29641- /* check for chars in output buffer (or rob_state?) */
> > 29642: if (tty->rawOutBufState != rob_idle) {
> > 29643- /* if chars available, call write function... */
> > 29644- (*tty->handler.write)(
> > 29645- 75fa: 6fe1 ldr r1, [r4, #124] ; 0x7c
> > 29646- 75fc: f8d4 30c4 ldr.w r3, [r4, #196] ; 0xc4
> > 29647- 7600: 4411 add r1, r2
> > 29648- 7602: 4628 mov r0, r5
> > 29649- 7604: 2201 movs r2, #1
> > 29650- 7606: 4798 blx r3
> > 29651- 7608: e726 b.n 7458
> <rtems_termios_ioctl+0x168>
> > 29652- 760a: bf00 nop
> > 29653-
> > 29654-0000760c <rtems_termios_puts>:
> > --
> > 29815- 76b2: bf24 itt cs
> > 29816- 76b4: f8d4 2088 ldrcs.w r2, [r4, #136] ; 0x88
> > 29817- 76b8: 1a9b subcs r3, r3, r2
> > 29818- tty->rawOutBuf.Head = newHead;
> > 29819-
> > 29820: if (tty->rawOutBufState == rob_idle) {
> > 29821- 76ba: f894 2094 ldrb.w r2, [r4, #148] ; 0x94
> > 29822- memcpy(&tty->rawOutBuf.theBuf[tty->rawOutBuf.Head], buf,
> nToCopy);
> > 29823-
> > 29824- newHead = tty->rawOutBuf.Head + nToCopy;
> > 29825- if (newHead >= tty->rawOutBuf.Size)
> > 29826- newHead -= tty->rawOutBuf.Size;
> > 29827- tty->rawOutBuf.Head = newHead;
> > 29828- 76be: f8c4 3080 str.w r3, [r4, #128] ; 0x80
> > 29829-
> > 29830: if (tty->rawOutBufState == rob_idle) {
> > 29831- 76c2: b192 cbz r2, 76ea
> <rtems_termios_puts+0xde>
> > 29832- ARM_SWITCH_BACK
> > 29833- : ARM_SWITCH_OUTPUT
> > 29834- : [level] "r" (level)
> > 29835- );
> > 29836-#elif defined(ARM_MULTILIB_ARCH_V7M)
> > 29837- __asm__ volatile (
> > 29838- 76c4: f385 8811 msr BASEPRI, r5
> > 29839- if (tty->handler.mode == TERMIOS_POLLED) {
> > 29840- (*tty->handler.write)(ctx, buf, len);
> > 29841- return;
> > 29842- }
> > --
> > 29885- 76e8: e7d2 b.n 7690 <rtems_termios_puts+0x84>
> > 29886- if (newHead >= tty->rawOutBuf.Size)
> > 29887- newHead -= tty->rawOutBuf.Size;
> > 29888- tty->rawOutBuf.Head = newHead;
> > 29889-
> > 29890: if (tty->rawOutBufState == rob_idle) {
> > 29891- startXmit (tty, tty->rawOutBuf.Tail, false);
> > 29892- 76ea: f8d4 1084 ldr.w r1, [r4, #132] ; 0x84
> > 29893- 76ee: 4620 mov r0, r4
> > 29894- 76f0: f7ff f8ca bl 6888 <startXmit>
> > 29895- 76f4: e7e6 b.n 76c4 <rtems_termios_puts+0xb8>
> > 29896- rtems_termios_device_context *ctx = tty->device_context;
> > 29897- rtems_interrupt_lock_context lock_context;
> > 29898- rtems_status_code sc;
> > 29899-
> > 29900- if (tty->handler.mode == TERMIOS_POLLED) {
> > 29901- (*tty->handler.write)(ctx, buf, len);
> > 29902- 76f6: f8d2 30c4 ldr.w r3, [r2, #196] ; 0xc4
> > --
> > 31283- while ((tty->rawInBuf.Head != tty->rawInBuf.Tail) &&
> > 31284- 7be4: 428a cmp r2, r1
> > 31285- 7be6: f04f 0501 mov.w r5, #1
> > 31286- 7bea: d968 bls.n 7cbe
> <rtems_termios_read+0x1a6>
> > 31287- == (FL_MDXON | FL_ISNTXOF))
> > 31288: && ((tty->rawOutBufState == rob_idle)
> > 31289- || (tty->flow_ctrl & FL_OSTOP))) {
> > 31290- /* XON should be sent now... */
> > 31291- (*tty->handler.write)(
> > 31292- tty->device_context, (void
> > *)&(tty->termios.c_cc[VSTART]), 1);
> > 31293- 7bec: f104 0849 add.w r8, r4, #73 ; 0x49
> > 31294- 7bf0: e012 b.n 7c18
> <rtems_termios_read+0x100>
> > 31295-
> > 31296- rtems_termios_device_lock_release (ctx, &lock_context);
> > 31297-
> > 31298- /* continue processing new character */
> > 31299- if (tty->termios.c_lflag & ICANON) {
> > 31300- if (siproc (c, tty))
> > --
> > 31401- if (((tty->flow_ctrl & (FL_MDXON | FL_ISNTXOF))
> > 31402- 7c56: f8d4 20d8 ldr.w r2, [r4, #216] ; 0xd8
> > 31403- 7c5a: 4013 ands r3, r2
> > 31404- 7c5c: 4553 cmp r3, sl
> > 31405- 7c5e: d01e beq.n 7c9e
> <rtems_termios_read+0x186>
> > 31406: && ((tty->rawOutBufState == rob_idle)
> > 31407- || (tty->flow_ctrl & FL_OSTOP))) {
> > 31408- /* XON should be sent now... */
> > 31409- (*tty->handler.write)(
> > 31410- tty->device_context, (void
> > *)&(tty->termios.c_cc[VSTART]), 1);
> > 31411- } else if (tty->flow_ctrl & FL_MDRTS) {
> > 31412- 7c60: f8d4 30d8 ldr.w r3, [r4, #216] ; 0xd8
> > 31413- 7c64: 05da lsls r2, r3, #23
> > 31414- 7c66: d50b bpl.n 7c80
> <rtems_termios_read+0x168>
> > 31415- tty->flow_ctrl &= ~FL_IRTSOFF;
> > 31416- 7c68: f8d4 30d8 ldr.w r3, [r4, #216] ; 0xd8
> > 31417- /* activate RTS line */
> > 31418- if (tty->flow.start_remote_tx != NULL) {
> > --
> > 31477- < tty->lowwater) {
> > 31478- tty->flow_ctrl &= ~FL_IREQXOF;
> > 31479- /* if tx stopped and XON should be sent... */
> > 31480- if (((tty->flow_ctrl & (FL_MDXON | FL_ISNTXOF))
> > 31481- == (FL_MDXON | FL_ISNTXOF))
> > 31482: && ((tty->rawOutBufState == rob_idle)
> > 31483- 7c9e: f894 3094 ldrb.w r3, [r4, #148] ; 0x94
> > 31484- 7ca2: b11b cbz r3, 7cac
> <rtems_termios_read+0x194>
> > 31485- || (tty->flow_ctrl & FL_OSTOP))) {
> > 31486- 7ca4: f8d4 30d8 ldr.w r3, [r4, #216] ; 0xd8
> > 31487- 7ca8: 0699 lsls r1, r3, #26
> > 31488- 7caa: d5d9 bpl.n 7c60
> <rtems_termios_read+0x148>
> > 31489- /* XON should be sent now... */
> > 31490- (*tty->handler.write)(
> > 31491- 7cac: f8d4 30c4 ldr.w r3, [r4, #196] ; 0xc4
> > 31492- 7cb0: f8d4 010c ldr.w r0, [r4, #268] ; 0x10c
> > 31493- 7cb4: 4641 mov r1, r8
> > 31494- 7cb6: 2201 movs r2, #1
> > --
> > 32101- /* disable interrupts */
> > 32102- rtems_termios_device_lock_acquire (ctx, &lock_context);
> > 32103- tty->flow_ctrl &= ~FL_OSTOP;
> > 32104- 7f34: f8d4 30d8 ldr.w r3, [r4, #216] ; 0xd8
> > 32105- /* check for chars in output buffer (or rob_state?) */
> > 32106: if (tty->rawOutBufState != rob_idle) {
> > 32107- 7f38: f894 2094 ldrb.w r2, [r4, #148] ; 0x94
> > 32108- if (flow_rcv) {
> > 32109- /* restart output according to FL_ORCVXOF flag */
> > 32110- if ((tty->flow_ctrl & (FL_ORCVXOF | FL_OSTOP)) ==
> FL_OSTOP) {
> > 32111- /* disable interrupts */
> > 32112- rtems_termios_device_lock_acquire (ctx, &lock_context);
> > 32113- tty->flow_ctrl &= ~FL_OSTOP;
> > 32114- 7f3c: f023 0320 bic.w r3, r3, #32
> > 32115- 7f40: f8c4 30d8 str.w r3, [r4, #216] ; 0xd8
> > 32116- /* check for chars in output buffer (or rob_state?) */
> > 32117: if (tty->rawOutBufState != rob_idle) {
> > 32118- 7f44: b94a cbnz r2, 7f5a
> > <rtems_termios_enqueue_raw_characters+0x1ca>
> > 32119- ARM_SWITCH_BACK
> > 32120- : ARM_SWITCH_OUTPUT
> > 32121- : [level] "r" (level)
> > 32122- );
> > 32123-#elif defined(ARM_MULTILIB_ARCH_V7M)
> > 32124- __asm__ volatile (
> > 32125- 7f46: f386 8811 msr BASEPRI, r6
> > 32126- 7f4a: 2601 movs r6, #1
> > 32127- 7f4c: e760 b.n 7e10
> > <rtems_termios_enqueue_raw_characters+0x80>
> > 32128- if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn !=
> > NULL )) {
> > 32129- (*tty->tty_rcv.sw_pfn)(&tty->termios,
> tty->tty_rcv.sw_arg);
> > --
> > 32136- 7f52: 9300 str r3, [sp, #0]
> > 32137- 7f54: f38a 8811 msr BASEPRI, sl
> > 32138- 7f58: e75a b.n 7e10
> > <rtems_termios_enqueue_raw_characters+0x80>
> > 32139- tty->flow_ctrl &= ~FL_OSTOP;
> > 32140- /* check for chars in output buffer (or rob_state?) */
> > 32141: if (tty->rawOutBufState != rob_idle) {
> > 32142- /* if chars available, call write function... */
> > 32143- (*tty->handler.write)(
> > 32144- ctx,
> &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1);
> > 32145- 7f5a: f8d4 2084 ldr.w r2, [r4, #132] ; 0x84
> > 32146- rtems_termios_device_lock_acquire (ctx, &lock_context);
> > 32147- tty->flow_ctrl &= ~FL_OSTOP;
> > 32148- /* check for chars in output buffer (or rob_state?) */
> > 32149: if (tty->rawOutBufState != rob_idle) {
> > 32150- /* if chars available, call write function... */
> > 32151- (*tty->handler.write)(
> > 32152- 7f5e: 6fe1 ldr r1, [r4, #124] ; 0x7c
> > 32153- 7f60: f8d4 30c4 ldr.w r3, [r4, #196] ; 0xc4
> > 32154- 7f64: 4411 add r1, r2
> > 32155- 7f66: 4658 mov r0, fp
> > 32156- 7f68: 2201 movs r2, #1
> > 32157- 7f6a: f8cd c004 str.w ip, [sp, #4]
> > 32158- 7f6e: 4798 blx r3
> > 32159- 7f70: f8dd c004 ldr.w ip, [sp, #4]
> > 32160- 7f74: e7e7 b.n 7f46
> > <rtems_termios_enqueue_raw_characters+0x1b6>
> > 32161- + tty->rawInBuf.Size) % tty->rawInBuf.Size) >
> > tty->highwater)) {
> > --
> > 32167- 7f76: 0692 lsls r2, r2, #26
> > 32168- 7f78: d403 bmi.n 7f82
> > <rtems_termios_enqueue_raw_characters+0x1f2>
> > 32169- 7f7a: f894 2094 ldrb.w r2, [r4, #148] ; 0x94
> > 32170- 7f7e: 2a00 cmp r2, #0
> > 32171- 7f80: d18c bne.n 7e9c
> > <rtems_termios_enqueue_raw_characters+0x10c>
> > 32172: (tty->rawOutBufState == rob_idle)) {
> > 32173- /* if tx is stopped due to XOFF or out of data */
> > 32174- /* call write function here */
> > 32175- tty->flow_ctrl |= FL_ISNTXOF;
> > 32176- 7f82: f8d4 20d8 ldr.w r2, [r4, #216] ; 0xd8
> > 32177- 7f86: 9301 str r3, [sp, #4]
> > 32178- 7f88: f042 0202 orr.w r2, r2, #2
> > 32179- 7f8c: f8c4 20d8 str.w r2, [r4, #216] ; 0xd8
> > 32180- (*tty->handler.write)(ctx,
> > 32181- 7f90: f8d4 30c4 ldr.w r3, [r4, #196] ; 0xc4
> > 32182- 7f94: 4658 mov r0, fp
> > 32183- 7f96: f104 014a add.w r1, r4, #74 ; 0x4a
> > 32184- 7f9a: 2201 movs r2, #1
> > --
> > 38521- 9512: f000 f825 bl 9560
> > <_Extension_Manager_initialization>
> > 38522-
> > 38523- _POSIX_API_Initialize();
> > 38524- 9516: f000 f863 bl 95e0 <_POSIX_API_Initialize>
> > 38525- 951a: 7025 strb r5, [r4, #0]
> > 38526: _Thread_Create_idle();
> > 38527-
> > 38528- /*
> > 38529- * Scheduling can properly occur now as long as we avoid
> > dispatching.
> > 38530- */
> > 38531-}
> > 38532- 951c: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr}
> > 38533- * _Thread_Executing and _Thread_Heir are not set.
> > 38534- *
> > 38535- * At this point all API extensions are in place. After the
> > call to
> > 38536: * _Thread_Create_idle() _Thread_Executing and _Thread_Heir
> > will be set.
> > 38537- */
> > 38538: _Thread_Create_idle();
> > 38539: 9520: f002 ba3a b.w b998 <_Thread_Create_idle>
> > 38540- 9524: 20004618 .word 0x20004618
> > 38541- 9528: 20004640 .word 0x20004640
> > 38542- 952c: 200041d0 .word 0x200041d0
> > 38543- 9530: 200041e0 .word 0x200041e0
> > 38544- 9534: 2000429c .word 0x2000429c
> > 38545- 9538: 20004298 .word 0x20004298
> > 38546-
> > 38547-0000953c <rtems_initialize_before_drivers>:
> > 38548- * Scheduling can properly occur now as long as we avoid
> > dispatching.
> > 38549- */
> > 38550-}
> > 38551-
> > --
> > 48137-)
> > 48138-{
> > 48139- b3c4: 4770 bx lr
> > 48140- b3c6: bf00 nop
> > 48141-
> > 48142:0000b3c8 <_Scheduler_default_Start_idle>:
> > 48143-#if defined(RTEMS_SMP)
> > 48144- Thread_Control *needs_help;
> > 48145-
> > 48146- needs_help =
> > 48147-#endif
> > 48148- ( *scheduler->Operations.unblock )( scheduler, the_thread );
> > 48149: b3c8: 4801 ldr r0, [pc, #4] ; (b3d0
> > <_Scheduler_default_Start_idle+0x8>)
> > 48150- b3ca: 6943 ldr r3, [r0, #20]
> > 48151- b3cc: 4718 bx r3
> > 48152- b3ce: bf00 nop
> > 48153- b3d0: 0001847c .word 0x0001847c
> > 48154-
> > 48155-0000b3d4 <_Scheduler_default_Tick>:
> > 48156- /*
> > 48157- * If the thread is not preemptible or is not ready, then
> > 48158- * just return.
> > 48159- */
> > 48160-
> > 48161- if ( !executing->is_preemptible )
> > --
> > 49735- b988: 0001847c .word 0x0001847c
> > 49736- b98c: 0001d828 .word 0x0001d828
> > 49737- b990: 0001d814 .word 0x0001d814
> > 49738- b994: 0001d878 .word 0x0001d878
> > 49739-
> > 49740:0000b998 <_Thread_Create_idle>:
> > 49741- cpu
> > 49742- );
> > 49743-}
> > 49744-
> > 49745:void _Thread_Create_idle( void )
> > 49746-{
> > 49747- b998: b5f0 push {r4, r5, r6, r7, lr}
> > 49748- return maximum_internal_threads;
> > 49749-}
> > 49750-
> > 49751-RTEMS_INLINE_ROUTINE Thread_Control
> *_Thread_Internal_allocate( void )
> > 49752-{
> > 49753- return (Thread_Control *)
> > 49754: b99a: 4f17 ldr r7, [pc, #92] ; (b9f8
> > <_Thread_Create_idle+0x60>)
> > 49755- b99c: b089 sub sp, #36 ; 0x24
> > 49756- b99e: 4638 mov r0, r7
> > 49757- b9a0: f7fe ff74 bl a88c
> <_Objects_Allocate_unprotected>
> > 49758- _Thread_Initialize(
> > 49759- &_Thread_Internal_information,
> > 49760: idle,
> > 49761- _Scheduler_Get_by_CPU( cpu ),
> > 49762- NULL, /* allocate the stack */
> > 49763: _Stack_Ensure_minimum(
> > rtems_configuration_get_idle_task_stack_size() ),
> > 49764: b9a4: 4e15 ldr r6, [pc, #84] ; (b9fc
> > <_Thread_Create_idle+0x64>)
> > 49765- *
> > 49766- * @return This method returns the minimum stack size;
> > 49767- */
> > 49768-RTEMS_INLINE_ROUTINE uint32_t _Stack_Minimum (void)
> > 49769-{
> > 49770- return rtems_minimum_stack_size;
> > 49771: b9a6: 4a16 ldr r2, [pc, #88] ; (ba00
> > <_Thread_Create_idle+0x68>)
> > 49772- b9a8: 6a73 ldr r3, [r6, #36] ; 0x24
> > 49773- b9aa: 6811 ldr r1, [r2, #0]
> > 49774- b9ac: 4605 mov r5, r0
> > 49775- b9ae: 428b cmp r3, r1
> > 49776- b9b0: bf38 it cc
> > 49777- b9b2: 460b movcc r3, r1
> > 49778- * fields not explicitly assigned were explicitly zeroed by
> > 49779- * _Workspace_Initialization.
> > 49780- */
> > 49781: idle = _Thread_Internal_allocate();
> > 49782-
> > 49783- _Thread_Initialize(
> > 49784: b9b4: 4a13 ldr r2, [pc, #76] ; (ba04
> > <_Thread_Create_idle+0x6c>)
> > 49785:static void _Thread_Create_idle_for_cpu( Per_CPU_Control *cpu )
> > 49786-{
> > 49787- Objects_Name name;
> > 49788: Thread_Control *idle;
> > 49789-
> > 49790- name.name_u32 = _Objects_Build_name( 'I', 'D', 'L', 'E' );
> > 49791: b9b6: f8df e058 ldr.w lr, [pc, #88] ; ba10
> > <_Thread_Create_idle+0x78>
> > 49792- * fields not explicitly assigned were explicitly zeroed by
> > 49793- * _Workspace_Initialization.
> > 49794- */
> > 49795: idle = _Thread_Internal_allocate();
> > 49796-
> > 49797- _Thread_Initialize(
> > 49798- b9ba: 7811 ldrb r1, [r2, #0]
> > 49799- b9bc: 2400 movs r4, #0
> > 49800- b9be: 2201 movs r2, #1
> > 49801- b9c0: 9300 str r3, [sp, #0]
> > 49802- b9c2: 9102 str r1, [sp, #8]
> > 49803- b9c4: f8cd e01c str.w lr, [sp, #28]
> > 49804- b9c8: 4629 mov r1, r5
> > 49805- b9ca: 4623 mov r3, r4
> > 49806- b9cc: 9203 str r2, [sp, #12]
> > 49807- b9ce: 4638 mov r0, r7
> > 49808- b9d0: 9401 str r4, [sp, #4]
> > 49809- b9d2: 9404 str r4, [sp, #16]
> > 49810- b9d4: 9405 str r4, [sp, #20]
> > 49811- b9d6: 9406 str r4, [sp, #24]
> > 49812: b9d8: 4a0b ldr r2, [pc, #44] ; (ba08
> > <_Thread_Create_idle+0x70>)
> > 49813- b9da: f000 f96d bl bcb8 <_Thread_Initialize>
> > 49814- * MUST be done before _Thread_Start is invoked.
> > 49815- */
> > 49816- cpu->heir =
> > 49817: cpu->executing = idle;
> > 49818-
> > 49819- _Thread_Start(
> > 49820- b9de: 6a32 ldr r2, [r6, #32]
> > 49821- /*
> > 49822- * WARNING!!! This is necessary to "kick" start the
> system and
> > 49823- * MUST be done before _Thread_Start is invoked.
> > 49824- */
> > 49825- cpu->heir =
> > 49826: cpu->executing = idle;
> > 49827: b9e0: 4e0a ldr r6, [pc, #40] ; (ba0c
> > <_Thread_Create_idle+0x74>)
> > 49828-
> > 49829- _Thread_Start(
> > 49830- b9e2: 9400 str r4, [sp, #0]
> > 49831- b9e4: 9601 str r6, [sp, #4]
> > 49832- b9e6: 4628 mov r0, r5
> > 49833- b9e8: 4621 mov r1, r4
> > 49834- b9ea: 4623 mov r3, r4
> > 49835- /*
> > 49836- * WARNING!!! This is necessary to "kick" start the
> system and
> > 49837- * MUST be done before _Thread_Start is invoked.
> > 49838- */
> > 49839- cpu->heir =
> > 49840: cpu->executing = idle;
> > 49841- b9ec: 60b5 str r5, [r6, #8]
> > 49842-
> > 49843- /*
> > 49844- * WARNING!!! This is necessary to "kick" start the
> system and
> > 49845- * MUST be done before _Thread_Start is invoked.
> > 49846- */
> > 49847- cpu->heir =
> > 49848- b9ee: 60f5 str r5, [r6, #12]
> > 49849: cpu->executing = idle;
> > 49850-
> > 49851- _Thread_Start(
> > 49852- b9f0: f000 fee0 bl c7b4 <_Thread_Start>
> > 49853-
> > 49854- if ( _Per_CPU_Is_processor_started( cpu ) ) {
> > 49855: _Thread_Create_idle_for_cpu( cpu );
> > 49856- }
> > 49857- }
> > 49858-}
> > 49859- b9f4: b009 add sp, #36 ; 0x24
> > 49860- b9f6: bdf0 pop {r4, r5, r6, r7, pc}
> > 49861- b9f8: 200042c0 .word 0x200042c0
> > 49862- b9fc: 000183c0 .word 0x000183c0
> > 49863- ba00: 200011c0 .word 0x200011c0
> > 49864- ba04: 200011bc .word 0x200011bc
> > 49865- ba08: 0001847c .word 0x0001847c
> > 49866- ba0c: 20004640 .word 0x20004640
> > 49867- ba10: 49444c45 .word 0x49444c45
> > --
> > 54093- const Scheduler_Control *scheduler,
> > 54094- Thread_Control *the_thread,
> > 54095- Per_CPU_Control *cpu
> > 54096-)
> > 54097-{
> > 54098: ( *scheduler->Operations.start_idle )( scheduler,
> the_thread, cpu );
> > 54099- c7de: 4809 ldr r0, [pc, #36] ; (c804
> > <_Thread_Start+0x50>)
> > 54100- _Thread_Ready( the_thread );
> > 54101- } else {
> > 54102- const Scheduler_Control *scheduler =
> _Scheduler_Get_by_CPU(
> > cpu );
> > 54103-
> > 54104- if ( scheduler != NULL ) {
> > 54105- the_thread->current_state = STATES_READY;
> > 54106- c7e0: 2200 movs r2, #0
> > 54107- c7e2: 612a str r2, [r5, #16]
> > 54108- c7e4: 6b43 ldr r3, [r0, #52] ; 0x34
> > 54109- c7e6: 4629 mov r1, r5
> > 54110- c7e8: 9a05 ldr r2, [sp, #20]
> >
> > On Wed, Apr 24, 2019 at 2:59 PM Christian Mauderer
> > <christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>
> > <mailto:christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>>> wrote:
> >
> > Am 24.04.19 um 02:35 schrieb Jython:
> > > yes, I need to do low power for stm32f4
> > > will this line work __asm__ volatile ("wfi");?
> >
> > That line should be correct. Please note that the instruction
> is already
> > used in the armv7 idle thread:
> >
> >
> https://git.rtems.org/rtems/tree/cpukit/score/cpu/arm/armv7-thread-idle.c#n32
> >
> > The stm32f4 is a Cortex-M4 so it's quite likely that this
> routine is
> > used. You can check by doing an "arm-rtems5-objdump -dS" on
> your file
> > and search for the idle body.
> >
> > With kind regards
> >
> > Christian
> >
> > >
> > >
> > > On Tue, Apr 23, 2019 at 10:28 PM Christian Mauderer
> > > <christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>
> > <mailto:christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>>
> > > <mailto:christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>
> > <mailto:christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>>>> wrote:
> > >
> > > Am 22.04.19 um 09:47 schrieb Jython:
> > > > HI, ALL!
> > > > wfi
> > >
> >
> http://www.keil.com/support/man/docs/armcc/armcc_chr1359125004400.htm
> > > > how can i call the arm __wfi?
> > > >
> > > > _______________________________________________
> > > > users mailing list
> > > > users at rtems.org <mailto:users at rtems.org>
> <mailto:users at rtems.org <mailto:users at rtems.org>>
> > <mailto:users at rtems.org <mailto:users at rtems.org>
> <mailto:users at rtems.org <mailto:users at rtems.org>>>
> > > > http://lists.rtems.org/mailman/listinfo/users
> > > >
> > >
> > > Hello Jython,
> > >
> > > WFI is an assembler instruction. The Keil wrapper isn't
> > available in
> > > gcc. I know of no direct replacement. Most likely you need a
> > gcc inline
> > > assembly for that.
> > >
> > > May I ask why you would need "wfi"? If you use a operating
> > system, the
> > > system typically handles such low level stuff for you.
> The only
> > > application that springs to mind for that instruction is
> > overwriting the
> > > idle loop to save energy.
> > >
> > > Best regards
> > >
> > > Christian
> > >
> > > --
> > > --------------------------------------------
> > > embedded brains GmbH
> > > Herr Christian Mauderer
> > > Dornierstr. 4
> > > D-82178 Puchheim
> > > Germany
> > > email: christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>
> > <mailto:christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>>
> > > <mailto:christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>
> > <mailto:christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>>>
> > > Phone: +49-89-18 94 741 - 18
> > > Fax: +49-89-18 94 741 - 08
> > > PGP: Public key available on request.
> > >
> > > Diese Nachricht ist keine geschäftliche Mitteilung im Sinne
> > des EHUG.
> > >
> >
> > --
> > --------------------------------------------
> > embedded brains GmbH
> > Herr Christian Mauderer
> > Dornierstr. 4
> > D-82178 Puchheim
> > Germany
> > email: christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>
> > <mailto:christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>>
> > Phone: +49-89-18 94 741 - 18
> > Fax: +49-89-18 94 741 - 08
> > PGP: Public key available on request.
> >
> > Diese Nachricht ist keine geschäftliche Mitteilung im Sinne
> des EHUG.
> >
>
> --
> --------------------------------------------
> embedded brains GmbH
> Herr Christian Mauderer
> Dornierstr. 4
> D-82178 Puchheim
> Germany
> email: christian.mauderer at embedded-brains.de
> <mailto:christian.mauderer at embedded-brains.de>
> Phone: +49-89-18 94 741 - 18
> Fax: +49-89-18 94 741 - 08
> PGP: Public key available on request.
>
> Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
>
--
--------------------------------------------
embedded brains GmbH
Herr Christian Mauderer
Dornierstr. 4
D-82178 Puchheim
Germany
email: christian.mauderer at embedded-brains.de
Phone: +49-89-18 94 741 - 18
Fax: +49-89-18 94 741 - 08
PGP: Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
More information about the users
mailing list