µGFX library fork

gos_x_threads_cortexm347.h 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * This file is subject to the terms of the GFX License. If a copy of
  3. * the license was not distributed with this file, you can obtain one at:
  4. *
  5. * http://ugfx.org/license.html
  6. */
  7. /**
  8. * Thread Switching Functions for the Cortex M3, M4 & M7 without hardware floating point
  9. *
  10. * Use the EABI calling standard (ARM's AAPCS) - Save r4 - r11
  11. * The context is saved at the current stack location and a pointer is maintained in the thread structure.
  12. */
  13. #if CORTEX_USE_FPU
  14. #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT
  15. #warning "GOS Threads: You have specified GFX_CPU=GFX_CPU_CORTX_M? with no hardware floating point support but CORTEX_USE_FPU is TRUE. Try using GFX_CPU_GFX_CPU_CORTEX_M?_FP instead"
  16. #elif GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_MACRO
  17. COMPILER_WARNING("GOS Threads: You have specified GFX_CPU=GFX_CPU_CORTX_M? with no hardware floating point support but CORTEX_USE_FPU is TRUE. Try using GFX_CPU_GFX_CPU_CORTEX_M?_FP instead")
  18. #endif
  19. #endif
  20. #if GFX_COMPILER == GFX_COMPILER_GCC || GFX_COMPILER == GFX_COMPILER_CYGWIN || GFX_COMPILER == GFX_COMPILER_MINGW32 || GFX_COMPILER == GFX_COMPILER_MINGW64
  21. #define GFX_THREADS_DONE
  22. #define _gfxThreadsInit()
  23. static __attribute__((pcs("aapcs"),naked)) void _gfxTaskSwitch(thread *oldt, thread *newt) {
  24. __asm__ volatile ( "push {r4, r5, r6, r7, r8, r9, r10, r11, lr} \n\t"
  25. "str sp, %[oldtcxt] \n\t"
  26. "ldr sp, %[newtcxt] \n\t"
  27. "pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} \n\t"
  28. : [newtcxt] "=m" (newt->cxt)
  29. : [oldtcxt] "m" (oldt->cxt)
  30. : "memory");
  31. }
  32. static __attribute__((pcs("aapcs"),naked)) void _gfxStartThread(thread *oldt, thread *newt) {
  33. newt->cxt = (void *)(((unsigned)newt + newt->size) & ~7);
  34. __asm__ volatile ( "push {r4, r5, r6, r7, r8, r9, r10, r11, lr} \n\t"
  35. "str sp, %[oldtcxt] \n\t"
  36. "ldr sp, %[newtcxt] \n\t"
  37. : [newtcxt] "=m" (newt->cxt)
  38. : [oldtcxt] "m" (oldt->cxt)
  39. : "memory");
  40. // Run the users function
  41. gfxThreadExit(_gfxCurrentThread->fn(_gfxCurrentThread->param));
  42. }
  43. #elif GFX_COMPILER == GFX_COMPILER_KEIL || GFX_COMPILER == GFX_COMPILER_ARMCC
  44. #define GFX_THREADS_DONE
  45. #define _gfxThreadsInit()
  46. static __asm void _gfxTaskSwitch(thread *oldt, thread *newt) {
  47. PRESERVE8
  48. // Save the old context
  49. push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
  50. str sp, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt
  51. // Load the new context
  52. ldr sp, [r1,#__cpp(offsetof(thread,cxt))] // newt->cxt
  53. pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
  54. }
  55. static __asm void _gfxStartThread(thread *oldt, thread *newt) {
  56. PRESERVE8
  57. // Calculate where to generate the new context
  58. // newt->cxt = (void *)(((unsigned)newt + newt->size) & ~7);
  59. ldr r2,[r1,#__cpp(offsetof(thread,size))]
  60. add r2,r2,r1
  61. and r2, r2, #0xFFFFFFF8
  62. str r2,[r1,#__cpp(offsetof(thread,cxt))]
  63. // Save the old context
  64. push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
  65. str sp, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt
  66. // Load the new (imcomplete) context
  67. ldr sp, [r1,#__cpp(offsetof(thread,cxt))] // newt->cxt
  68. // Run the users function - we save some code because gfxThreadExit() never returns
  69. // gfxThreadExit(_gfxCurrentThread->fn(_gfxCurrentThread->param));
  70. ldr r2,=__cpp(&_gfxCurrentThread)
  71. ldr r2,[r2,#0]
  72. ldr r0,[r2,#__cpp(offsetof(thread,param))]
  73. ldr r1,[r2,#__cpp(offsetof(thread,fn))]
  74. blx r1
  75. mov r4,r0
  76. bl __cpp(gfxThreadExit)
  77. ALIGN
  78. }
  79. #else
  80. #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT
  81. #warning "GOS Threads: You have specified a specific CPU but your compiler is not supported. Defaulting to CLIB switching"
  82. #elif GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_MACRO
  83. COMPILER_WARNING("GOS Threads: You have specified a specific CPU but your compiler is not supported. Defaulting to CLIB switching")
  84. #endif
  85. #endif