查看: 4854|回复: 0

Perf-V开发板三:定时中断方式的流水灯实验

[复制链接]
  • TA的每日心情
    开心
    2019-6-20 14:08
  • 签到天数: 43 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2019-1-10 15:39:32 | 显示全部楼层 |阅读模式
    分享到:
            不知道什么原因Perf-V IDE下中断无法工作,我实现的流水灯是使用查询方式下进行的,但是根据官方群技术支持工作人员所述是可以定时中断方式工作的,所以我便在虚拟机下进行了验证,果不其然其工作杠杠的(我在反向进行修改,将虚拟机下的工程移植到Perf-V IDE下,但是没有成功,这部分工作还将继续摸索中,究其原因还是不太喜欢linux下开发吧)。现总结如下。
            1. 修改E203 SOC核,如前一贴所述。
            2. 找到hifive1.h文件,修改对led0-3的宏定义,如下图1所示。hifive1.h路径如图1中红色框所示。
    66.png
    图1  hifive1.h文件
             主程序如下所示。
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include "platform.h"
    4. #include <string.h>
    5. #include "plic/plic_driver.h"
    6. <font style="background-color: magenta;">#include "../../bsp/env/hifive1.h"</font>
    7. #include "encoding.h"
    8. #include <unistd.h>
    9. #include "stdatomic.h"
    10. #define uchar unsigned char
    11. #define uint unsigned int
    12. uint32_t count=0;
    13. uint32_t delay_mark=0;
    14. void delay(uint32_t times);
    15. void reset_demo (uint32_t times);
    16. void GPIO_SET(uint32_t pin_num,uint32_t pin_val,uint32_t pin_model);

    17. // Structures for registering different interrupt handlers
    18. // for different parts of the application.
    19. typedef void (*function_ptr_t) (void);


    20. void no_interrupt_handler (void) {};

    21. function_ptr_t g_ext_interrupt_handlers[PLIC_NUM_INTERRUPTS];


    22. // Instance data for the PLIC.

    23. plic_instance_t g_plic;


    24. /*Entry Point for PLIC Interrupt Handler*/
    25. void handle_m_ext_interrupt(){
    26.   plic_source int_num  = PLIC_claim_interrupt(&g_plic);
    27.   if ((int_num >=1 ) && (int_num < PLIC_NUM_INTERRUPTS)) {
    28.     g_ext_interrupt_handlers[int_num]();
    29.   }
    30.   else {
    31.     exit(1 + (uintptr_t) int_num);
    32.   }
    33.   PLIC_complete_interrupt(&g_plic, int_num);
    34. }


    35. /*Entry Point for Machine Timer Interrupt Handler*/
    36. void handle_m_time_interrupt(){
    37.          
    38.    clear_csr(mie, MIP_MTIP);
    39.    volatile uint64_t * mtime       = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);
    40.    volatile uint64_t * mtimecmp    = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
    41.     uint64_t now = *mtime;
    42.     uint64_t then = now +0.5* RTC_FREQ;
    43.    *mtimecmp = then;
    44.   count++;
    45.        
    46. if(count==1)
    47. {
    48.         uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
    49.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD4_r));
    50.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD5_r));
    51.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD6_r));
    52.        
    53.         GPIO_SET(led1,0,output);
    54.         GPIO_SET(led2,1,output);
    55.         GPIO_SET(led3,1,output);       
    56.         GPIO_SET(led4,1,output);
    57. }
    58. if(count==2)
    59. {
    60.         uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
    61.                GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD4_g));
    62.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD5_g));
    63.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD6_g));
    64.        
    65.         GPIO_SET(led1,1,output);
    66.         GPIO_SET(led2,0,output);
    67.         GPIO_SET(led3,1,output);       
    68.         GPIO_SET(led4,1,output);
    69. }
    70. if(count==3)
    71. {
    72.         uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
    73.        GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD4_b));
    74.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD5_b));
    75.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD6_b));

    76.         GPIO_SET(led1,1,output);
    77.         GPIO_SET(led2,1,output);
    78.         GPIO_SET(led3,0,output);       
    79.         GPIO_SET(led4,1,output);
    80. }
    81. if(count==4)
    82. {
    83.         uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
    84.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD4_r));
    85.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD4_g));
    86.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD4_b));

    87.         GPIO_SET(led1,1,output);
    88.         GPIO_SET(led2,1,output);
    89.         GPIO_SET(led3,1,output);       
    90.         GPIO_SET(led4,0,output);
    91. }
    92. if(count==5)
    93. {
    94.         uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
    95.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD5_r));
    96.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD5_g));
    97.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD5_b));

    98.         GPIO_SET(led1,1,output);
    99.         GPIO_SET(led2,1,output);
    100.         GPIO_SET(led3,1,output);       
    101.         GPIO_SET(led4,1,output);
    102. }
    103. if(count==6)
    104. {
    105.         uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
    106.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD6_r));
    107.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD6_g));
    108.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD6_b));

    109.         GPIO_SET(led1,1,output);
    110.         GPIO_SET(led2,1,output);
    111.         GPIO_SET(led3,0,output);       
    112.         GPIO_SET(led4,1,output);
    113. }
    114. if(count==7)
    115. {
    116.         uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
    117.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD4_r));
    118.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD5_r));
    119.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD6_r));

    120.         GPIO_SET(led1,1,output);
    121.         GPIO_SET(led2,0,output);
    122.         GPIO_SET(led3,1,output);       
    123.         GPIO_SET(led4,1,output);
    124. }
    125. if(count==8)
    126. {
    127.         uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
    128.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD4_g));
    129.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD5_g));
    130.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD6_g));

    131.         GPIO_SET(led1,0,output);
    132.         GPIO_SET(led2,1,output);
    133.         GPIO_SET(led3,1,output);       
    134.         GPIO_SET(led4,1,output);
    135. }
    136. if(count==9)
    137. {
    138.         uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
    139.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD4_b));
    140.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD5_b));
    141.         GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x0 << ledD6_b));

    142.         GPIO_SET(led1,1,output);
    143.         GPIO_SET(led2,1,output);
    144.         GPIO_SET(led3,1,output);       
    145.         GPIO_SET(led4,1,output);
    146. }
    147. if(count==9)
    148. {
    149.         count=0;
    150. }

    151.   // read the current value of the LEDS and invert them.


    152.    
    153.      // uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);
    154.      // GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << BLUE_LED_OFFSET));
    155.        
    156.    
    157.     //GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << ledD4_r));
    158.   // Re-enable the timer interrupt.
    159. <font style="background-color: darkorchid;">  set_csr(mie, MIP_MTIP);</font>

    160. }


    161. void print_instructions() {

    162.   //write (STDOUT_FILENO, instructions_msg, strlen(instructions_msg));
    163.   //write (STDOUT_FILENO, instructions_msg_sirv, strlen(instructions_msg_sirv));
    164.   // printf ("%s",instructions_msg_sirv);

    165. }


    166. void reset_demo (uint32_t times){

    167.   // Disable the machine & timer interrupts until setup is done.

    168.   clear_csr(mie, MIP_MEIP);
    169.   clear_csr(mie, MIP_MTIP);

    170.   for (int ii = 0; ii < PLIC_NUM_INTERRUPTS; ii ++){
    171.     g_ext_interrupt_handlers[ii] = no_interrupt_handler;
    172.   }


    173.     // Set the machine timer to go off in 3 seconds.
    174.    
    175.     volatile uint64_t * mtime       = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);
    176.     volatile uint64_t * mtimecmp    = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
    177.     uint64_t now = *mtime;
    178.     uint64_t then = now + times*RTC_FREQ;
    179.     *mtimecmp = then;

    180.     // Enable the Machine-External bit in MIE
    181. <font style="background-color: orange;">    set_csr(mie, MIP_MEIP);</font>
    182.     // Enable the Machine-Timer bit in MIE
    183. <font style="background-color: orange;">    set_csr(mie, MIP_MTIP);</font>
    184.     // Enable interrupts in general.
    185. <font color="black" style="background-color: orange;">    set_csr(mstatus, MSTATUS_MIE);</font>
    186. }


    187. void GPIO_SET(uint32_t pin_num,uint32_t pin_val,uint32_t pin_model)
    188. {
    189.     if(pin_model==output)
    190.      {       
    191.         GPIO_REG(GPIO_OUTPUT_EN) |= (0x01<<pin_num);
    192.         if(pin_val==1)
    193.         {
    194.              GPIO_REG(GPIO_OUTPUT_VAL) |=(0x01<<pin_num);
    195.         }
    196.         if(pin_val==0)
    197.         {
    198.              GPIO_REG(GPIO_OUTPUT_VAL) &=~(0x01<<pin_num);
    199.         }
    200.      }
    201.     if(pin_model==input)
    202.     {
    203.         GPIO_REG(GPIO_INPUT_EN) |= (0x01<<pin_num);
    204.     }

    205. }

    206. int main(int argc, char **argv)
    207. {




    208.   /**************************************************************************
    209.    * Set up the PLIC
    210.    *
    211.    *************************************************************************/
    212.    PLIC_init(&g_plic,
    213.             PLIC_CTRL_ADDR,
    214.             PLIC_NUM_INTERRUPTS,
    215.             PLIC_NUM_PRIORITIES);

    216.    reset_demo(1);
    217.         GPIO_SET(ledD4_r,1,output);
    218.         GPIO_SET(ledD4_g,1,output);
    219.         GPIO_SET(ledD4_b,1,output);

    220.         GPIO_SET(ledD5_r,1,output);
    221.         GPIO_SET(ledD5_g,1,output);
    222.         GPIO_SET(ledD5_b,1,output);

    223.         GPIO_SET(ledD6_r,1,output);
    224.         GPIO_SET(ledD6_g,1,output);
    225.         GPIO_SET(ledD6_b,1,output);
    226.        
    227.         GPIO_SET(led4,1,output);
    228.         GPIO_SET(led1,1,output);
    229.         GPIO_SET(led2,1,output);       
    230.         GPIO_SET(led3,1,output);
    231.        
    232.         //GPIO_SET(BLUE_LED_OFFSET,1,output);

    233.   while (1){
    234.          
    235.        
    236.   }


    237.   return 0;

    238. }


    复制代码
            3. 执行编译命令。
    1. make software PROGRAM=demo_gpio BOARD=Perf-V-creative-board
    复制代码
            4. 执行加载命令。
    1. make upload PROGRAM=demo_gpio BOARD=Perf-V-creative-board
    复制代码
           5.  效果如下。




    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-3-28 18:37 , Processed in 0.112504 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.