ขอคำแนะนำผู้ที่ใช้ IAR Embedded workbench ครับ

Started by viroj83, June 27, 2016, 02:08:38 PM

Previous topic - Next topic

viroj83

ตอนนี้ผมเริ่มเขียน ARM เป็นครั้งแรกครับใช้ชิพของ Freescale kinetis K50 ครับ IDE ที่ใช้คือ IAR Embedded workbench
พยายามเขียนโปรแกรมไฟกะพริบมาหลายวันแล้วยังไม่ได้เลยไม่เข้าใจการเข้าถึง register ในส่วนของการควบคุม GPIO ของชิพตัวนี้
และยังใช้ IDE ของ IAR ไม่เป็นครับรบกวนผู้รู้ช่วยแนะนำด้วยครับขอ Example code ไฟกะพริบง่ายๆสำหรับใช้เป็นตัวอย่างเพื่อต่อยอด
ด้วยครับ
ขอบคุณครับ

TaoTao

เบอร์นี้ ไม่เคยใช้ง่ะ
แต่ ลองตรวจสอบ initial ทาง Hardware ว่า ต่อครบหรือยัง
และ Initail ทาง ซอฟแวร์ เช่น คล็อก ว่าเซ็ตไว้ถูกต้องหรือเปล่า

ผมเอง หลักๆ ตอนนี้ใช้ STM32 อยู่หลายเบอ

ครั้งแรกที่เทส
ผมมักจะสั่งให้ pin มันส่งออก เป็น 0 บ้าง 1 บ้าง
ผมตั้งจุดเบรกพ้อย แล้วเอามิเตอจิ้มวัดที่ pin นั้นๆ เลย
ถ้าไฟ มันออกตามที่เราตั้งไว้ ก็จบ สำหรับชิบเบอร์ที่ใช้

อาจดูง่าย และพื้นฐาน มั่กๆ แต่ผมทำแค่นี้ จริงๆ ครับ

แต่ถ้าไฟที่ pin ไม่ออกตามที่เราเซ็ต
คงต้องย้อนกลับไปตรวจสอบ initial ทั้ง hardware ที่ดาต้าชีท
และพวก initial / header file และการ คอนฟิกพิน ที่ Reference Manual แล้วแหล่ะ

ซึ่ง ถ้าเริ่มจับทางได้แล้ว การเปลี่ยนเบอ หรือ เปลี่ยนซีรี่
ไม่ใช่ปัญหาเลยครับ ผมว่า มันแทบไม่ต่างกันเลย

เดี๋ยวก็ได้ครับ
😁

TaoTao

อ้อ ชิบหลายๆ ตัว มีขา Boot ด้วยนะครับ
ต้อง initial ขานี้ เพื่อสั่งให้มัน Boot จากอะไร
โดยการ pull up หรือ pull down ด้วย R
ผมแถม C decouple noise ด้วยอีกตัว เพราะเจ็บใจ

เนื่องจากครั้งแรกเริ่มเลย  หลังจาก เบินชิปแล้ว
มันทำงานบ้าง ไม่ทำงานบ้าง
มึนอยู่ครึ่งวัน เพราะลืมขานี้ไป

พอดู ดาต้าชีทอีกรอบ เห็นขานี้ ถึงบางอ้อเลย
;D


viroj83

ตรวจสอบ Hardware แล้วไม่มีปัญหาครับพอดีมีไฟล์ .out โปรแกรมตัวอย่างอยู่ครับลองโปรแกรมแล้วทำงานได้ปกติครับ
ตอนนี้ติดปัญหาคือไม่เข้าใจโครงสร้างในการเขียนโปรแกรม ARM Core อะครับว่ามันต้องมีองค์ประกอบอะไรบ้างการที่จะ
ทำให้ GPIO มันทำงานมันต้อง set register อะไรบ้างแล้ว start up file มีไว้ทำอะไรมันทำงานยังไงการทำ GPIO
memory map ต้องทำยังไงแล้วการ set clock ต้อง set แยกแต่ละ GPIO หรือเปล่าหรือว่า set ครั้งเดียวใช้ร่วมกัน
ทั้ง system เหมือน set clock ให้กับ controller 8 bit ทั้วไปหรือเปล่าอยากขอคำแนะนำต่อครับว่าถ้าผมจะเริ่มเขียน
โปรแกรมไฟกะพริบให้กับ ARM Controller coretex-M4 ผมต้องเริ่มยังไงต้องใช้ไฟล์อะไรประกอบบ้าง

ขอขอบคุณสำหรับทุกๆคำแนะนำครับ

wlasoi

ARM cortex  หรือ  แม้แต่ CPU32  bit  ตระกูลใหม่ๆ  ไม่เหมือนพวก  8 bit  ที่เข้าถึง  ขา IO  ได้โดยตรง ... ขา IO มันจะถูกแยกออกจากกันจาก  peripheral  ต่างๆิจะใช้งานได้ต้อง MAP ผ่าน ระบบ BUS ซึ่ง BUs ของ ARM มีอยู่ 2 ชนิด ต้องเข้าใจโครงสร้างมันก่อน

เอาง่ายๆว่าจะใช้งาน uart  ก่อนใช้งานต่องกำหนดขา IO ก่อนว่าจะใช้ขาไหน  มันไม่ได้ต่อไว้ ต้องกำหนดที่ Bus รวมทั้งพวก  clock  ต่าวๆของ  bus ก็ต้องกำหนดด้วย จะใช้ตรงๆไม่ได้ต้อง  แพร์สาย (ในระบบ memory map)  เข้าหากันก่อน

กรณีใช้งานเป็นแค่ IO --> PORTA , PIN5

void LED_Initialize (void){

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
}


กรณีต้อง MAP ใส่ peripheral อื่นๆ เช่น External Interrupt --> PORTA , PIN4



static void EXTILine4_Config(void)
{
   //port
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 

GPIO_InitStructure4.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure4.GPIO_PuPd = GPIO_PuPd_DOWN;
  //pin
GPIO_InitStructure4.GPIO_Pin = GPIO_Pin_4;
//port
GPIO_Init(GPIOA, &GPIO_InitStructure4);

//port
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource4);

//pin
EXTI_InitStructure4.EXTI_Line = EXTI_Line4;
EXTI_InitStructure4.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure4.EXTI_Trigger = EXTI_Trigger_Rising; 
EXTI_InitStructure4.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure4);

NVIC_InitStructure4.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStructure4.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure4.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure4.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure4);
}


สังเกตุ


  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

dec

"start up file มีไว้ทำอะไรมันทำงานยังไง"

ปกติ arm cortex m ก็จะเริ่มทำงานเหมือนกับ mcu ตัวอื่นๆ คือเริ่ม execute จาก address 0x00000000 (ใส่ offset ได้)
แต่ในบาง mcu นั้น address 0x00000000 นั้นจะเป็น address ที่ไม่ได้มี memory อยู่จริง เป็นแค่ address ที่ใช้ในการ
remap เท่านั้น สังเกตง่ายๆ mcu พวกนี้จะมี pin boot0, boot1 เช่น stm32 ถ้าต่อ pin boot0 ลง gnd จะ remap
address 0x00000000 ไปที่ address 0x08000000 ซึ่งเป็น internal flash ถ้าต่อ VDD จะ remap address ไปที่
0x20000000 ซึ่งก็คือ internal ram ถ้ามี boot1 ก็ remap ไป external ram ได้ด้วย แต่สำหรับ kinetis ผมดูจาก code
ของ k60 แล้วน่าจะไม่มีการ remap address เพราะมัน flash code ลง address 0x00000000 โดยตรงเลย



เพราะฉะนั้น address 0x00000000 ที่กล่าวถึงนี้อาจเป็น address แรกของ flash หรือ ram ก็ได้ ตามที่
mcu remap ไป

arm cortex m เริ่ม execute ที่ address 0x00000000 ก็จริง แต่มันก็มีบางอย่างที่ต้องทำเป็นอันดับแรกคือ

1. กำหนดค่า stack pointer - เมื่อเริ่มจ่ายไฟ arm cortex m core เริ่มทำงาน มันจะ fetch ข้อมูลจาก address
0x00000000 ขนาด 4 Bytes เอาไปใส่ใน stack pointer register (R13)

2. กำหนดค่า program counter - หลังจากกำหนดค่า stack pointer ก็จะ fetch ข้อมูลจาก address
0x00000004 ขนาด 4 Bytes เอาไปใส่ใน program counter register (R15)
ค่าใน address 0x00000004 เรามักจะเรียกกันว่า reset vector มันเป็นค่า address ของ function
แรกที่จะเริ่มทำงาน หรือเวลาทำการ software reset มันก็จะ jump มาที่ function นี้เช่นกัน บางทีอาจชื่อว่า startup
อะไรประมาณนี้ ส่วน address 0x00000008 และต่อจากนี้ก็จะเป็น interrupt vector อื่นๆ ต่อไป
โดยประมาณ 15 - 16 ตัวแรกจะเป็นของ arm cortex m core หลังจากนั้นจะเป็นของ peripheral
ก็จะแตกต่างไปตามแต่ละชิป



ในทางปฏิบัติการเขียน vector table ก็คือเขียน array ของ address ของ function interrupt ต่างๆ
แล้วก็สั่งให้ linker เอาตัวแปรนี้ไปไว้ที่ address 0x00000000 หรือ address แรกของ flash ก็ว่าไป



3. เริ่มทำงาน - cpu ก็จะเริ่มประมวลผลตาม code ตำแหน่งที่ program counter ชี้ไป ส่วนใหญ่ code ตรงนี้ก็จะทำการ initialize
ค่าที่สำคัญๆ เช่น master clock ของระบบ, init external ram (ถ้ามี), กำหนดค่าเริ่มต้นของพวกตัวแปร global,
เรียก constructor ของ static object กรณีใช้ c++ หลังจากนั้นค่อยเรียก function main



ปล. ผมไม่มีบอร์ด kinetis นะ ในรูป sim บน IAR เอา โดยเอา code มาจาก demo ของ FreeRTOS บนบอร์ด Kinetis K60 Tower
ปล.2 ส่วนการขับ GPIO ลองดดูลิ้งนี้ https://community.nxp.com/thread/353036 ผมว่าน่าจะลองผิดลองถูกได้ไม่ยาก
ตอนนี้อย่าพึ่งไป create project เองแบบเริ่มจาก 0 ลองเอา project ตัวอย่างมาตัด code ออก เหลือแต่ main (ยังไม่ต้องไปยุ่งกับ
startup files ใช้ default ของเค้าไปนั่นแหละ ปกติเค้ามักจะตั้งปรับ clock สูงสุดไว้แล้ว) แล้วลองเขียนคุม peripheral ดูก่อน
เรื่อง peripheral คงต้องพึ่ง datasheet และ google เพราะ kinetis มันไม่เป็นที่แพร่หลายในไทย พอเริ่มใช้ peripheral เป็นแล้ว
ค่อยลองพวก interrupt ต่อ เป็นแล้วค่อยไปลองเรื่องการปรับ clock

vbaserv

ขอบคุณครับ

อธิบายได้เคลียร์มากเลย

viroj83

ขอบคุณมากๆครับอธิบายได้ละเอียดมากจริงๆตอนนี้ผมพยายามศึกษา Example project ที่ติดมากับตัวโปรแกรม IAR ครับ Project getting started กับ Project GPIO แต่ผมไม่มี Debugger ก็เลยไม่รู้เลยว่าโปรแกรมที่ compile ผ่านแล้วมันทำงานได้จริงหรือเปล่ามีแต่ตัวโปรแกรมเมอร์ PALMiCE3 อยู่ตัวเดียวไม่รู้ว่ามันทำเป็น Debugger ได้หรือเปล่าแล้วบน IAR มันสามารถ simulation การทำงานของโปรแกรมที่เขียนโดยไม่ผ่าน Debugger ได้หรือเปล่าครับ