Keil MDK + Arduino DUE + FreeRTOS

<rawat.s>
10 min readMar 1, 2021

--

​ ​ ​

บทความนี้สาธิตการใช้งานซอฟต์แวร์ Keil MDK (MDK-Lite) เขียนโค้ดภาษา C สำหรับไมโครคอนโทรลเลอร์ ATSAM3X8E (Arm Cortex-M3) โดยเลือกใช้บอร์ด Arduino DUE ทดสอบการทำงานของโค้ด และใช้ ST-Link/V2 Debugger เป็นอุปกรณ์ในการอัปโหลดไฟล์ .hex ไปยังชิปไมโครคอนโทรลเลอร์ ผ่านทาง SWD (Serial Wire Debug) และเปรียบเทียบกับการใช้งาน Arduino IDE สำหรับการใช้งาน FreeRTOS Library (for Arduino DUE)

รูป: Arduino DUE Pinout

โค้ดทดสอบการทำงานโดยใช้ Arduino IDE

​ ​ ​

แนะนำให้ลองใช้บอร์ด Arduino DUE โดยเขียนโค้ด Arduino Sketch หากยังไม่เคยใช้งานบอร์ดนี้มาก่อน

ในการคอมไพล์โค้ดตัวอย่างนี้ ให้ใช้ Arduino IDE และเลือกบอร์ดเป็น Arduino DUE (Programming Port) และเชื่อมต่อบอร์ด Arduino DUE กับคอมพิวเตอร์ผู้ใช้ผ่านทาง USB

// Board: Arduino DUE with SAM3X8E#define LED1_PIN  73 // TX_LED = PA21
#define LED2_PIN 72 // RX_LED = PC30
void setup() {
Serial.begin( 115200 );
pinMode( LED_BUILTIN, OUTPUT );
pinMode( LED1_PIN, OUTPUT );
pinMode( LED2_PIN, OUTPUT );
digitalWrite( LED_BUILTIN, LOW ); // turn off
}
void loop() {
static int state = 0;
static uint32_t cnt = 0;
static char sbuf[32];
digitalWrite( LED1_PIN, state );
digitalWrite( LED2_PIN, !state );
state ^= 1; // toggle state
sprintf( sbuf, "cnt: %u\r\n", cnt++ );
Serial.print( sbuf );
delay(100);
}

ตรวจสอบดูก่อนว่า ได้ติดตั้ง Arduino SAM Boards ใน Arduino Boards Manager แล้วหรือไม่

ถัดไปให้ติดตั้ง FreeRTOS Library สำหรับ Arduino DUE (https://github.com/bdmihai/DueFreeRTOS) โดยให้ดาวน์โหลดมาเป็นไฟล์ .ZIP แล้วนำไปแตกไฟล์ภายใต้ไดเรกทอรีของ Arduino ที่มีชื่อว่า libraries แล้วเริ่มต้นใช้งาน Arduino IDE ใหม่อีกครั้ง

ทดลองโค้ดตัวอย่างต่อไปนี้

#include <FreeRTOS.h> // https://github.com/bdmihai/DueFreeRTOS
#include "task.h"
#define NUM_TASKS (2)const int LED_PINS[NUM_TASKS ] = {72,73}; // RXLED, TXLED
const char* TASK_NAMES[ NUM_TASKS ] = {"T0","T1"};
TaskHandle_t taskHandles[ NUM_TASKS ];
void task( void *pvParameters );void setup() {
for (int i=0; i < NUM_TASKS; i++ ) {
xTaskCreate( task, TASK_NAMES[i],
128, (void *)i,
tskIDLE_PRIORITY+1, &taskHandles[i] );
}
vTaskStartScheduler(); // start the scheduler
}
void loop() {} // idlevoid task( void *pvParameters ) {
int id = (int)pvParameters;
int pin = LED_PINS[id];
int state = (id==0) ? 0 : 1;
pinMode( pin, OUTPUT );
while(1) {
state ^= 1; // toggle the state
taskENTER_CRITICAL();
digitalWrite( pin, state ); // update output pin
taskEXIT_CRITICAL();
vTaskDelay( 100 /*ticks*/ );
}
}

ตัวอย่างนี้สาธิตการสร้างทาสก์สำหรับ FreeRTOS จำนวน 2 ทาสก์ ซึ่งจะทำให้ LED บนบอร์ด Arduino DUE กระพริบได้ (ตรงกับขาหมายเลข 72 และ 73 ตามลำดับ)

ลองศึกษาดูตัวอย่างต่อไปนี้ ซึ่งสาธิตการใช้ FreeRTOS Library และมีการสร้างทาสก์หลาย ๆ ทาสก์และมีการส่งข้อมูลกันระหว่างทาสก์ โดยใช้ FreeRTOS Queue

https://github.com/bdmihai/DueFreeRTOS/blob/master/examples/arduino-due-oled-encoder/arduino-due-oled-encoder.ino

การเขียนโค้ดโดยใช้ MDK-Lite / uVision IDE

​ ​ ​

เริ่มต้นด้วยการเปิดใช้งาน MDK uVision IDE และถ้ายังไม่ได้ติดตั้ง Software Pack (Atmel:SAM3X_DFP) สำหรับไมโครคอนโทรลเลอร์ตระกูลนี้ ก็ให้ติดตั้งก่อนทำขั้นตอนถัดไป โดยใช้ Pack Installer ของ MDK

การสร้างโปรเจกต์ใหม่

​ ​ ​

ถัดไปเป็นการสร้างโปรเจกต์ใหม่ กำหนดชื่อและไดเรกทอรีที่ต้องการสร้างและใช้งาน

เลือกไมโครคอนโทรลเลอร์ที่จะใช้งาน ซึ่งก็คือ ATSAM3X8E

ขั้นตอนถัดไปเป็นการเลือกใช้คอมโพเนนต์ต่าง ๆ ในส่วนที่เรียกว่า Run-Time Environment (RTE) และให้เลือกคอมโพเนนต์ดังนี้

  • CMSIS CORE
  • Device Startup

จากนั้นคลิกปุ่ม OK

เมื่อสร้างโปรเจกต์ใหม่แล้ว ถัดไปให้สร้างและเพิ่มไฟล์ main.c โดยเลือกจาก User Code Template ดังนี้

จากนั้นเปิดไฟล์ main.c เพื่อแก้ไขโค้ดตามตัวอย่าง

รูป: การเขียนโค้ดในไฟล์ main.c
#include "sam.h"// onboard LED pin
#define PIO_LED_PIN PIO_PB27
// global variables
static volatile uint32_t ms_ticks = 0U;
// function prototypes
static void led_init(void);
void SysTick_Handler(void) {
ms_ticks++; // Increment the tick counter
}
static void __delay_ms( uint32_t msec ) {
uint32_t start_ticks = ms_ticks;
while (ms_ticks - start_ticks < msec) {}
}
int main(void) {
// Initialize the SAM system
SystemInit();
// Disable WDT
WDT->WDT_MR = WDT_MR_WDDIS;
// Set up SysTick Timer for 1 msec interrupts.
if (SysTick_Config(SystemCoreClock /1000UL)) {
while (1) {} // error handler
}
// Initialize the LED pin
led_init();
while (1) { // LED toggle
if (PIOB->PIO_ODSR & PIO_PB27) { // Is PIO_PB7 high ?
PIOB->PIO_CODR = PIO_LED_PIN; // Clear bit
} else{
PIOB->PIO_SODR = PIO_LED_PIN; // Set bit
}
__delay_ms(500);
}
}
static void led_init(void) {
// Enable peripheral clock for PIOB
PMC->PMC_PCER0 = (1 << ID_PIOB);
PIOB->PIO_PER = PIO_LED_PIN;
PIOB->PIO_OER = PIO_LED_PIN;
PIOB->PIO_OWER = PIO_LED_PIN;
}

ข้อสังเกต: โดยทั่วไป การเขียนโปรแกรมสำหรับ ATSAM3X8E หรือไมโครคอนโทรลเลอร์ที่ใช้ซีพียูตระกูล ARM Cortex-M ของบริษัท Atmel เราก็มักจะใช้ API ที่เรียกว่า Atmel Software Framework (ASF) เวอร์ชัน 3 (ASF) หรือ 4 (ASF4) แต่ในบทความนี้ ไม่ได้ใช้ ASF ในการเขียนโค้ด

โค้ดตัวอย่างนี้จะทำให้ LED ที่ขา GPIO Port B Pin 27 (PIO_PB27) กระพริบได้ โดยเลือกใช้วงจร 12MHz Crystal Oscillator ที่อยู่บนบอร์ด เป็นแหล่งที่มาของสัญญาณ Clock แล้วไปผ่านวงจร PLL ที่อยู่ภายใน เพื่อให้ได้ความถี่ 84 MHz และตัวแปร SystemCoreClock จะมีค่าเท่ากับ 84000000

การเรียกใช้ฟังก์ชัน SysTick_Config() ในโค้ดตัวอย่าง เป็นการเปิดใช้งาน SysTick Timer ของซีพียู และตั้งค่าให้เกิดอินเทอร์รัพท์ทุก ๆ 1 มิลลิวินาที และจะเพิ่มค่าของตัวแปร ms_ticks ครั้งละหนึ่ง

การคอมไพล์โค้ดและรันโค้ดในฮาร์ดแวร์

​ ​ ​

เมื่อได้แก้ไขโค้ดตามตัวอย่างแล้ว ถัดไปลองคอมไพล์โค้ด (ทำขั้นตอน Build Target) และคอมไพล์เลอร์ที่ใช้งานคือ ARM Compiler v6 (armclang) เวอร์ชันที่ใช้คือ v6.15

ถ้าต้องการอัปโหลดไฟล์ที่ได้จากการคอมไพล์สำเร็จแล้ว ไปยังบอร์ดไมโครคอนโทรลเลอร์ เราจะใช้อุปกรณ์ เช่น ST-Link/v2 Programmer / Debugger ซึ่งมีราคาถูก หรือจะใช้อุปกรณ์ประเภท CMSIS-DAP Compatible Debug Probe ก็ได้ เชื่อมต่อกับบอร์ดโดยใช้อินเทอร์เฟสที่เรียกว่า SWD (Serial Wire Debug)

ความยุ่งยากของการใช้งาน SWD สำหรับบอร์ด Arduino DUE คือ คอนเนกเตอร์สำหรับ JTAG/SWD ที่ขาแบบ 2x5 ซึ่งมีขนาดเล็ก ต้องใช้อุปกรณ์เสริม เป็นสายแปลงคอนเนกเตอร์ให้สามารถเชื่อมต่อกับขาหรือ Pin Headers ที่มีระยะห่าง 2.54mm. ของอุปกรณ์ ST-Link Debugger

ถ้าใช้อุปกรณ์ที่เป็น CMSIS-DAP Debugger ให้ตั้งค่าใช้งานดังนี้

และถ้ากดปุ่ม Settings ก็จะเห็นรายละเอียดของอุปกรณ์ที่กำลังเชื่อมต่ออยู่กับคอมพิวเตอร์ผู้ใช้

​ ​ ​

ข้อสังเกต: เมื่อเสียบสายเชื่อมต่อระหว่าง 2x5 JTAG/SWD Connector บนบอร์ด Arduino DUE กับอุปกรณ์ ST-Link Debugger หรือ CMSIS-DAP Debugger แล้ว จะต้องเสียบสาย microUSB เชื่อมต่อพอร์ตที่เรียกว่า USB Programming Port ของ Arduino DUE กับคอมพิวเตอร์ของผู้ใช้ด้วย เพื่อใช้สำหรับจ่ายแรงดันไฟเลี้ยงให้บอร์ด

ในตัวอย่างนี้ เราจะใช้ ST-Link Debugger เพื่ออัปโหลดไฟล์ .hex ไปยังบอร์ดไมโครคอนโทรลเลอร์ และให้ตรวจสอบการตั้งค่าใช้งานก่อนดังนี้

​ ​ ​

ถ้าจะรันโค้ดโดยใช้ In-Circuit Debugging ก็ให้เลือก ST-Link Debugger (แทนที่การใช้ Simulator)

เมื่อได้อัปโหลดโปรแกรมไปยังบอร์ดได้แล้ว (ทำขั้นตอน Flash > Download) จะเห็นว่า LED บนบอร์ดจะกระพริบ (หรือลองกดปุ่มรีเซตที่อยู่ตรงมุมของบอร์ด Arduino DUE)

ถัดไปก็ให้ลองทำขั้นตอน Debug > Start/Stop Debug Session และให้ลองกำหนดตำแหน่งหรือบรรทัดในโค้ด เพื่อใช้เป็น Breakpoint(s)

เมื่อรันโค้ดใน Debug Session ก็จะไปหยุดในตำแหน่งของ Breakpoint ถัดไป ซึ่งสังเกตได้จากบรรทัดที่มีวงกลมสีแดงอยู่ข้างหน้า

การจำลองการทำงานของโค้ดโดยใช้ Simulator

​ ​ ​

การใช้งาน Simulator เพื่อรันโค้ดตัวอย่าง โดยไม่ใช้อุปกรณ์ฮาร์ดแวร์ใด ๆ ก็สามารถทำได้ แต่จะต้องมีการแก้ไขและตั้งค่าการใช้งานให้เหมาะสมก่อน (แตกต่างจากการใช้ฮาร์ดแวร์)

ให้เลือกเป็น “Use Simulator” แทนการใช้ “Use ST-Link Debugger”

​ ​ ​

สร้างไฟล์ debug.ini (Initialization File) ในโปรเจกต์ แล้วเพิ่มข้อความบรรทัดต่อไปนี้ลงในไฟล์ดังกล่าว

MAP 0x40000000, 0x400FFFFF READ WRITE

หรือจะกำหนดช่วงแอดเดรส (Map Range) ในหน้าต่าง Memory Map ก็ได้ เมื่อเข้าสู่ Debug Session

ให้เปิดไฟล์ system_SAM3XA.c แล้วแก้ไขค่าของพารามิเตอร์ PMC_SETUP จากเดิมที่มีค่า 1 ให้เป็น 0

การแก้ไขดังกล่าว จะทำให้ความถี่ของระบบลดลงจาก 84 MHz และใช้สัญญาณ Clock จากวงจร Internal RC Oscillator (EFRC_OSC) ภายใน ATSAM3X8E ซึ่งมีความถี่ 4MHz

ตั้งค่า Xtal ให้เท่ากับ 4MHz เพื่อให้ตรงกับความถี่ที่จะใช้ในการจำลองการทำงาน

จากนั้นก็คอมไพล์โค้ดในโปรเจกต์อีกครั้ง (Build Target) และทำเข้าสู่ Debug Session

เราสามารถดูการเปลี่ยนแปลงค่าของตัวแปร เช่น ms_ticks ได้ และกำหนดตำแหน่งของ Breakpoint ให้ตรงกับการทำงานของฟังก์ชัน SysTick_Handler() เมื่อเกิดอินเทอร์รัพท์จากการทำงานของ SysTick Timer ก็จะไปเรียกฟังก์ชันดังกล่าวที่ทำหน้าที่เป็น ISR (ในตัวอย่างนี้ จะเกิดอินเทอร์รัพท์ทุก ๆ 0.001 วินาที และค่าของตัวแปร ms_ticks จะเพิ่มขึ้นทีละหนึ่ง ทุก ๆ 0.001 วินาที เช่นกัน

โค้ดตัวย่างเพิ่มเติม: การส่งข้อความทาง Serial

​ ​ ​

บนบอร์ด Arduino DUE มีวงจร ATmega32U2 ทำหน้าที่เป็น USB-to-Serial และเชื่อมต่อกับขา ขา PA8 (D0 Pin) และ PA9 (D1 Pin) ของ ATSAM3X8E ที่ใช้เป็นขา RX0 และ RX0 ตามลำดับ

โดยทั่วไปแล้ว ก็จะใช้ช่องทางนี้อัปโหลด Arduino Sketch จาก Arduino IDE ในคอมพิวเตอร์ของผู้ใช้ ไปยังบอร์ดดังกล่าวผ่านทางสาย USB

โค้ดต่อไปนี้สาธิตการเปิดใช้งาน Serial และทดสอบการทำงานในลักษณะ Serial Loopback และแนะนำให้ทดสอบกับฮาร์ดแวร์จริงเท่านั้น

#include "sam.h"
#include <stdio.h>
// onboard LED pin
#define PIO_LED_PIN PIO_PB27
// global variables
static volatile uint32_t ms_ticks = 0U;
// function prototypes
static void led_init(void);
static void uart_init(uint32_t);
static void uart_write_str(const char *);
static void uart_write_char(char );
static char uart_read_char(void);
static uint32_t uart_is_tx_ready(void);
static uint32_t uart_is_rx_ready(void);

void SysTick_Handler(void) {
ms_ticks++; // Increment the tick counter
}
static void __delay_ms( uint32_t msec ) {
uint32_t start_ticks = ms_ticks;
while (ms_ticks - start_ticks < msec) {}
}
int main(void) {
// Initialize the SAM system
SystemInit();
// Disable WDT
WDT->WDT_MR = WDT_MR_WDDIS;
// Set up SysTick Timer for 1 msec interrupts.
if (SysTick_Config(SystemCoreClock /1000UL)) {
while (1) {} // error handler
}
// Initialize the LED pin
led_init();
// Initialize UART
uart_init(115200);
char sbuf[64];
__delay_ms(100);
sprintf( sbuf, "\r\nSystemCoreClock: %u Hz\r\n", SystemCoreClock);
uart_write_str( sbuf );
while (1) { // LED toggle
if (PIOB->PIO_ODSR & PIO_PB27) { // Is PIO_PB7 high ?
PIOB->PIO_CODR = PIO_LED_PIN; // Clear bit
} else{
PIOB->PIO_SODR = PIO_LED_PIN; // Set bit
}
if ( uart_is_rx_ready() ) { // serial loopback test
char ch = uart_read_char();
uart_write_char(ch);
}
__delay_ms(100);
}
}
static void led_init(void) {
// Enable peripheral clock for PIOB
PMC->PMC_PCER0 = (1 << ID_PIOB);
PIOB->PIO_PER = PIO_LED_PIN;
PIOB->PIO_OER = PIO_LED_PIN;
PIOB->PIO_OWER = PIO_LED_PIN;
}
static void uart_init(uint32_t baudrate) {
// Enable Clock for UART
PMC->PMC_PCER0 = (1 << ID_UART);
// Set pin in peripheral mode
PIOA->PIO_PDR = PIO_PA8;
PIOA->PIO_PDR = PIO_PA9;

// Select peripheral A
PIOA->PIO_ABSR &= ~PIO_PA8;
PIOA->PIO_ABSR &= ~PIO_PA9;

// Enable pull-ups
PIOA->PIO_PUER = PIO_PA8;
PIOA->PIO_PUER = PIO_PA9;

// UART clock divider
UART->UART_BRGR = (SystemCoreClock >> 4)/ baudrate;

// UART mode 8n1
UART->UART_MR = UART_MR_PAR_NO;

// Enable Receive and Transmit
UART->UART_CR = UART_CR_TXEN | UART_CR_RXEN;

// Disable UART interrupt
UART->UART_IER &= ~(UART_IER_RXRDY | UART_IER_TXRDY);
}
static uint32_t uart_is_tx_ready(void) {
return (UART->UART_SR & UART_SR_TXRDY);
}
static uint32_t uart_is_rx_ready(void) {
return (UART->UART_SR & UART_SR_RXRDY);
}
static void uart_write_char(char ch) {
UART->UART_THR = (uint32_t) ch;
}
static char uart_read_char(void) {
char ch = (char) UART->UART_RHR;
return ch;
}
static void uart_write_str(const char *str) {
while (*str != '\0') {
while (!uart_is_tx_ready());
uart_write_char(*str);
str++;
}
}

ตัวอย่างโค้ดนี้ได้ดัดแปลงมาจาก https://github.com/theolind/mahm3lib/

การเขียนโค้ดด้วย FreeRTOS

.

สร้างโปรเจกต์ใหม่ แต่คราวนี้ ให้เลือกคอมโพเนนต์ที่เป็น FreeRTOS อีกหนึ่งรายการ

​ ​ ​

โค้ดสำหรับทดสอบการทำงาน FreeRTOS ในเบื้องต้น

#include "sam.h"
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
// onboard LED pin
#define PIO_LED_PIN PIO_PB27
// function prototypes
static void led_init(void);
static void uart_init(uint32_t);
static void uart_write_str(const char *);
static void uart_write_char(char );
static char uart_read_char(void);
static uint32_t uart_is_tx_ready(void);
static uint32_t uart_is_rx_ready(void);
void vTask1( void *pvParameters ); // task entry function for Task1
void vTask2( void *pvParameters ); // task entry function for Task2
int main(void) {
// Initialize the SAM system
SystemInit();
// Disable WDT
WDT->WDT_MR = WDT_MR_WDDIS;
// Set up SysTick Timer for 1 msec interrupts.
// Initialize the LED pin
led_init();
// Initialize UART
uart_init(115200);
// Create Task 1
xTaskCreate( vTask1, "Task1",
configMINIMAL_STACK_SIZE,
(void*)NULL, tskIDLE_PRIORITY+1, NULL );
// Create Task 2 (with larger stack size !!!)
xTaskCreate( vTask2, "Task2",
4*configMINIMAL_STACK_SIZE+1, (void*)NULL,
tskIDLE_PRIORITY+1, NULL );
// Start the scheduler
vTaskStartScheduler();
while(1);
}
static void led_init(void) {
// Enable peripheral clock for PIOB
PMC->PMC_PCER0 = (1 << ID_PIOB);
PIOB->PIO_PER = PIO_LED_PIN;
PIOB->PIO_OER = PIO_LED_PIN;
PIOB->PIO_OWER = PIO_LED_PIN;
}
static void uart_init(uint32_t baudrate) {
// Enable Clock for UART
PMC->PMC_PCER0 = (1 << ID_UART);
// Set pin in peripheral mode
PIOA->PIO_PDR = PIO_PA8;
PIOA->PIO_PDR = PIO_PA9;

// Select peripheral A
PIOA->PIO_ABSR &= ~PIO_PA8;
PIOA->PIO_ABSR &= ~PIO_PA9;

// Enable pull-ups
PIOA->PIO_PUER = PIO_PA8;
PIOA->PIO_PUER = PIO_PA9;

// UART clock divider
UART->UART_BRGR = (SystemCoreClock >> 4)/ baudrate;

// UART mode 8n1
UART->UART_MR = UART_MR_PAR_NO;

// Enable Receive and Transmit
UART->UART_CR = UART_CR_TXEN | UART_CR_RXEN;

// Disable UART interrupt
UART->UART_IER &= ~(UART_IER_RXRDY | UART_IER_TXRDY);
}
static uint32_t uart_is_tx_ready(void) {
return (UART->UART_SR & UART_SR_TXRDY);
}
static uint32_t uart_is_rx_ready(void) {
return (UART->UART_SR & UART_SR_RXRDY);
}
static void uart_write_char(char ch) {
UART->UART_THR = (uint32_t) ch;
}
static char uart_read_char(void) {
char ch = (char) UART->UART_RHR;
return ch;
}
static void uart_write_str(const char *str) {
while (*str != '\0') {
while (!uart_is_tx_ready());
uart_write_char(*str);
str++;
}
}
void vTask1( void *pvParameters ) {
while (1) { // toggle LED
if (PIOB->PIO_ODSR & PIO_PB27) { // Is PIO_PB7 high ?
PIOB->PIO_CODR = PIO_LED_PIN; // Clear bit
} else{
PIOB->PIO_SODR = PIO_LED_PIN; // Set bit
}
vTaskDelay( 100 / portTICK_PERIOD_MS );
}
}
void vTask2( void *pvParameters ) {
char sbuf[32];
uint32_t cnt = 0;
sprintf( sbuf, "\r\nSystemCoreClock: %u Hz\r\n", SystemCoreClock);
uart_write_str( sbuf );
while (1) { // send a text line to serial every 1 second
sprintf( sbuf, "Count: %u\r\n", cnt++ );
uart_write_str( sbuf );
vTaskDelay( 1000 / portTICK_PERIOD_MS );
}
}

ข้อสังเกต: จะต้องแก้ไขไฟล์ FreeRTOSConfig.h ดังนี้

#define configUSE_TIMERS 1 // enable software timers in FreeRTOS

และเพิ่มขนาดของ Heap โดยแก้ไขพารามิเตอร์ configTOTAL_HEAP_SIZE เช่น ให้เป็น 16 KB (16* 1024)

และจะต้องแก้ไขการกำหนดค่าสำหรับพารามิเตอร์ configPRIO_BITS

#define configPRIO_BITS 4 // change from 3 to 4

ข้อสังเกต: ลองเปรียบเทียบกับการตั้งค่าสำหรับ FreeRTOS (DueFreeRTOS Library) บางส่วนดังนี้

ปัญหา: จากการทดสอบโค้ดตัวอย่างสำหรับ FreeRTOS โดยใช้บอร์ด Arduino DUE ก็สามารถทำงานได้ถูกต้อง (LED กระพริบ และได้รับข้อความจากบอร์ดผ่านทาง Serial) แต่หลังจากการทำขั้นตอน Flash > Download ได้พบปัญหาดังนี้

  • เมื่ออัปโหลดไฟล์ไปแล้ว จะต้องกดปุ่ม RESET บนบอร์ดก่อน และการอัปโหลดในครั้งถัดไป จะต้องกดปุ่ม ERASE บนบอร์ด Ardiuno DUE หนึ่งครั้ง
  • พบปัญหาในการทำขั้นตอน In-Circuit Debugging (ฮาร์ดแวร์ไม่ตอบสนองต่อการทำงานของ Software Debugger)

กล่าวสรุป

​ ​ ​

เราได้เห็นขั้นตอนการใช้งาน MDK-Lite ในการเขียนโค้ดสำหรับนำมาใช้งานกับบอร์ดไมโครคอนโทรลเลอร์ Arduino DUE ในเบื้องต้นแล้ว สามารถรันโค้ดได้ โดยใช้ฮาร์ดแวร์จริง หรือใช้ Simulator รวมถึงการทดลองใช้งาน FreeRTOS สำหรับบอร์ดนี้เช่นกัน

--

--

<rawat.s>
<rawat.s>

Written by <rawat.s>

I'm Thai and working in Bangkok/Thailand.

No responses yet