久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5082|回復: 0
打印 上一主題 下一主題
收起左側

ARM SVC模式源碼

[復制鏈接]
跳轉到指定樓層
樓主
ID:487325 發表于 2019-3-9 12:35 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
采用svc模式可以將SDK(API)和Application分離, 也可以省略很多重復的代碼,比如在bootload中用到了usb, 然后在application中想復用的話,可以用svc
原理: 類似軟件中斷,中添加了一個軟件中斷源,通過中斷源表明調用的函數接口

源程序如下:
  1. #ifndef NRF_SVC__
  2. #define NRF_SVC__

  3. #ifdef SVCALL_AS_NORMAL_FUNCTION
  4. #define SVCALL(number, return_type, signature) return_type signature
  5. #else

  6. #ifndef SVCALL
  7. #if defined (__CC_ARM)
  8. #define SVCALL(number, return_type, signature) return_type __svc(number) signature
  9. #elif defined (__GNUC__)
  10. #define SVCALL(number, return_type, signature) \
  11.   _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \
  12.   _Pragma("GCC diagnostic push") \
  13.   _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
  14.   __attribute__((naked)) static return_type signature \
  15.   { \
  16.     __asm( \
  17.         "svc %0\n" \
  18.         "bx r14" : : "I" (number) : "r0" \
  19.     ); \
  20.   }    \
  21.   _Pragma("GCC diagnostic pop")
  22. #elif defined (__ICCARM__)
  23. #define PRAGMA(x) _Pragma(#x)
  24. #define SVCALL(number, return_type, signature) \
  25. PRAGMA(swi_number = number) \
  26. __swi return_type signature;
  27. #else
  28. #define SVCALL(number, return_type, signature) return_type signature  
  29. #endif
  30. #endif  // SVCALL

  31. #endif  // SVCALL_AS_NORMAL_FUNCTION
  32. #endif  // NRF_SVC__

  33. void C_SVC_Handler(uint8_t svc_num, uint32_t * p_svc_args)
  34. {
  35.     switch (svc_num)
  36.     {
  37.         case NRF_SEC_SVC_HASH:
  38.             p_svc_args[0] = nrf_sec_hash((nrf_sec_data_t *)     p_svc_args[0],
  39.                                          (uint8_t *)            p_svc_args[1],
  40.                                          (nrf_sec_hash_func_t)  p_svc_args[2]);
  41.             break;

  42.         case NRF_SEC_SVC_VERIFY:
  43.             p_svc_args[0] = nrf_sec_verify((nrf_sec_data_t *)           p_svc_args[0],
  44.                                            (nrf_sec_ecc_point_t *)      p_svc_args[1],
  45.                                            (nrf_sec_ecc_signature_t *)  p_svc_args[2],
  46.                                            (nrf_sec_algo_t)             p_svc_args[3]);
  47.             break;
  48.         
  49.         default:
  50.             p_svc_args[0] = NRF_ERROR_SVC_HANDLER_MISSING;
  51.             break;
  52.     }
  53. }

  54. #if defined ( __CC_ARM )
  55. __asm void SVC_Handler(void)
  56. {
  57. EXC_RETURN_CMD_PSP  EQU 0xFFFFFFFD  ; EXC_RETURN using PSP for ARM Cortex. If Link register contains this value it indicates the PSP was used before the SVC, otherwise the MSP was used.

  58.     IMPORT C_SVC_Handler
  59.     LDR   R0, =EXC_RETURN_CMD_PSP   ; Load the EXC_RETURN into R0 to be able to compare against LR to determine stack pointer used.
  60.     CMP   R0, LR                    ; Compare the link register with R0. If equal then PSP was used, otherwise MSP was used before SVC.
  61.     BNE   UseMSP                    ; Branch to code fetching SVC arguments using MSP.
  62.     MRS   R1, PSP                   ; Move PSP into R1.
  63.     B     Call_C_SVC_Handler        ; Branch to Call_C_SVC_Handler below.
  64. UseMSP
  65.     MRS   R1, MSP                   ; MSP was used, therefore Move MSP into R1.
  66. Call_C_SVC_Handler
  67.     LDR   R0, [R1, #24]             ; The arguments for the SVC was stacked. R1 contains Stack Pointer, the values stacked before SVC are R0, R1, R2, R3, R12, LR, PC (Return address), xPSR.
  68.                                     ; R1 contains current SP so the PC of the stacked frame is at SP + 6 words (24 bytes). We load the PC into R0.
  69.     SUBS  R0, #2                    ; The PC before the SVC is in R0. We subtract 2 to get the address prior to the instruction executed where the SVC number is located.
  70.     LDRB  R0, [R0]                  ; SVC instruction low octet: Load the byte at the address before the PC to fetch the SVC number.
  71.     LDR   R2, =C_SVC_Handler        ; Load address of C implementation of SVC handler.
  72.     BX    R2                        ; Branch to C implementation of SVC handler. R0 is now the SVC number, R1 is the StackPointer where the arguments (R0-R3) of the original SVC are located.
  73.     ALIGN
  74. }
  75. #elif defined ( __GNUC__ )
  76. void __attribute__ (( naked )) SVC_Handler(void)
  77. {
  78.     const uint32_t exc_return = 0xFFFFFFFD;      // EXC_RETURN using PSP for ARM Cortex. If Link register contains this value it indicates the PSP was used before the SVC, otherwise the MSP was used.
  79.    
  80.     __asm volatile(
  81.         "cmp   lr, %0\t\n"                       // Compare the link register with argument 0 (%0), which is exc_return. If equal then PSP was used, otherwise MSP was used before SVC.
  82.         "bne   UseMSP\t\n"                       // Branch to code fetching SVC arguments using MSP.
  83.         "mrs   r1, psp\t\n"                      // Move PSP into R1.
  84.         "b     Call_C_SVC_Handler\t\n"           // Branch to Call_C_SVC_Handler below.
  85.         "UseMSP:  \t\n"                          //
  86.         "mrs   r1, msp\t\n"                      // MSP was used, therefore Move MSP into R1.
  87.         "Call_C_SVC_Handler:  \t\n"              //
  88.         "ldr   r0, [r1, #24]\t\n"                // The arguments for the SVC was stacked. R1 contains Stack Pointer, the values stacked before SVC are R0, R1, R2, R3, R12, LR, PC (Return address), xPSR.
  89.                                                  // R1 contains current SP so the PC of the stacked frame is at SP + 6 words (24 bytes). We load the PC into R0.
  90.         "sub   r0, r0, #2\t\n"                   // The PC before the SVC is in R0. We subtract 2 to get the address prior to the instruction executed where the SVC number is located.
  91.         "ldrb  r0, [r0]\t\n"                     // SVC instruction low octet: Load the byte at the address before the PC to fetch the SVC number.
  92.         "bx    %1\t\n"                           // Branch to C implementation of SVC handler, argument 1 (%1). R0 is now the SVC number, R1 is the StackPointer where the arguments (R0-R3) of the original SVC are located.
  93.         ".align\t\n"
  94.         :: "r" (exc_return), "r" (C_SVC_Handler) // Argument list for the gcc assembly. exc_return is %0, C_SVC_Handler is %1.
  95.         : "r0", "r1"                             // List of register maintained manually.
  96.     );
  97. }
  98. #else
  99. #error Compiler not supported.
  100. #endif


  101. __asm void SVCHandler(void)
  102. {
  103.     IMPORT SVCHandler_main
  104.     TST lr, #4
  105.     ITE EQ
  106.     MRSEQ R0, MSP
  107.     MRSNE R0, PSP
  108.     B SVCHandler_main
  109. }
  110. void SVCHandler_main(unsigned int * svc_args)
  111. {
  112.     unsigned int svc_number;
  113.     /*
  114.     * Stack contains:
  115.     * R0, R1, R2, R3, R12, R14, the return address and xPSR
  116.     * First argument (R0) is svc_args[0]
  117.     */
  118.     svc_number = ((char *)svc_args[6])[-2];
  119.     switch(svc_number)
  120.     {
  121.         case SVC_00:
  122.             /* Handle SVC 00 */
  123.             break;
  124.         case SVC_01:
  125.             /* Handle SVC 01 */
  126.             break;
  127.         default:
  128.             /* Unknown SVC */
  129.             break;
  130.     }
  131. }

  132. #define SVC_00 0x00
  133. #define SVC_01 0x01
  134. void __svc(SVC_00) svc_zero(const char *string);
  135. void __svc(SVC_01) svc_one(const char *string);
  136. int call_system_func(void)
  137. {
  138.     svc_zero("String to pass to SVC handler zero");
  139.     svc_one("String to pass to a different OS function");
  140. }

  141. 在 ARM 狀態時為 0。

  142. ARM 和 Thumb 指令集均有 SVC 指令。 在 Thumb 狀態下調用 SVC 時,必須考慮以下情況:

  143. 指令的地址在 lr–2,而不在 lr–4。

  144. 該指令本身為 16 位,因而需要半字加載,請參閱Figure 6.3。

  145. 在 ARM 狀態下,SVC 編號以 8 位存儲,而不是 24 位。
  146. Example 6.8. SVC 處理程序
  147.     PRESERVE8
  148.     AREA SVC_Area, CODE, READONLY
  149.     EXPORT SVC_Handler    IMPORT C_SVC_Handler
  150. T_bit   EQU    0x20                    ; Thumb bit (5) of CPSR/SPSR.
  151. SVC_Handler
  152.     STMFD   sp!, {r0-r3, r12, lr}  ; Store registers
  153.     MOV     r1, sp                 ; Set pointer to parameters
  154.     MRS     r0, spsr               ; Get spsr
  155.     STMFD   sp!, {r0, r3}          ; Store spsr onto stack and another
  156.                                    ; register to maintain 8-byte-aligned stack
  157.     TST     r0, #T_bit             ; Occurred in Thumb state?
  158.     LDRNEH  r0, [lr,#-2]           ; Yes: Load halfword and...
  159.     BICNE   r0, r0, #0xFF00        ; ...extract comment field
  160.     LDREQ   r0, [lr,#-4]           ; No: Load word and...
  161.     BICEQ   r0, r0, #0xFF000000    ; ...extract comment field

  162.     ; r0 now contains SVC number
  163.     ; r1 now contains pointer to stacked registers

  164.     BL      C_SVC_Handler          ; Call main part of handler
  165.     LDMFD   sp!, {r0, r3}          ; Get spsr from stack
  166.     MSR     SPSR_cxsf, r0               ; Restore spsr
  167.     LDMFD   sp!, {r0-r3, r12, pc}^ ; Restore registers and return
  168.     END
復制代碼

所有資料51hei提供下載:
ARM SVC.zip (3.58 KB, 下載次數: 9)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一区二区日韩 | 91.xxx.高清在线 | 欧美日本在线观看 | 国产日韩欧美一区二区 | 亚洲五码在线 | 成人网在线 | 亚洲第一在线 | 一级毛片大全免费播放 | 亚州精品成人 | 国产一区二区在线免费观看 | 中国大陆高清aⅴ毛片 | 91久久国产综合久久 | 亚洲一区在线日韩在线深爱 | 久久精品成人 | 日本色婷婷 | 伊人青青久久 | 国产在线精品一区二区 | 亚洲成人中文字幕 | 91色在线| 免费的av网站 | 欧美大片一区 | 国产一在线观看 | 毛片大全| 午夜久久久 | 国产第二页 | 日韩在线视频一区二区三区 | 久久综合av | 综合激情网 | 一级毛片免费完整视频 | 国产精品久久久久久久久久久久午夜片 | 国产精品一区二 | 自拍偷拍精品 | 在线国产中文字幕 | 亚洲黄色一级 | 在线成人 | 欧美色综合天天久久综合精品 | 99精品一区二区 | 91视频网址| 久久高清 | 亚洲欧美综合精品另类天天更新 | 精品免费视频 |