ทำไมไม่ใช้ DMA เพื่อขัดจังหวะกับ UART บน STM32 เสมอไป [ปิด]


9

ฉันใช้เวลาหลายเดือนในการทำให้ UART (สำหรับ MIDI) ทำงานกับ STM (STM32F103C8T6) โดยใช้การขัดจังหวะโดยไม่ประสบความสำเร็จมากนัก

อย่างไรก็ตามในเย็นวันนี้เมื่อใช้ DMA มันทำงานได้ค่อนข้างเร็ว

เนื่องจากเท่าที่ฉันอ่าน DMA นั้นเร็วขึ้นและบรรเทา CPU ทำไมไม่ใช้ DMA แทนการขัดจังหวะ? โดยเฉพาะอย่างยิ่งตั้งแต่บน STM32 ดูเหมือนว่าจะมีปัญหาค่อนข้างมาก

ฉันกำลังใช้ STM32CubeMx / HAL


2
ทำไมจะไม่ล่ะ? นั่นเป็นคำถามเกี่ยวกับความคิดเห็นใครที่กำลังเดาว่าเหตุผลทางเทคนิคที่เป็นไปได้หรือในลักษณะเดียวกันกว้างเกินไปและไม่ใช่คำถามที่เป็นของที่นี่ ในการตั้งชื่อตัวอย่างแบบสุ่ม DMA จะหมายถึงเวลาแฝงที่มากขึ้นในการอ้างสิทธิ์ข้อมูลโดยเฉพาะอย่างยิ่งเมื่อคุณไม่ได้รับผลประโยชน์ที่แท้จริงนอกจากคุณจะอนุญาตให้รวบรวมอักขระหลายตัว บ่อยครั้งที่อาจไม่เป็นไรบางครั้งอาจไม่ดี
Chris Stratton

6
หากการขัดจังหวะการทำงานใช้เวลาหลายสัปดาห์อาจเป็นเพราะคุณเข้าหางานในทางที่ผิด การทำให้ DMA ทำงานได้ดีอาจใช้เวลานานขึ้น - จริง ๆ แล้วมันเป็นงานที่ซับซ้อนกว่าดังนั้นความง่ายของงานที่ซับซ้อนมากกว่าที่ง่ายกว่าอย่างหนึ่งน่าจะมาจากแหล่งข้อมูลที่คุณใช้เพื่อเป็นแนวทางในการทำงานไม่ใช่กลไกเอง
Chris Stratton

5
อย่าสันนิษฐานว่า dma ปลดปล่อยซีพียูให้เป็นอิสระในบางครั้งก็ใช่ซีพียูยังคงทำงานต่อไปในบางครั้งไม่มีตัวประมวลผลใดถูกแช่แข็งให้เก็บบัสสำหรับเครื่องยนต์ dma สิ่งเล็กน้อยที่จะทำเช่นนี้กับการติดตั้งแขนดังนั้นไม่สามารถบอกได้ว่าแขนทุกแขนเป็นแบบนี้และ x86 ทั้งหมดนั้นเป็นแบบนั้นหรืออะไรก็ตามมันไม่ง่ายเลยคุณต้องตรวจสอบการออกแบบระบบเสมอ ชิปที่คุณมีอาจเพิ่มแกนแขนได้อย่างดีนี่เป็นเพียงความคิดเห็นเกี่ยวกับ dma เท่าที่คำถามของคุณไม่สมเหตุสมผลคุณไม่สามารถติดตามได้และ dma + int น่าจะเป็นทางออกที่สมบูรณ์หากคุณไม่สามารถสำรวจความคิดเห็น
old_timer

5
การขัดจังหวะจะค่อนข้างเล็กน้อยในพอร์ตอนุกรม STM32F ทำไมคุณไม่โพสต์คำถามด้วยรหัสของคุณเพื่อให้พวกเราบางคนพยายามที่จะจุดที่คุณจะผิด? ไม่มีความคิดที่ดีที่จะแฮกรหัสจนกว่ามันจะทำงานโดยที่ไม่เข้าใจว่าปัญหาที่เกิดขึ้นนั้นเป็นอย่างไร
Jon

7
จากความเห็นที่ถ่อมตนของฉันนี่เป็นข้อเสียอย่างหนึ่งในการใช้ Cube ที่น่ากลัวและบวม เขียนซอฟต์แวร์ตั้งแต่เริ่มต้นคุณจะได้เรียนรู้ว่า UART ทำงานอย่างไร (เพราะคุณต้องทำ) คุณจะเข้าใจอุปกรณ์ต่อพ่วงได้ดีขึ้นมากและในระยะยาวมันจะช่วยให้คุณประหยัดเวลาได้มาก
DiBosco

คำตอบ:


24

ในขณะที่ DMA ช่วยลด CPU และอาจลดความหน่วงแฝงของแอปพลิเคชั่นที่ทำงานด้วยการขัดจังหวะอื่น ๆ ที่ทำงานบนแกนเดียวกัน แต่มีค่าใช้จ่ายที่เกี่ยวข้อง:

  • มีแชนเนล DMA ในจำนวน จำกัดเท่านั้นและมีข้อ จำกัด เกี่ยวกับวิธีที่แชนเนลเหล่านั้นสามารถโต้ตอบกับอุปกรณ์ต่อพ่วงต่างๆ อุปกรณ์ต่อพ่วงอื่นในช่องทางเดียวกันอาจเหมาะกว่าสำหรับการใช้ DMA

    ตัวอย่างเช่นหากคุณมีการถ่ายโอน I2C จำนวนมากทุก 5 มิลลิวินาทีดูเหมือนว่าจะเป็นตัวเลือกที่ดีกว่าสำหรับ DMA มากกว่าคำสั่งการดีบักเป็นครั้งคราวที่มาถึง UART2

  • การตั้งค่าและบำรุงรักษา DMA นั้นเป็นต้นทุนด้วยตัวเอง (โดยปกติการตั้งค่า DMA นั้นซับซ้อนกว่าการตั้งค่าการถ่ายโอนข้อมูลอินเตอร์รัปต์แบบอักขระต่ออักขระเนื่องจากการจัดการหน่วยความจำอุปกรณ์ต่อพ่วงที่เกี่ยวข้องมากขึ้น DMA ใช้การขัดจังหวะตัวเองและความเป็นไปได้ที่คุณต้องแยกอักขระสองสามตัวแรกนอก DMA ยังไงดูด้านล่าง)

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

  • DMA ต้องการบัฟเฟอร์หน่วยความจำในการทำงานกับ (เว้นแต่ว่าคุณกำลังทำ DMA ต่อพ่วง) ดังนั้นจึงมีค่าใช้จ่ายหน่วยความจำบางส่วนที่เกี่ยวข้อง

    (ค่าใช้จ่ายหน่วยความจำอาจจะมีเมื่อใช้ขัดจังหวะต่อตัวละคร แต่มันอาจมีขนาดเล็กลงหรือหายไปเลยถ้าข้อความจะถูกตีความทันทีในการขัดจังหวะ)

  • DMA สร้างเวลาแฝงเนื่องจาก CPU จะได้รับแจ้งเมื่อการถ่ายโอนเสร็จสมบูรณ์ / เสร็จสมบูรณ์ครึ่งแล้ว (ดูคำตอบอื่น ๆ )

  • ยกเว้นเมื่อสตรีมข้อมูลเข้า / ออกจากบัฟเฟอร์บัฟเฟอร์คุณจำเป็นต้องรู้ล่วงหน้าว่าคุณจะรับ / ส่งข้อมูลจำนวนเท่าใด

    • นี่อาจหมายความว่าจำเป็นต้องประมวลผลอักขระตัวแรกของข้อความโดยใช้การขัดจังหวะแบบอักขระต่อตัวอักษรตัวอย่างเช่นเมื่อเชื่อมต่อกับ XBee คุณต้องอ่านประเภทและขนาดของแพ็คเก็ตก่อนจากนั้นจึงเรียกการถ่ายโอน DMA ลงในบัฟเฟอร์ที่จัดสรร

    • สำหรับโปรโตคอลอื่น ๆ สิ่งนี้อาจเป็นไปไม่ได้เลยหากใช้ตัวคั่นสิ้นสุดข้อความเท่านั้น: ตัวอย่างเช่นโปรโตคอลแบบข้อความที่ใช้'\n'เป็นตัวคั่น (ยกเว้นอุปกรณ์ต่อพ่วง DMA รองรับการจับคู่กับอักขระ)

อย่างที่คุณเห็นมีข้อเสียมากมายให้พิจารณาที่นี่ บางตัวเกี่ยวข้องกับข้อ จำกัด ของฮาร์ดแวร์ (จำนวนช่องสัญญาณความขัดแย้งกับอุปกรณ์ต่อพ่วงอื่น ๆ การจับคู่กับตัวอักษร) บางตัวขึ้นอยู่กับโปรโตคอลที่ใช้ (ตัวคั่นความยาวที่รู้จักบัฟเฟอร์หน่วยความจำ)

ในการเพิ่มหลักฐานเล็ก ๆ น้อย ๆ ฉันได้เผชิญหน้ากับการแลกเปลี่ยนทั้งหมดในโครงการงานอดิเรกซึ่งใช้อุปกรณ์ต่อพ่วงที่แตกต่างกันมากมายที่มีโปรโตคอลแตกต่างกันมาก มีการแลกเปลี่ยนบางอย่างที่ต้องทำส่วนใหญ่ตามคำถามที่ว่า "ฉันถ่ายโอนข้อมูลมากแค่ไหนและฉันจะทำเช่นนั้นบ่อยแค่ไหน?" สิ่งนี้จะช่วยให้คุณประเมินคร่าวๆเกี่ยวกับผลกระทบของการถ่ายโอนที่ใช้อินเตอร์รัปต์อย่างง่าย ๆ บน CPU ฉันจึงให้ความสำคัญกับการถ่ายโอน I2C ดังกล่าวข้างต้นทุก ๆ 5ms ผ่านการถ่ายโอน UART ทุกสองสามวินาทีซึ่งใช้แชนเนล DMA เดียวกัน การถ่ายโอน UART อื่นเกิดขึ้นบ่อยครั้งและมีข้อมูลมากขึ้นในขณะที่การถ่ายโอน I2C ลำดับความสำคัญสูงกว่าซึ่งเกิดขึ้นได้ยากกว่า มันคือการแลกเปลี่ยนทั้งหมด

แน่นอนว่าการใช้ DMA นั้นมีข้อดีเช่นกัน แต่นั่นไม่ใช่สิ่งที่คุณต้องการ


ขอบคุณสำหรับคำตอบโดยละเอียดของคุณ MIDI จะเป็นส่วนที่สำคัญที่สุดดังนั้นฉันคิดว่า DMA เหมาะสำหรับมัน (แม้ว่าความเร็วจะต่ำ: 31250 บอด) ฉันมีช่อง DMA เพียงพอหลังจากนั้นฉันจะใช้ STM32 อีกตัวเมื่อใช้งาน 4 USART ฉันไม่ต้องการระงับ CPU เนื่องจากจะมีพลังงาน USB 5V และฉันต้องทำการประมวลผลระหว่างข้อความ (เพื่อประมวลผลข้อความในลูปหลัก) ฉันมี 256 ไบต์อ่านและบัฟเฟอร์การส่ง 256 ไบต์ ฉันสามารถเพิ่มได้ในภายหลังหากจำเป็น STM32f103c8t6 มี RAM 20 KB, STM ที่ฉันจะใช้ในที่สุดคือ 192 KB
Michel Keijzers

และคุณให้ความคิดที่ดีกับฉันในการปรับปรุง จนถึงตอนนี้ฉันมักจะอ่าน 1 ไบต์และตรวจสอบอย่างต่อเนื่องเมื่อได้รับข้อความที่สมบูรณ์ (MIDI) แต่ฉันสามารถอ่านไบต์แรกและขึ้นอยู่กับว่าส่วนใหญ่ขนาดเป็นที่รู้จักและสามารถขอส่วนที่เหลือ สิ่งนี้ทำให้ฉันมีบัฟเฟอร์ขนาดเล็กอีกอันหนึ่ง แต่ก็ไม่เป็นไร
Michel Keijzers

การอ่านไบต์เดียวด้วย DMA นั้นไม่มีประสิทธิภาพมาก สำหรับเวลาแฝงที่ต่ำกว่าและประสิทธิภาพที่สูงขึ้นให้ใช้การขัดจังหวะแต่ละอักขระจนกว่าคุณจะรู้ขนาดแล้วจึงเปลี่ยนไปใช้ DMA
Jonas Schäfer

ฉันมีปัญหามากมายในการใช้อินเตอร์รัปต์ (โดยไม่มี DMA) ฉันคิดว่าฉันจะใช้ 1 ไบต์ DMA ที่ได้รับและหลังจากนั้นฉันก็รู้ว่ามีกี่ไบต์ที่ฉันคาดหวังและทำตามคำขอ DMA เพื่อรับมากขึ้น
Michel Keijzers

6
นั่นอาจเป็นข้อผิดพลาด - คุณควรแก้ไขรหัสขัดจังหวะโดยไม่ใช้ DMA
Chris Stratton

10

โดยทั่วไปแล้วการใช้ DMA หมายความว่าคุณจะไม่ถูกขัดจังหวะในตัวละครทุกตัวอีกต่อไป แต่จะได้รับหลังจากที่ได้รับ "บัฟเฟอร์เต็ม" ของตัวอักษร (หรือส่งแล้ว) เท่านั้น สิ่งนี้จะเพิ่มเวลาแฝงของการประมวลผลตัวอักษรเหล่านั้น - ตัวอักษรแรกจะไม่ถูกประมวลผลจนกว่าจะได้รับตัวอักษรตัวสุดท้ายในบัฟเฟอร์

เวลาแฝงนี้อาจเป็นสิ่งที่ไม่ดีโดยเฉพาะอย่างยิ่งในแอปพลิเคชันที่มีความอ่อนไหวแฝงเช่น MIDI ซึ่งมี ms ไม่กี่ที่นี่และสามารถเพิ่มปัญหาการเล่นที่รุนแรงสำหรับการแสดงสด


สิ่งที่ฉันทำคือรับทีละ 1 ไบต์ (ดังนั้นบัฟเฟอร์ 'DMA' ของ 1 ไบต์) และหลังจาก DMA โทรกลับของหนึ่งไบต์นั้นทุกครั้งเพื่อเก็บไว้ในบัฟเฟอร์บัฟเฟอร์ที่ฉันจัดการด้วยตนเอง ในวงหลักของฉันฉันต้องการตรวจสอบข้อความ MIDI ที่สมบูรณ์และประมวลผลข้อความเหล่านั้น
Michel Keijzers

3
โดยทั่วไปแล้ว DMA จะใช้เพื่อรับหลายไบต์และขัดจังหวะเมื่อได้รับทั้งหมดเท่านั้น การขัดจังหวะหลังจากเพียงหนึ่งไบต์เป็นเรื่องปกติเมื่อไม่ได้ใช้ DMA ดังนั้นฉันจึงสงสัยว่า: อะไรคือสิ่งที่มีความซับซ้อนเป็นพิเศษในการใช้ DMA สำหรับสิ่งนั้น
Steve Melnikoff

5
@MichelKeijzers จากนั้นสิ่งที่คุณทำนั้นค่อนข้างจะเหมือนกันกับที่คุณทำในการใช้งานอินเตอร์รัปต์ที่ขับเคลื่อนด้วยความบริสุทธิ์ ดังนั้นจึงไม่มีประโยชน์ในการใช้ DMA ในกรณีนี้และปัญหาดั้งเดิมของคุณอาจไม่ได้รับการแก้ไขโดย DMA แต่โดยการเขียนรหัส (ISR, setup) ของคุณใหม่
JimmyB

@JimmyB ... ขอบคุณ ... อย่างไรก็ตามเนื่องจากคำตอบของโจนัสด้านล่างฉันจะปรับปรุงการอ่านไบต์จำนวนมากเนื่องจากข้อความยาว ฉันรู้สิ่งนี้หลังจากได้รับไบต์แรก (ในกรณีส่วนใหญ่) ยิ่งกว่านั้นมันจะมีประโยชน์มากขึ้นในการใช้ DMA ผ่านการขัดจังหวะ
Michel Keijzers

8

DMA ไม่ได้ใช้แทนการขัดจังหวะ - โดยทั่วไปจะใช้ร่วมกัน! หากคุณกำลังใช้ DMA เพื่อส่งข้อมูลผ่าน UART ตัวอย่างเช่นคุณยังต้องมีการขัดจังหวะเพื่อบอกคุณเมื่อการส่งเสร็จสมบูรณ์


จริงอยู่บางทีใน STM32 กลไกการขัดจังหวะ (pure non DMA) นั้นค่อนข้างงุ่มง่ามเมื่อเทียบกับ DMA โดยตรง
Michel Keijzers

2
@duskwuff ไม่จริง ๆ ; คุณสามารถสำรวจความคิดเห็นเพื่อดูว่า DMA เสร็จสิ้นแล้วและคุณอาจต้องการเพราะเหตุผลสำคัญประการหนึ่งสำหรับการใช้ DMA คือไม่ต้องกังวลกับพอร์ตอนุกรมจนกว่าโปรแกรมของคุณจะอยู่ในสถานะที่สามารถทำงานกับผู้รับได้ ข้อมูล. หรือสำหรับ DMA ขาออกคุณสามารถสำรวจเพื่อดูว่าเป็นไปได้หรือไม่ที่จะเพิ่มมากขึ้นในบัฟเฟอร์การส่ง
Chris Stratton

1
@MichelKeijzers: IDK ชิปเฉพาะ แต่โดยทั่วไปทางเลือกของ DMA ไม่ได้ขัดจังหวะอย่างแท้จริงมันเป็นโปรแกรม-IO (ที่คุณใช้คำสั่ง CPU เพื่ออ่าน / เขียนข้อมูลจาก / ลงทะเบียน I / O) ในตัวจัดการอินเทอร์รัปต์โดยทั่วไปคุณจะอ่านหนึ่งครั้งแล้วอาจจะอีกอันหนึ่งในกรณีที่ตัวละครเข้ามาในขณะที่คุณอ่านตัวแรก หรืออ่านจนกระทั่งบัฟเฟอร์ภายในว่างเปล่าหากมีบัฟเฟอร์ดังกล่าว เห็นได้ชัดว่าคุณต้องการการขัดจังหวะเพิ่มเติมสำหรับ PIO และตั้งค่าต่าง ๆ
Peter Cordes

@ChrisStratton จุดที่ดี ... จนถึงตอนนี้ฉันยังไม่ได้เช็คอินถ้าเป็นไปได้ที่จะส่งฉันเพิ่งส่งบางสิ่งบางอย่างไม่ได้ตรวจสอบว่ามันโอเค อาจเป็นได้ถ้าไม่ใช่ฉันลองอีกครั้งในภายหลัง
Michel Keijzers

@PeterCordes ดูเหมือนว่า STM32 จะมีอินเตอร์รัปต์เพียงพอสำหรับ DMA และฉันอ่านทุกครั้งที่มีเพียง 1 ไบต์ แม้แต่ STM32 ที่ง่ายที่สุด (F103c8t6) ก็มีพอร์ต DMA / อินเตอร์รัปต์เพียงพอ
Michel Keijzers

5

การใช้ DMA แนะนำคำถามและความท้าทายที่น่าสนใจนอกเหนือจากข้อควรพิจารณาอื่น ๆ ของการใช้อุปกรณ์ต่อพ่วงของ UART ฉันจะให้คุณตัวอย่าง: สมมติว่าคุณกำลังนั่งอยู่บนรถบัส RS485 (หรืออะไรก็ตาม) กับอุปกรณ์อื่น ๆ มีข้อความมากมายบนรถบัสบางข้อความมีไว้สำหรับ uC ของคุณบางข้อความไม่ใช่ นอกจากนี้สมมติว่าเพื่อนบ้านรถบัสเหล่านี้ทั้งหมดพูดโพรโทคอลข้อมูลที่แตกต่างกันซึ่งหมายถึงความยาวของข้อความจะแตกต่างกัน

บางคำถามที่เกิดขึ้นเมื่อใช้ DMA คือ:

  • ฉันจะขัดจังหวะเมื่อใด
    • DMA นั้นชอบที่จะขัดจังหวะเมื่อพวกเขาถ่ายโอนข้อมูลจำนวนที่กำหนดไว้เท่านั้น
    • คุณจะทำอย่างไรถ้าคุณไม่ได้รับข้อมูลมากพอที่จะทำให้ DMA หยุดชะงัก
  • ถ้าคุณได้รับข้อความบางส่วนเมื่อ DMA ขัดจังหวะ
  • บัฟเฟอร์ RX ของคุณมีลักษณะอย่างไร พวกมันเป็นเส้นตรงหรือเป็นวงกลม?
    • DMA สามารถเป็นผู้มีส่วนร่วมบัฟเฟอร์แบบไม่เชื่อฟังในแง่ที่ว่ามันเป็นไปตามขอบเขตของที่อยู่เท่านั้น

อย่างไรก็ตามเพียงแค่อาหารสำหรับความคิด


ขอบคุณสำหรับการพิจารณาเหล่านั้น ขณะนี้ฉันได้รับ 1 ไบต์และเก็บไว้ในบัฟเฟอร์วงแหวนเสมอเนื่องจากข้อความของฉัน (MIDI) สามารถมีความยาวต่างกันได้และฉันก็ไม่ทราบว่าจะรับอะไรต่อไป ในลูปหลักของฉันฉันตรวจสอบข้อความที่สมบูรณ์เพื่อประมวลผลพวกเขา (และถ้าเสร็จสมบูรณ์ฉันจะลบพวกเขาออกจากวงแหวนบัฟเฟอร์) ดังนั้นฉันจะได้รับข้อมูลเพียงพอเสมอ (เว้นแต่ฉันจะพลาดไบต์ฉันต้องตรวจสอบสิ่งนั้น) RX buffer ของฉันมีเพียง 1 ไบต์ แต่ฉันคัดลอกไปยังบัฟเฟอร์ ring / Circular ฉันไม่ได้ตรวจสอบว่าเต็มหรือไม่ (ต้องเพิ่ม)
Michel Keijzers

เฮ้ไม่ต้องกังวล ฉันแน่ใจว่าใบสมัครของคุณจะได้รับการโปรแกรมอย่างดี ดังที่คนอื่น ๆ กล่าวถึง DMA นั้นยอดเยี่ยม แต่ไม่ใช่ทั้งหมดฟรี มันแนะนำข้อควรพิจารณาเพิ่มเติมในระบบซึ่งไม่มีอยู่ถ้าคุณสามารถหนีไปได้โดยไม่ต้องใช้มัน
pgvoorhees

ดีฉันหวังว่าฉันยังคงเป็นผู้เริ่มต้น
Michel Keijzers

3

ที่ด้านรับ (ตามที่ฉันจำได้) DMA จะยุติการแข่งขันอย่างใดอย่างหนึ่งหรือที่จำนวนเทอร์มินัล โพรโทคอลบางตัวและแอปพลิเคชั่นแบบอินเทอร์แอคทีฟหลายตัวไม่เหมาะกับโมเดลนี้อย่างแท้จริงและคุณจำเป็นต้องจัดการกับตัวละครโดยตัวละคร เทคนิค DMA ยังเปราะหากลิงก์การสื่อสารไม่น่าเชื่อถือการสูญเสียอักขระเดี่ยวในสตรีมสามารถทำให้เครื่อง DMA ของคุณยุ่งเหยิงได้ง่าย


ฉันได้รับ byte byte และคัดลอกมันไปที่ ring buffer เพื่อประมวลผลในภายหลัง
Michel Keijzers

1

ฉันได้ใช้ STM32CubeMx / HAL ในสองโครงการในขณะนี้และพบว่าซอฟต์แวร์การจัดการ UART ที่สร้างขึ้นนั้นมีข้อบกพร่องที่ชัดเจนในด้านการรับ

ในการส่งสัญญาณปกติแล้วคุณจะต้องการส่งบล็อคข้อมูลหรือบรรทัดข้อความ ในกรณีนี้คุณรู้ล่วงหน้าว่าการถ่ายโอนข้อมูลนานแค่ไหนดังนั้นการใช้ DMA จึงเป็นทางออกที่ชัดเจน คุณได้รับการขัดจังหวะเมื่อการถ่ายโอนเสร็จสมบูรณ์และสามารถใช้ฟังก์ชั่นการโทรกลับที่สมบูรณ์แบบของ UART TX เพื่อระบุรหัสหลักของคุณว่าการส่งสัญญาณเสร็จสมบูรณ์และคุณสามารถส่งข้อมูลบล็อกอื่นได้

เมื่อพูดถึงการรับข้อมูลฟังก์ชั่นที่จัดทำโดย ST ทุกคนคิดว่าคุณรู้จำนวนตัวอักษรที่อุปกรณ์ส่งจะให้คุณก่อนที่จะเริ่มส่ง โดยปกติจะไม่เป็นที่รู้จัก ฟังก์ชันการขัดจังหวะจะวางข้อมูลที่ได้รับลงในบัฟเฟอร์และระบุว่ามีข้อมูลที่พร้อมใช้งานเมื่อได้รับจำนวนอักขระที่กำหนดไว้ล่วงหน้า หากคุณพยายามใช้ DMA หรือฟังก์ชั่นขัดจังหวะเพื่อรับข้อมูลโดยการตั้งค่าการถ่ายโอนอักขระเดี่ยวตามลำดับเวลาในการตั้งค่าสำหรับแต่ละสิ่งเหล่านี้จะหมายถึงว่าคุณจะสูญเสียอักขระไปอย่างอื่นนอกเหนือจากอัตราข้อมูลที่ช้าที่สุด เริ่มต้นที่จะสูญเสียข้อมูลจะขึ้นอยู่กับความเร็วสัญญาณนาฬิกาของโปรเซสเซอร์ของคุณ) และจะโหลดโปรเซสเซอร์มากเกินไปโดยไม่ทิ้งรอบการสอนสำหรับการประมวลผลอื่น ๆ

ในการปัดเศษนี้ฉันได้เขียนฟังก์ชันตัวจัดการขัดจังหวะของตัวเองที่เก็บข้อมูลในบัฟเฟอร์วงกลมขนาดเล็กในท้องถิ่นและตั้งค่าจำนวนที่อ่านโดยรหัสหลัก (RTOS นับสัญญาณสัญญาณ) เพื่อระบุว่ามีข้อมูลที่ได้รับพร้อม รหัสหลักสามารถรวบรวมข้อมูลจากบัฟเฟอร์นี้ในเวลาว่างมันไม่สำคัญว่ามีความล่าช้าในการรวบรวมข้อมูลโดยที่บัฟเฟอร์ท้องถิ่นไม่ล้นก่อนที่จะมีการรวบรวมข้อมูล


ฉันทำสิ่งเดียวกัน (ฉันคิดว่า) ฉันอ่านทีละ 1 ไบต์และเก็บไว้ในบัฟเฟอร์แบบวนรอบและฉันตั้งใจจะตรวจสอบในลูปหลักสำหรับข้อความที่สมบูรณ์ สามารถปรับปรุงได้เล็กน้อย
Michel Keijzers

คุณคิดว่าฉันอาจพบปัญหาที่การตั้งค่า DMA ในแต่ละครั้งจะทำให้ตัวประมวลผลของฉัน / ตัวอักษรที่หายไปเกินพิกัดที่ 31,250 บอดหรือไม่
Michel Keijzers

1
ตราบใดที่คุณตั้งค่า DMA ขึ้นเพื่อถ่ายโอนจำนวนอักขระในแต่ละครั้งมากกว่านี้จะไม่มีปัญหา ฉันมี 4 UART ที่ทำงาน 115200 ขึ้นไปและ I2C ใช้ DMA โดยไม่มีปัญหา การส่งสัญญาณ UART มีขนาดทั้งหมด ~ 20 ไบต์หรือนานกว่านั้น ปัญหาคือการใช้ DMA เพื่อรับบนโปรเซสเซอร์ UART (L4 โปรเซสเซอร์ที่ 80MHz, 9600 baud)
คุณ

ขณะนี้ฉันตั้งค่าเป็น 1 ไบต์ต่อครั้ง แต่ฉันสามารถปรับปรุงได้ (โดยทำไบต์แรกและไม่ต้องตรวจสอบว่าจำเป็นต้องใช้ไบต์เพิ่มอีกกี่ไบต์)
Michel Keijzers
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.