ตัวจัดการขัดจังหวะถูกนำไปใช้ใน CMSIS ของ Cortex M0 อย่างไร


9

ฉันมีชุด LPC1114 ไม่กี่วันที่ผ่านมาฉันได้ขุดการใช้งาน CMSIS ของ Cortex M0 เพื่อค้นหาสิ่งต่างๆ จนถึงตอนนี้ฉันเข้าใจว่าการลงทะเบียนแต่ละครั้งถูกทำแผนที่อย่างไรและฉันสามารถเข้าถึงได้อย่างไร แต่ถึงกระนั้นฉันก็ไม่รู้ว่ามีการใช้อินเทอร์รัปต์อย่างไร สิ่งที่ฉันรู้เกี่ยวกับการขัดจังหวะใน CMSIS คือมีบางชื่อตัวจัดการขัดจังหวะที่กล่าวถึงในไฟล์เริ่มต้น และฉันสามารถเขียนตัวจัดการของฉันเองโดยเพียงแค่เขียนฟังก์ชั่น C ที่มีชื่อเดียวกับที่ระบุในไฟล์เริ่มต้น สิ่งที่ทำให้ฉันสับสนคือในคู่มือผู้ใช้จะมีการบอกว่า GPIO ทั้งหมดสามารถใช้เป็นแหล่งขัดจังหวะภายนอก แต่มีอินเทอร์รัปต์ PIO เพียง 4 ตัวที่กล่าวถึงในไฟล์เริ่มต้น ดังนั้นบอกฉัน:

  1. ฉันจะใช้ตัวจัดการขัดจังหวะภายนอกสำหรับ GPIO อื่นได้อย่างไร
  2. ตารางขัดจังหวะอยู่ที่ไหนใน CMSIS
  3. อะไรคือความแตกต่างที่สำคัญระหว่าง NVIC และการติดตั้ง Interrupt ใน AVRs / PICs? (ยกเว้น NVIC สามารถทำแผนที่ได้ทุกที่ในแฟลช)

คำตอบ:


14

ข้อมูลต่อไปนี้เป็นคำตอบที่ยอดเยี่ยมของ Igor

จากเปอร์สเปคทีฟการเขียนโปรแกรม C ตัวจัดการขัดจังหวะถูกกำหนดในไฟล์ cr_startup_xxx.c (เช่นไฟล์ cr_startup_lpc13.c สำหรับ LPC1343) ตัวจัดการขัดจังหวะที่เป็นไปได้ทั้งหมดถูกกำหนดไว้ที่นั่นเป็นนามแฝงที่อ่อนแอ หากคุณไม่ได้กำหนด XXX_Handler () ของคุณเองสำหรับแหล่งขัดจังหวะฟังก์ชันตัวจัดการขัดจังหวะเริ่มต้นที่กำหนดไว้ในไฟล์นี้จะถูกนำมาใช้ ตัวเชื่อมโยงจะเรียงลำดับฟังก์ชันที่จะรวมในไบนารีสุดท้ายพร้อมกับตารางเวกเตอร์ขัดจังหวะจาก cr_startup_xxx.c

ตัวอย่างของการขัดจังหวะ GPIO จากพอร์ตจะแสดงในไฟล์สาธิตใน gpio.c มีอินพุตอินเตอร์รัปต์หนึ่งสัญญาณไปยัง NVIC ต่อพอร์ต GPIO แต่ละบิตในพอร์ตสามารถเปิด / ปิดการใช้งานเพื่อสร้างการขัดจังหวะบนพอร์ตนั้น หากคุณต้องการการขัดจังหวะบนพอร์ต PIO1_4 และ PIO1_5 เช่นนั้นคุณจะเปิดใช้งานบิตการขัดจังหวะ PIO1_4 และ PIO1_5 แต่ละบิตใน GPIO0IE เมื่อ PIOINT0_Handler () ฟังก์ชั่นตัวจัดการขัดจังหวะของไฟไหม้ขึ้นอยู่กับคุณที่จะพิจารณาว่าการขัดจังหวะ PIO1_4 หรือ PIO1_5 ใด (หรือทั้งสองอย่าง) นั้นอยู่ในระหว่างรอดำเนินการโดยการอ่านการลงทะเบียน GPIO0RIS และจัดการขัดจังหวะอย่างเหมาะสม


10

(โปรดทราบว่าจุดที่ 1 และ 2 เป็นรายละเอียดการใช้งานและไม่ใช่ข้อ จำกัด ทางสถาปัตยกรรม)

  1. ในชิป NXP ที่ใหญ่กว่า (เช่น LPC17xx) มีหมุดอินเตอร์รัปต์สองสามตัว (EINTn) ซึ่งมีตัวจัดการขัดจังหวะของตัวเอง ส่วนที่เหลือของ GPIO ต้องใช้หนึ่งการขัดจังหวะทั่วไป (EINT3) จากนั้นคุณสามารถสำรวจสถานะการขัดจังหวะการลงทะเบียนเพื่อดูว่าหมุดใดที่กระตุ้นการขัดจังหวะ
  2. ฉันไม่คุ้นเคยกับ LPC11xx มากนัก แต่ดูเหมือนว่าจะมีหนึ่งอินเตอร์รัปต์ต่อพอร์ต GPIO คุณจะต้องตรวจสอบสถานะการลงทะเบียนอีกครั้งเพื่อหาพินที่ระบุ นอกจากนี้ยังมีมากถึง 12 พินที่สามารถทำหน้าที่เป็นแหล่งปลุก ฉันไม่แน่ใจว่าคุณสามารถขโมยพวกเขาเป็นขัดจังหวะทั่วไป (เช่นพวกเขาอาจจะถูกเรียกเมื่ออยู่ในสถานะสลีป)
  3. ตารางตัวจัดการเริ่มต้นถูกวางไว้ที่ที่อยู่ 0 (ซึ่งอยู่ในแฟลช) รายการแรกคือค่ารีเซ็ตสำหรับการลงทะเบียน SP รายการที่สองคือรีเซ็ตเวกเตอร์และส่วนที่เหลือเป็นข้อยกเว้นอื่น ๆ และเวกเตอร์ขัดจังหวะ สองสามตัวแรก (เช่น NMI และ HardFault) ได้รับการแก้ไขโดย ARM ส่วนที่เหลือเป็นเฉพาะชิป หากคุณต้องการเปลี่ยนเวกเตอร์ในขณะใช้งานจริงคุณสามารถทำการแมปใหม่เป็น RAM (ก่อนอื่นคุณต้องคัดลอกตาราง) ใน LPC11xx การแมปใหม่ได้รับการแก้ไขจนถึงจุดเริ่มต้นของ SRAM (0x10000000) ชิปอื่นสามารถมีความยืดหยุ่นมากขึ้น
  4. NVIC ได้รับการปรับปรุงเพื่อการจัดการขัดจังหวะที่มีประสิทธิภาพ:
    • ระดับความสำคัญที่ตั้งโปรแกรมได้ 0-3 สำหรับการขัดจังหวะแต่ละครั้ง อินเทอร์รัปต์ที่มีลำดับความสำคัญสูงกว่าจะจับไว้ที่ลำดับความสำคัญต่ำกว่า (การซ้อนกัน) การดำเนินการของลำดับความสำคัญต่ำกว่าดำเนินต่อเมื่อการขัดจังหวะลำดับความสำคัญสูงกว่าเสร็จสิ้น
    • สแต็คอัตโนมัติของสถานะโปรเซสเซอร์ในรายการอินเตอร์รัปต์ สิ่งนี้ช่วยให้การเขียนตัวจัดการขัดจังหวะโดยตรงใน C และขจัดความจำเป็นในการห่อหุ้มแอสเซมบลี
    • การผูกมัดแบบหาง: แทนที่จะ popping และผลักดันสถานะอีกครั้งการขัดจังหวะที่ค้างอยู่ถัดไปจะถูกจัดการทันที
    • มาถึงล่าช้า: หากการขัดจังหวะที่มีลำดับความสำคัญสูงกว่ามาถึงในขณะที่สแต็คสถานะโปรเซสเซอร์จะถูกดำเนินการทันทีแทนที่จะเป็นสถานะที่ค้างอยู่ก่อนหน้านี้

เนื่องจากคุณคุ้นเคยกับ PIC โปรดดูที่แอพนี้หมายเหตุ: การ โยกย้ายจาก PIC Microcontrollers ไปยัง Cortex-M3

มันเกี่ยวกับ M3 แต่คะแนนส่วนใหญ่ใช้กับ M0 ด้วย


8

คำตอบของ Austin และ Igor นั้นมีรายละเอียดเพียงพอ อย่างไรก็ตามฉันต้องการตอบมันด้วยวิธีอื่นบางทีคุณอาจเห็นว่าเป็นประโยชน์

LPC11xx (Cortex-M0) มี 4 ระดับสำหรับพิน GPIO, พินทั้งหมดจาก GPIO0.0 ถึง GPIO0.n แบ่งปันหมายเลขอินเตอร์รัปต์เดียวกันและพินทั้งหมดจาก GPIO3.0 ถึง GPIO3.m ใช้หมายเลขอินเตอร์รัปต์เดียวกัน

มีหกขั้นตอนในการเริ่มต้นการขัดจังหวะ GPIO ใน LPC11xx

  1. ตั้งค่าฟังก์ชั่นพินโดยการแก้ไข Pin Connection Block Registers
  2. ตั้งค่าทิศทางเข็มหมุดโดยการแก้ไขการลงทะเบียนทิศทางข้อมูล GPIO (ค่าเริ่มต้นคืออินพุต)
  3. ตั้งค่าการขัดจังหวะสำหรับแต่ละพินแต่ละครั้งคุณต้องไปที่ GPIO อินเตอร์รัลมาสก์ลงทะเบียน GPIOnIE และตั้งค่าบิต (ที่สอดคล้องกับพิน) ลอจิก 1
  4. ตั้งค่าการขัดจังหวะเพื่อเพิ่มขอบหรือลดลงหรือทั้งสองโดยการปรับเปลี่ยนความรู้สึกขัดจังหวะ GPIO ลงทะเบียน GPIOnIBE และ GPIOnIS
  5. เปิดใช้งานแหล่งสัญญาณขัดจังหวะไม่ว่าจะเป็น PIO_0 / PIO_1 / PIO_2 / PIO_3 ใน Nested Vectored Interrupt Control โดยใช้ฟังก์ชั่น CMSIS
  6. ตั้งค่าลำดับความสำคัญของอินเตอร์รัปต์โดยใช้ฟังก์ชัน CMSIS

การติดตั้งโค้ด คุณต้องการสองฟังก์ชัน: หนึ่งค่าเริ่มต้น 6 ขั้นตอนข้างต้นและอย่างที่สองคือตัวจัดการขัดจังหวะซึ่งจำเป็นต้องมีชื่อเดียวกับตัวจัดการที่กำหนดไว้ในรหัสเริ่มต้นstartup_LPC11xx.sไฟล์ ชื่อมาจากการPIOINT0_IRQHandler PIOINT3_IRQHandlerหากคุณใช้ชื่ออื่นคุณจะต้องเปลี่ยนชื่อในไฟล์เริ่มต้น

/*Init the GPIO pin for interrupt control */
void GPIO_Init(){
    LPC_IOCON-> =..              //Pin configuration register
    LPC_GPIO1->FIODIR = ...      //GPIO Data direction register
    LPC_GPIO1->FIOMASK = ..      //GPIO Data mask register - choose  the right pin
    LPC_GPIO1->GPIOnIE = ..      //Set up falling or rising edge 
    NVIC_EnableIRQ(PIO_1);       //Call API to enable interrupt in NVIC
    NVIC_SetPriority(PriorityN); //Set priority if needed
}


/*Must have the same name as listed in start-up file startup_LPC11xx.s */
void PIOINT1_IRQHandler(void){
   //Do something here
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.