三、板載led和串口的驅(qū)動(dòng)
3.1 板載led(GPIO)
RA6M5的引腳結(jié)構(gòu)體定義
左右滑動(dòng)查看
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;
暫時(shí)只用得上輸出引腳,實(shí)現(xiàn)pin_write接口,利用fsp庫實(shí)現(xiàn)引腳輸出。
左右滑動(dòng)查看
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數(shù)組 */ 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 { /* 非法值,之后打印錯(cuò)誤信息 */ ret = CAT_ERROR; while(1); } /* 寫入結(jié)束結(jié)束循環(huán) */ break; } /* if */ } /* for */ return ret; }
3.2 串口
野火教程以及我找到的官方例程中RA6M5的串口收發(fā)均使用中斷實(shí)現(xiàn),但在本內(nèi)核中的標(biāo)準(zhǔn)輸入輸出函數(shù)大部分是以字符為單位,故發(fā)送接口用寄存器方式實(shí)現(xiàn),串口接收仍然使用fsp庫+中斷實(shí)現(xiàn)
3.2.1 串口發(fā)送
左右滑動(dòng)查看
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; /* 獲取設(shè)備實(shí)例數(shù)據(jù) */ 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; /* 將要發(fā)送的數(shù)據(jù)放進(jìn)數(shù)據(jù)寄存器 */ p_ctrl->p_reg->TDR = data; /* 等待發(fā)送完成或超時(shí) */ while( ((p_ctrl->p_reg->SSR_b.TEND) == 0) && (0 != timeout) ) { timeout--; } /* 未超時(shí)才成功 */ 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++; ? ?} ? ?/* 因?yàn)榍懊嬖谝淮?while 循環(huán)中無論發(fā)送是否成功 cnt 都會(huì)無條件加一,所以如果失敗了就有一個(gè)多加上的計(jì)數(shù) */ ? ?if(CAT_ERROR == err) ? ?{ ? ? ? ?cnt--; ? ?} ? ?return cnt; }
3.2.2 串口接收
左右滑動(dòng)查看
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; /**< 串口接收緩沖區(qū)訪問索引 */ cat_uint32_t err = CAT_ERROR; struct _cat_ra6m5_fire_uart_private_data_t *private_data = NULL; /* 獲取設(shè)備實(shí)例數(shù)據(jù) */ 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) { /* 獲取失敗,因?yàn)閣hile條件判斷過非空,所以出大問題 */ 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 串口中斷服務(wù)函數(shù)
左右滑動(dòng)查看
/* uart4中斷回調(diào)函數(shù) */ 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; } } }
四、調(diào)試驗(yàn)證
4.1 創(chuàng)建demo項(xiàng)目
在Projects目錄利用RASC工具生成Keil裸機(jī)工程,只需配置led引腳以及UART串口
4.2 編寫程序創(chuàng)建任務(wù)
在hal_entry中創(chuàng)建用戶任務(wù)
左右滑動(dòng)查看
#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驅(qū)動(dòng)初始化板載led */ board_led_init(); /* 測(cè)試創(chuàng)建任務(wù)運(yùn)行 */ 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) ); /* 開始調(diào)度 */ catos_start_sched(); /* 不會(huì)到達(dá)這里 */ while(1); #if BSP_TZ_SECURE_BUILD /* Enter non-secure code */ R_BSP_NonSecureEnter(); #endif }
4.3 燒寫與驗(yàn)證
使用xshell連接串口并燒錄程序,可以觀察到l led閃爍,并且串口有shell的信息,命令可以正常使用。
五、總結(jié)
在整個(gè)項(xiàng)目過程中,因?yàn)樯婕暗讓硬僮鳎⑶医坛踢€比較少,走了不少彎路,但總體來說還是很不錯(cuò)的,特別是fsp配置方面。
建議瑞薩可以在e2 studio適配更多調(diào)試器方便開發(fā)者使用;并且在使用野火dap時(shí)發(fā)現(xiàn)其在ubuntu下要被識(shí)別比較麻煩,如果能改進(jìn),使用場(chǎng)景會(huì)更多。
審核編輯:湯梓紅
-
led
+關(guān)注
關(guān)注
242文章
23577瀏覽量
668132 -
嵌入式
+關(guān)注
關(guān)注
5119文章
19403瀏覽量
312267 -
內(nèi)核
+關(guān)注
關(guān)注
3文章
1401瀏覽量
40860 -
RTOS
+關(guān)注
關(guān)注
24文章
836瀏覽量
120452 -
GPIO
+關(guān)注
關(guān)注
16文章
1235瀏覽量
53170
原文標(biāo)題:【瑞薩RA MCU創(chuàng)意氛圍賽作品賞析】項(xiàng)目4——基于優(yōu)先級(jí)的RTOS內(nèi)核(下)
文章出處:【微信號(hào):瑞薩MCU小百科,微信公眾號(hào):瑞薩MCU小百科】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
基于優(yōu)先級(jí)調(diào)度的嵌入式實(shí)時(shí)操作系統(tǒng)內(nèi)核詳解(上)
嵌入式實(shí)時(shí)操作系統(tǒng)uCos
嵌入式領(lǐng)域linux作為實(shí)時(shí)操作系統(tǒng)的缺點(diǎn)
詳解RT-Thread實(shí)時(shí)操作系統(tǒng)
幾種嵌入式實(shí)時(shí)操作系統(tǒng)分析與比較
嵌入式操作系統(tǒng)FreeRTOS 的原理與實(shí)現(xiàn)
實(shí)時(shí)操作系統(tǒng)概念
嵌入式實(shí)時(shí)系統(tǒng)中的優(yōu)先級(jí)反轉(zhuǎn)是什么?
嵌入式實(shí)時(shí)系統(tǒng)中的優(yōu)先級(jí)反轉(zhuǎn)問題怎么解決?
嵌入式操作系統(tǒng)為什么必須要有一個(gè)良好的任務(wù)調(diào)度算法呢
嵌入式實(shí)時(shí)操作系統(tǒng)VxWorks內(nèi)核調(diào)度機(jī)制研究
嵌入式實(shí)時(shí)操作系統(tǒng)VxWorks內(nèi)核調(diào)度機(jī)制分析
嵌入式系統(tǒng)優(yōu)先級(jí)反轉(zhuǎn)問題的分析

嵌入式實(shí)時(shí)操作系統(tǒng)內(nèi)核的設(shè)計(jì)

嵌入式實(shí)時(shí)操作系統(tǒng)MQX內(nèi)核研究

評(píng)論