【瑞萨RA4系列开发板体验】KEIL环境搭建+STLINK调试+FreeRTOS使用
作者:hehung
下面是之前发的帖子,请参考:
【瑞萨RA4系列开发板体验】新建工程+按键控制LED
前言
上一篇帖子讲解了如何基于e2从头创建一个新的工程,但是因为没有JLINK,下载软件很麻烦,而且也不能在线DEBUG,所以想着在MDK上搭建环境,因为MDK上支持多种调试器,可以利用手头的ST-LINK来作为调试器下载与debug。
本文实现主要内容: - MDK环境搭建以及ST-LINK调试配置;
- 使用freeRTOS实现按键以及LED功能。
MDK环境搭建
环境搭建过程不在赘述,参考文档即可,我这里主要说一下基于RA4M2搭建以及使用ST-LINK调试时需要注意的事项。 - 根据手头的调试器选择自己的调试工具,我手头的是ST-LINK
2.加载下载算法文件以及算法存放在RAM中的地址
算法下载地址是根据RA4M2的地址分布来确定的,算法需要下载到RAM中, 需要的大小可以自己确定,这里选择0x1000,如果不够的话下载不成功。
FreeRTOS使用
我在创建工程的时候选择了使用FreeRTOS,RASC会默认配置一个最小配置项的freeRTOS环境,只支持基本的功能,很多扩展功能都不支持,只支持静态创建任务,我还没找到在哪里可以配置,因为直接修改配置文件不行,RASC再次生成的时候会覆盖。
虽然freeRTOS只支持静态配置以及一些基础功能,但是也够我们使用了,下面开始实现我的逻辑。 因为是静态分配栈,所以该部分功能需要我们自己实现,FreeRTOS提供了接口。
- /* Implement the Idle task memory static alocation */
- void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,
- StackType_t ** ppxIdleTaskStackBuffer,
- uint32_t * pulIdleTaskStackSize)
- {
- *ppxIdleTaskTCBBuffer = &xIdleTaskTcb;
- *ppxIdleTaskStackBuffer = xIdleTaskStack;
- *pulIdleTaskStackSize = 1024;
- }
复制代码因为是静态分配栈,所以该部分功能需要我们自己实现,FreeRTOS提供了接口。
- /* Implement the Timer task memory static alocation */
- void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
- StackType_t **ppxTimerTaskStackBuffer,
- uint32_t *pulTimerTaskStackSize)
- {
- *ppxTimerTaskTCBBuffer = &xTimerTaskTcb;
- *ppxTimerTaskStackBuffer = xTiemrTaskStack;
- *pulTimerTaskStackSize = 2048;
- }
复制代码- 新建LED任务
LED任务实现流水灯功能,每200ms切换一次。
任务创建:
- /* Create static task */
- Task_Led_Handle = xTaskCreateStatic(Task_LedRunning,
- "Led", /* Task name */
- 1024, /* Stack */
- NULL, /* Task parameter */
- 4, /* Priority */
- xTaskLedStack,
- &xTaskLedTcb); /* Task handler */
复制代码 LED任务实现:
- static void Task_LedRunning(void *pvParameters)
- {
- (void)pvParameters;
-
- for (;;)
- {
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_HIGH);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_LOW);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW);
- /* Delay for 200ms */
- vTaskDelay(pdMS_TO_TICKS(200));
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_HIGH);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW);
- /* Delay for 200ms */
- vTaskDelay(pdMS_TO_TICKS(200));
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_LOW);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_HIGH);
- /* Delay for 200ms */
- vTaskDelay(pdMS_TO_TICKS(200));
- }
- }
复制代码- 新建Key任务
按键实现了对按键SW1与SW2的采集,滤波等功能,任务周期为10ms,滤波时间为40ms。
当SW1按下,暂停LED任务;
当SW2按下,恢复LED任务。
任务创建:
- Task_Key_Handle = xTaskCreateStatic(Task_KeyRunning,
- "Key", /* Task name */
- 1024, /* Stack */
- NULL, /* Task parameter */
- 3, /* Priority */
- xTaskKeyStack,
- &xTaskKeyTcb); /* Task handler */
复制代码 任务实现:
- static void Task_KeyRunning(void *pvParameters)
- {
- (void)pvParameters;
- bsp_io_level_t key_Status[2] = {BSP_IO_LEVEL_HIGH, BSP_IO_LEVEL_HIGH};
- uint16_t key_press_cnt[2] = {0U, 0U};
-
- for (;;)
- {
- if (FSP_SUCCESS == R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &key_Status[0]))
- {
- if (key_Status[0] == BSP_IO_LEVEL_LOW)
- {
- /* Filter */
- if (key_press_cnt[0] >= 0U)
- {
- /* Key SW0 press confirm */
- /* Suspend led task */
- vTaskSuspend(Task_Led_Handle);
- }
- else
- {
- key_press_cnt[0] ++;
- }
- }
- else
- {
- key_press_cnt[0] = 0U;
- }
- }
-
- if (FSP_SUCCESS == R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_06, &key_Status[1]))
- {
- if (key_Status[1] == BSP_IO_LEVEL_LOW)
- {
- /* Filter */
- if (key_press_cnt[1] >= 4U)
- {
- /* Key SW1 press confirm */
- /* Resume led task */
- vTaskResume(Task_Led_Handle);
- }
- else
- {
- key_press_cnt[1] ++;
- }
- }
- else
- {
- key_press_cnt[1] = 0U;
- }
- }
- vTaskDelay(pdMS_TO_TICKS(10));
- }
- }
复制代码
完整代码
- #include "hal_data.h"
- #include "FreeRTOS.h"
- #include "task.h"
- FSP_CPP_HEADER
- void R_BSP_WarmStart(bsp_warm_start_event_t event);
- FSP_CPP_FOOTER
- /* Stack for Idle task */
- static StackType_t xIdleTaskStack[512];
- static StaticTask_t xIdleTaskTcb;
- /* Stack for Timer task */
- static StackType_t xTiemrTaskStack[512];
- static StaticTask_t xTimerTaskTcb;
- /* Staack for LED task */
- static StackType_t xTaskLedStack[1024];
- static StaticTask_t xTaskLedTcb;
- static TaskHandle_t Task_Led_Handle = NULL;
- /* Staack for LED task */
- static StackType_t xTaskKeyStack[1024];
- static StaticTask_t xTaskKeyTcb;
- static TaskHandle_t Task_Key_Handle = NULL;
- extern void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,
- StackType_t ** ppxIdleTaskStackBuffer,
- uint32_t * pulIdleTaskStackSize);
- extern void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
- StackType_t **ppxTimerTaskStackBuffer,
- uint32_t *pulTimerTaskStackSize);
- static void Task_LedRunning(void *pvParameters);
- static void Task_KeyRunning(void *pvParameters);
- static void Task_LedRunning(void *pvParameters)
- {
- (void)pvParameters;
-
- for (;;)
- {
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_HIGH);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_LOW);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW);
- /* Delay for 200ms */
- vTaskDelay(pdMS_TO_TICKS(200));
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_HIGH);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW);
- /* Delay for 200ms */
- vTaskDelay(pdMS_TO_TICKS(200));
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_LOW);
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_HIGH);
- /* Delay for 200ms */
- vTaskDelay(pdMS_TO_TICKS(200));
- }
- }
- static void Task_KeyRunning(void *pvParameters)
- {
- (void)pvParameters;
- bsp_io_level_t key_Status[2] = {BSP_IO_LEVEL_HIGH, BSP_IO_LEVEL_HIGH};
- uint16_t key_press_cnt[2] = {0U, 0U};
-
- for (;;)
- {
- if (FSP_SUCCESS == R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &key_Status[0]))
- {
- if (key_Status[0] == BSP_IO_LEVEL_LOW)
- {
- /* Filter */
- if (key_press_cnt[0] >= 0U)
- {
- /* Key SW0 press confirm */
- /* Suspend led task */
- vTaskSuspend(Task_Led_Handle);
- }
- else
- {
- key_press_cnt[0] ++;
- }
- }
- else
- {
- key_press_cnt[0] = 0U;
- }
- }
-
- if (FSP_SUCCESS == R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_06, &key_Status[1]))
- {
- if (key_Status[1] == BSP_IO_LEVEL_LOW)
- {
- /* Filter */
- if (key_press_cnt[1] >= 4U)
- {
- /* Key SW1 press confirm */
- /* Resume led task */
- vTaskResume(Task_Led_Handle);
- }
- else
- {
- key_press_cnt[1] ++;
- }
- }
- else
- {
- key_press_cnt[1] = 0U;
- }
- }
- vTaskDelay(pdMS_TO_TICKS(10));
- }
- }
- /* Implement the Idle task memory static alocation */
- void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,
- StackType_t ** ppxIdleTaskStackBuffer,
- uint32_t * pulIdleTaskStackSize)
- {
- *ppxIdleTaskTCBBuffer = &xIdleTaskTcb;
- *ppxIdleTaskStackBuffer = xIdleTaskStack;
- *pulIdleTaskStackSize = 1024;
- }
- /* Implement the Timer task memory static alocation */
- void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
- StackType_t **ppxTimerTaskStackBuffer,
- uint32_t *pulTimerTaskStackSize)
- {
- *ppxTimerTaskTCBBuffer = &xTimerTaskTcb;
- *ppxTimerTaskStackBuffer = xTiemrTaskStack;
- *pulTimerTaskStackSize = 2048;
- }
- /*******************************************************************************************************************//**
- * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
- * is called by main() when no RTOS is used.
- **********************************************************************************************************************/
- void hal_entry(void)
- {
- /* Create static task */
- Task_Led_Handle = xTaskCreateStatic(Task_LedRunning,
- "Led", /* Task name */
- 1024, /* Stack */
- NULL, /* Task parameter */
- 4, /* Priority */
- xTaskLedStack,
- &xTaskLedTcb); /* Task handler */
-
- Task_Key_Handle = xTaskCreateStatic(Task_KeyRunning,
- "Key", /* Task name */
- 1024, /* Stack */
- NULL, /* Task parameter */
- 3, /* Priority */
- xTaskKeyStack,
- &xTaskKeyTcb); /* Task handler */
- if (NULL != Task_Led_Handle)
- {
- vTaskStartScheduler();
- }
- while (1) {}
- #if BSP_TZ_SECURE_BUILD
- /* Enter non-secure code */
- R_BSP_NonSecureEnter();
- #endif
- }
- /*******************************************************************************************************************//**
- * This function is called at various points during the startup process. This implementation uses the event that is
- * called right before main() to set up the pins.
- *
- * @param[in] event Where at in the start up process the code is currently at
- **********************************************************************************************************************/
- void R_BSP_WarmStart(bsp_warm_start_event_t event)
- {
- if (BSP_WARM_START_RESET == event)
- {
- #if BSP_FEATURE_FLASH_LP_VERSION != 0
- /* Enable reading from data flash. */
- R_FACI_LP->DFLCTL = 1U;
- /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
- * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
- #endif
- }
- if (BSP_WARM_START_POST_C == event)
- {
- /* C runtime environment and system clocks are setup. */
- /* Configure pins. */
- R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);
- }
- }
- #if BSP_TZ_SECURE_BUILD
- BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
- /* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
- BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
- {
- }
- #endif
复制代码
|