<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于優先級調度的嵌入式實時操作系統內核詳解(下)

瑞薩MCU小百科 ? 來源:瑞薩MCU小百科 ? 2023-09-06 12:46 ? 次閱讀

三、板載led和串口的驅動

3.1 板載led(GPIO)

RA6M5的引腳結構體定義

左右滑動查看

typedef struct _ra6m5_fire_pin_t
{
  cat_uint32_t       pin_num;
  ioport_instance_ctrl_t *p_ctrl_ptr;
  const bsp_io_port_pin_t gpio_pin;
}ra6m5_fire_pin_t;

暫時只用得上輸出引腳,實現pin_write接口,利用fsp庫實現引腳輸出。

左右滑動查看

cat_uint8_t cat_pin_write(cat_uint32_t pin_num, cat_uint8_t val)
{
  cat_uint8_t ret = CAT_ERROR;
  ra6m5_fire_pin_t *p = &(pin_map[0]);


  /* 遍歷pin_map數組 */
  for(; p->pin_num!=0xffff; p++)
  {
    if(p->pin_num == pin_num)
    {
      if(0 == val)
      {
        R_IOPORT_PinWrite(p->p_ctrl_ptr, p->gpio_pin, BSP_IO_LEVEL_LOW);
        ret = CAT_EOK;
      }
      else if(1 == val)
      {
        R_IOPORT_PinWrite(p->p_ctrl_ptr, p->gpio_pin, BSP_IO_LEVEL_HIGH);
        ret = CAT_EOK;
      }
      else
      {
        /* 非法值,之后打印錯誤信息 */
        ret = CAT_ERROR;
        while(1);
      }


      /* 寫入結束結束循環 */
      break;
    } /* if */
  } /* for */


  return ret;
}

3.2 串口

野火教程以及我找到的官方例程中RA6M5的串口收發均使用中斷實現,但在本內核中的標準輸入輸出函數大部分是以字符為單位,故發送接口用寄存器方式實現,串口接收仍然使用fsp庫+中斷實現

3.2.1 串口發送

左右滑動查看

static cat_int8_t ra6m5_uart_send_char(cat_device_t*dev, cat_uint32_t timeout, cat_uint8_t data)
{
  cat_int8_t ret = CAT_ERROR;
  struct _cat_ra6m5_fire_uart_private_data_t *private_data = NULL;


  /* 獲取設備實例數據 */
  private_data = (struct _cat_ra6m5_fire_uart_private_data_t *)(dev->pri_data);


  sci_uart_instance_ctrl_t *p_ctrl = private_data->inst_ctrl_ptr;


  /* 將要發送的數據放進數據寄存器 */
  p_ctrl->p_reg->TDR = data;


  /* 等待發送完成或超時 */
  while(
    ((p_ctrl->p_reg->SSR_b.TEND) == 0) &&
    (0 != timeout)
  )
  {
    timeout--;
  }


  /* 未超時才成功 */
  if(0 != timeout)
  {
    ret = CAT_EOK;
  }


  return ret;
}


static cat_uint32_t ra6m5_uart_send(cat_device_t*dev, uint32_t timeout, uint8_t const * const buffer, uint32_t const size)
{
  (void)timeout;
  cat_uint32_t cnt = 0;
  cat_int8_t err = CAT_EOK;


  while(
    (CAT_EOK == err) &&
    (cnt < size)
 ? ?)
 ? ?{
 ? ? ? ?err = ra6m5_uart_send_char(dev, 0xffff, buffer[cnt]);
 ? ? ? ?cnt++;
 ? ?}


 ? ?/* 因為前面在一次 while 循環中無論發送是否成功 cnt 都會無條件加一,所以如果失敗了就有一個多加上的計數 */
 ? ?if(CAT_ERROR == err)
 ? ?{
 ? ? ? ?cnt--;
 ? ?}


 ? ?return cnt;
}

3.2.2 串口接收

左右滑動查看

static cat_uint32_t ra6m5_uart_recv(cat_device_t*dev, uint32_t timeout, uint8_t *buffer, uint32_t const size)
{
cat_uint32_t recv_buffer_idx = 0; /**< 串口接收緩沖區訪問索引 */
cat_uint32_t err = CAT_ERROR;
struct _cat_ra6m5_fire_uart_private_data_t *private_data = NULL;


/* 獲取設備實例數據 */
private_data = (struct _cat_ra6m5_fire_uart_private_data_t *)(dev->pri_data);
assert(NULL != private_data);


/* 讀取 */
while(recv_buffer_idx != size)
{
while(
(false == uart4_receive_char) &&
(0 != timeout)
)
{
timeout--;
};


if(0 == timeout)
{
break;
}


while(
(cat_ringbuffer_is_empty(private_data->p_ringbuffer) == 0)
)
{
/* 獲取接收到的字符 */
err = cat_ringbuffer_get(private_data->p_ringbuffer, &(buffer[recv_buffer_idx++]));


if(CAT_ERROR == err)
{
/* 獲取失敗,因為while條件判斷過非空,所以出大問題 */
while(1);
}


if(recv_buffer_idx == size)
{
break;
}
}


if(cat_ringbuffer_is_empty(private_data->p_ringbuffer))
{
/* 取完才改遍flag */
uart4_receive_char = false;
}
}


return recv_buffer_idx;
}

3.2.3 串口中斷服務函數

左右滑動查看

/* uart4中斷回調函數 */
void debug_uart4_callback(uart_callback_args_t *pargs)
{
  switch(pargs->event)
  {
    case UART_EVENT_RX_CHAR:
    {
      cat_ringbuffer_put(&uart4_rb, pargs->data);
      uart4_receive_char = true;
    }
    default:
    {
      break;
    }
  }
}

四、調試驗證

4.1 創建demo項目

在Projects目錄利用RASC工具生成Keil裸機工程,只需配置led引腳以及UART串口

eb88a170-4c6a-11ee-a25d-92fbcf53809c.png

eba6cb0a-4c6a-11ee-a25d-92fbcf53809c.png

4.2 編寫程序創建任務

在hal_entry中創建用戶任務

左右滑動查看

#include "hal_data.h"
#include "catos.h"


FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER


/*******************************************************************************************************************//**
* 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.
**********************************************************************************************************************/
#define TASK1_STACK_SIZE  (1024)
#define TASK2_STACK_SIZE  (1024)


struct _cat_task_t task1;
struct _cat_task_t task2;


cat_stack_type_t task1_env[TASK1_STACK_SIZE];
cat_stack_type_t task2_env[TASK2_STACK_SIZE];


uint32_t sched_task1_times = 0;
uint32_t sched_task2_times = 0;


#define BOARD_LED_PIN 0


void board_led_init(void)
{
  cat_pin_init(BOARD_LED_PIN, CAT_PIN_MODE_OUTPUT);
}


void board_led_on(void)
{
  cat_pin_write(BOARD_LED_PIN, CAT_PIN_LOW);
}


void board_led_off(void)
{
  cat_pin_write(BOARD_LED_PIN, CAT_PIN_HIGH);
}


void task1_entry(void *arg)
{


  for(;;)
  {
    sched_task1_times++;
    board_led_on();
    cat_sp_task_delay(100);
    board_led_off();
    cat_sp_task_delay(100);
  }
}


void task2_entry(void *arg)
{
  for(;;)
  {
    cat_sp_task_delay(100);
    //CAT_DEBUG_PRINTF("[task2] %d
", catos_systicks);
  }
}


void hal_entry(void)
{
  /* TODO: add your own code here */


  /* 初始化os */
  catos_init();


  /* 利用pin驅動初始化板載led */
  board_led_init();


  /* 測試創建任務運行 */
  cat_sp_task_create(
   (const uint8_t *)"task1_task",
   &task1,
   task1_entry,
   NULL,
   0,
   task1_env,
   TASK1_STACK_SIZE
  );


  cat_sp_task_create(
   (const uint8_t *)"task2_task",
   &task2,
   task2_entry,
   NULL,
   0,
   task2_env,
   sizeof(task2_env)
  );




  /* 開始調度 */
  catos_start_sched();


  /* 不會到達這里 */


  while(1);


#if BSP_TZ_SECURE_BUILD
  /* Enter non-secure code */
  R_BSP_NonSecureEnter();
#endif
}



4.3 燒寫與驗證

使用xshell連接串口并燒錄程序,可以觀察到l led閃爍,并且串口有shell的信息,命令可以正常使用。

ebfaf4aa-4c6a-11ee-a25d-92fbcf53809c.png

五、總結

在整個項目過程中,因為涉及底層操作,并且教程還比較少,走了不少彎路,但總體來說還是很不錯的,特別是fsp配置方面。

建議瑞薩可以在e2 studio適配更多調試器方便開發者使用;并且在使用野火dap時發現其在ubuntu下要被識別比較麻煩,如果能改進,使用場景會更多。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • led
    led
    +關注

    關注

    237

    文章

    22550

    瀏覽量

    646873
  • 嵌入式
    +關注

    關注

    5002

    文章

    18414

    瀏覽量

    291567
  • 內核
    +關注

    關注

    3

    文章

    1314

    瀏覽量

    39920
  • RTOS
    +關注

    關注

    20

    文章

    780

    瀏覽量

    118891
  • GPIO
    +關注

    關注

    16

    文章

    1149

    瀏覽量

    50738

原文標題:【瑞薩RA MCU創意氛圍賽作品賞析】項目4——基于優先級的RTOS內核(下)

文章出處:【微信號:瑞薩MCU小百科,微信公眾號:瑞薩MCU小百科】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    基于優先級調度嵌入式實時操作系統內核詳解(上)

    今日分享參加瑞薩RA MCU創意氛圍賽的選手項目——基于優先級的RTOS內核。本項目為基于優先級調度嵌入式
    發表于 09-04 14:12 ?385次閱讀

    嵌入式實時操作系統uCos

    嵌入式實時操作系統uCos:嵌入式實時操作系統μCOS -II一、RTOS基礎 
    發表于 12-10 14:35

    嵌入式領域linux作為實時操作系統的缺點

    幾乎公平的分配任務時間,在特殊場合linux內核在任務調度上實現的是一種幾乎公平的分配任務時間,在特殊場合Linux內核很難滿足
    發表于 01-06 13:31

    詳解RT-Thread實時操作系統

    操作系統,由國內一些專業開發人員開發、維護。它不僅僅是一款 高效、穩定的實時操作系統內核,也是一套面向嵌入式
    發表于 03-02 14:24

    五大適合STM32的嵌入式操作系統

    ,具有執行效率高、占用空間小、實時性能優良和擴展性強等特點。對于實時性的滿足上,由于μC/OS-II內核是針對實時系統的要求設計實現的,所以
    發表于 04-15 15:39

    幾種嵌入式實時操作系統分析與比較

    實時操作系統采用基于優先級搶占調度與時間片輪轉調度相結合的
    發表于 06-11 09:14

    嵌入式操作系統FreeRTOS 的原理與實現

    的使用權后才能獲得運行,這樣可提高CPU的運行效率。2、FreeRTOS操作系統的原理與實現2.1任務調度機制的實現任務調度機制是嵌入式實時
    發表于 06-23 08:00

    實時操作系統概念

    對很多嵌入式系統來說,一個設計良好的實時操作系統可以讓開發工程師把握系統執行任何任務或響應任何關鍵事件的時間,滿足
    發表于 07-19 06:18

    如何進行嵌入式Linux內核實時化研究?

    嵌入式Linux是指對Linux進行剪裁后,將其固化在單片機或者存儲器中,應用于特定場合的專用Linux系統。嵌入式系統要求實時性能高,但L
    發表于 08-06 07:15

    嵌入式實時系統中的優先級反轉是什么?

    的可搶占調度策略。系統為每一個任務分配一個優先權,調度程序保證當前運行的進程是優先權最高的進程
    發表于 09-17 07:16

    適合STM32的三大嵌入式操作系統

    ,μC/OS-II的移植相對比較簡單,只需要修改與處理器相關的代碼就可以。綜上可知,μC/OS-II是一個結構簡單、功能完備和實時性很強的嵌入式操作系統內核,針對于沒有MMU功能的CP
    發表于 06-29 11:32

    嵌入式實時系統中的優先級反轉問題怎么解決?

    嵌入式實時系統中的優先級反轉問題怎么解決?
    發表于 04-27 06:44

    嵌入式操作系統為什么必須要有一個良好的任務調度算法呢

    引言隨著嵌入式實時操作系統應用的不斷深入,多個實時任務并發執行,再加上任務之間不停地動態切換,這對任務調度算法提出了較高的要求。
    發表于 12-21 06:24

    嵌入式實時操作系統VxWorks內核調度機制分析

    本文簡要介紹了多任務內核,重點分析了嵌入式實時操作系統VxWorks的內核調度機制——
    發表于 12-11 16:15 ?14次下載

    嵌入式實時操作系統內核的設計

    針對廣泛使用的微處理單元(MCU),從任務TCB設計、任務的創建和刪除、任務調度的算法及實現、中斷管理、優先級管理和操作系統及用戶的接口等6個部分出發,提出了一個嵌入式
    發表于 08-26 14:34 ?63次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>實時</b><b class='flag-5'>操作系統</b><b class='flag-5'>內核</b>的設計
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>