Presentation is loading. Please wait.

Presentation is loading. Please wait.

Copyright © 2004 Texas Instruments. All rights reserved. 1.Introduction 2.Real-Time System Design Considerations 3.Hardware Interrupts (HWI) 4.Software.

Similar presentations


Presentation on theme: "Copyright © 2004 Texas Instruments. All rights reserved. 1.Introduction 2.Real-Time System Design Considerations 3.Hardware Interrupts (HWI) 4.Software."— Presentation transcript:

1 Copyright © 2004 Texas Instruments. All rights reserved. 1.Introduction 2.Real-Time System Design Considerations 3.Hardware Interrupts (HWI) 4.Software Interrupts (SWI) 5.Task Authoring (TSK) 6.Data Streaming (SIO) 7.Multi-Threading (CLK, PRD) 8.BIOS Instrumentation (LOG, STS, SYS, TRC) 9.Static Systems (GCONF, TCONF) 10.Cache (BCACHE) 11.Dynamic Systems (MEM, BUF) 12.Flash Programming (HexAIS, Flashburn) 13.Inter-Thread Communication (MSGQ,...) 14.DSP Algorithm Standard (XDAIS) 15.Input Output Mini-Drivers (IOM) 16.Direct Memory Access (DMA) 17.Review DSP/BIOS System Integration Workshop T TO Technical Training Organization 1

2 Objectives  Describe the concepts of BIOS drivers  List the key IOM API  List the basic activities in each IOM function  Describe the support tools for writing IOMs  Describe all components of an example IOM T TO Technical Training Organization 2

3 “Lab 11” 1Evaluation Forms (get password) 2Zip folder : C:\BIOS 3Copy zip file to Thumb Drive 4certificates T TO Technical Training Organization 3

4 BIOS Mini Drivers  SIO Review  IOM Concepts  Writing Mini Drivers  DDK - Driver Developers Kit  Chip Support Library  Device Structures  IOM API Coding Basics T TO Technical Training Organization 4

5 SIO Review  Common I/O interface: between Tasks and Devices  Universal interface to I/O devices  Yields improved code maintenance and portability  Number of buffers and buffer size are user selectable  Unidirectional: streams are input or output - not both  Efficiency: block passed by reference instead of by copy  SIO_issue passes a “IOM_Packet” buffer descriptor to driver via stream  SIO_reclaim waits for a IOM_Packet to be returned by driver via stream  Abstraction: TSK author insulated from underlying functionality  BIOS (SIO) implicitly manages two QUEues (todevice & fromdevice)  SIO_reclaim synchronized via implicitBIOS (DIO) SEM  IOM_Packets (aka DEV_Frames) produced by SIO on stream creation  Asynchronous: TSK and driver activity is independent, synch’d by buffer passes  Buffers: Data buffers must be created - by config tool or TSK MY_DSP_algo Task issue reclaim Output IOM issue reclaim SIO Input IOM SIO IOM_Packet prev {QUE_Elem} next Ptr addr Uns size Arg misc Arg arg Uns cmd Int status 5

6 BIOS Mini Drivers  SIO Review  IOM Concepts  Writing Mini Drivers  DDK - Driver Developers Kit  Chip Support Library  Device Structures  IOM API Coding Basics T TO Technical Training Organization 6

7 BIOS I/O Models Class Drivers I/O Mini- driver SIO Processing Thread Options  Original DEV coding now broken into two parts  Class Driver – provided by TI  I/O Mini Driver – I/F to HW (port/peripheral); from DDK, etc  Process Thread Author: Choose the class and I/O Mini-drivers desired  Same IOM for any class driver – “write once, use many’  Change of Mini-Drivers : new driver, same processing thread & class driver DIO TSK or SWI custom GIO PIP PIO SWI equiv. of old Device Driver “DEV” spec’n A single mini-driver can be used with any DSP/BIOS I/O model T TO Technical Training Organization 7

8 MiniDriver: Interface to TSK or SWI myTsk() SIO_create MEM_alloc SIO_issue SIO_issue while(1) SIO_reclaim dsp... SIO_issue SIO_idle SIO_reclaim SIO_reclaim MEM_free SIO_delete createSwi() SIO_create MEM_alloc SIO_issue SIO_issue executeSwi() SIO_reclaim dsp... SIO_issue deleteSwi() SIO_idle SIO_reclaim SIO_reclaim MEM_free SIO_delete dio_codec... SEM_pend() SEM_post() ?SWI_post()... md_SubmitChan md_codec... T TO Technical Training Organization 8

9 IOM Methods – Concepts 1/5 DSK5402_MCBSP_AD50_init - usually an empty fxn mdBindDev(dgp, devid, dparams) -initialize parameters - acquire resources -initialize h/w- plug ISRs -create/initialize global data structure (devObj) BIOS_init m dBindDev main T TO Technical Training Organization 9

10 IOM Methods – Concepts 2/5 BIOS_init m dBindDev main myTsk() SIO_create MEM_alloc SIO_issue SIO_issue while(1) I SIO_reclaim dsp... SIO_issue SIO_idle SIO_reclaim SIO_reclaim MEM_free SIO_delete DSK5402_MCBSP_AD50_init - usually an empty fxn mdBindDev(dgp, devid, dparams) -initialize parameters - acquire resources -initialize h/w- plug ISRs -create/initialize global data structure (devObj) SIO: -create SIO object -create IO Packets -call DIO mdCreateChan() -create QUE -create chan object -enable interrupt DIO: -create DIO object -create QUE -call mdCreateChan T TO Technical Training Organization 10

11 IOM Methods – Concepts 3/5 BIOS_init m dBindDev main myTsk() SIO_create MEM_alloc SIO_issue SIO_issue while(1) I SIO_reclaim dsp... SIO_issue SIO_idle SIO_reclaim SIO_reclaim MEM_free SIO_delete DSK5402_MCBSP_AD50_init - usually an empty fxn mdBindDev(dgp, devid, dparams) -initialize parameters - acquire resources -initialize h/w- plug ISRs -create/initialize global data structure (devObj) SIO: -create SIO object -create IO Packets -call DIO DIO: -create DIO object -create QUE -call mdCreateChan mdCreateChan() -create QUE -create chan object -enable interrupt SIO: -put *buf in IOP -queue IOP -call DIO mdSubmitChan() -if no current IOP, begin using this one -else QUE for later use DIO: -dequeue IOP -pass IOP to IOM -call mdSubmitChan IOM: ISR -fill buf with data T TO Technical Training Organization 11

12 IOM Methods – Concepts 4/5 BIOS_init m dBindDev main myTsk() SIO_create MEM_alloc SIO_issue SIO_issue while(1) I SIO_reclaim dsp... SIO_issue SIO_idle SIO_reclaim SIO_reclaim MEM_free SIO_delete DSK5402_MCBSP_AD50_init - usually an empty fxn mdBindDev(dgp, devid, dparams) -initialize parameters - acquire resources -initialize h/w- plug ISRs -create/initialize global data structure (devObj) SIO: -create SIO object -create IO Packets -call DIO DIO: -create DIO object -create QUE -call mdCreateChan mdCreateChan() -create QUE -create chan object -enable interrupt SIO: -put *buf in IOP -queue IOP -call DIO DIO: -dequeue IOP -pass IOP to IOM -call mdSubmitChan mdSubmitChan() -if no current IOP, begin using this one -else QUE for later use SIO: call DIO DIO: SEM_pend() IOM: ISR -fill buf with data T TO Technical Training Organization 12

13 IOM Methods – Concepts 5/5 BIOS_init m dBindDev main myTsk() SIO_create MEM_alloc SIO_issue SIO_issue while(1) I SIO_reclaim dsp... SIO_issue SIO_idle SIO_reclaim SIO_reclaim MEM_free SIO_delete DSK5402_MCBSP_AD50_init - usually an empty fxn mdBindDev(dgp, devid, dparams) -initialize parameters - acquire resources -initialize h/w- plug ISRs -create/initialize global data structure (devObj) SIO: -create SIO object -create IO Packets -call DIO DIO: -create DIO object -create QUE -call mdCreateChan mdCreateChan() -create QUE -create chan object -enable interrupt SIO: -put *buf in IOP -queue IOP -call DIO DIO: -dequeue IOP -pass IOP to IOM -call mdSubmitChan mdSubmitChan() -if no current IOP, begin using this one -else QUE for later use IOM: ISR -fill buf with data -when full/empty, run cbFxn(arg, IOP) SIO: call DIO DIO: SEM_pend() DIO: callback fxn -queue IOP - SEM_post() - rtn to SIO Class Driver: Provided by DSP/BIOS SIO: -deque IOP -get buf info from IOP & rtn to TSK T TO Technical Training Organization 13

14 BIOS Mini Drivers  SIO Review  IOM Concepts  Writing Mini Drivers  DDK - Driver Developers Kit  Chip Support Library  Device Structures  IOM API Coding Basics T TO Technical Training Organization 14

15 BIOS Mini Drivers  SIO Review  IOM Concepts  Writing Mini Drivers  DDK - Driver Developers Kit  Chip Support Library  Device Structures  IOM API Coding Basics T TO Technical Training Organization 15

16 Device Driver Developer’s Kit: DDK PlatformMcBSPUARTOther 6711DSK AD535 6713 DSK AIC23SW McASP 6416 DSK AIC23SW DM642 EVM AIC23HWMcASP C6x1x AD535SW C5416 PCM3002 C5509 AIC23SW C5510 AIC23SW  Productized Drivers for TI DSP Peripherals  Simple Example Applications that Use These Drivers  Documentation on Using Existing Drivers & Developing New Drivers  Downloadable : Free of Charge / No Run-time Royalties  Available via:  CCS Update Advisor  TI DSP Developer’s Village (dspvillage.com)  www.TI.com  Example Drivers: T TO Technical Training Organization 16

17 DDK Documentation Start Here: DSP/BIOS Driver Developer's Guide (SPRU616)  Each Device Driver Has Corresponding Documentation (App Note) Usage, Architecture, Data Sheet  Every Device Driver project has a Readme File Doc #DSPDeviceBoard SPRA882AllUARTAll SPRA858C5000McBSP/DMAAll C5000 SPRA857C5509AIC23 CodecC5509 DSK SPRA855C5416PCM3002 CodecC5416 DSK SPRA856C5510AIC23 CodecC5510 DSK SPRA846C6x1xMcBSP/EDMAAll C6000 SPRA850C6x11AD535 CodecC6711 DSK SPRA677C6713AIC23C6713 DSK SPRA909C6416AIC23C6416 DSK SPRA677DM642AIC23DM642 EVM SPRA870C6x1xMcASP/EDMAAll C6000 T TO Technical Training Organization 17

18 DDK Summary  Productized IOM Drivers for TI DSP Peripherals  PCI, USB, Multimedia Card, McBSP, McASP, Video Ports, Codecs, UART  Full source code and documentation provided  Introduces the new IOM Driver Model to simplify development of new drivers  Reusable modules  Standard APIs defined  Backwards-compatability is maintained for older BIOS code which uses older driver models  Extensible, integrated DSP/BIOS I/O Modules  New DEV, PIO, GIO API’s T TO Technical Training Organization 18

19 DSP/BIOS McBSP Codec Driver  Generic McBSP-DMA Data Mover  Implemented as a stand-alone mini-driver  Multi-channel  Reusable across codecs  Codec Specific Part of Mini-Driver  Handles codec specific bind, channel open  AIC23, PCM3002, AD50, AD535  Only mdSubmitChan and mdCreateChan Calls Are Handled by the Codec-Specific Portion of the Mini- Driver, So That’s All You Have To Write! Application/Framework Device Driver PIP PIO Adapter SIO DIO Adapter GIO Class Driver Codec-Specific Part of Mini-Driver Generic McBSP-DMA Data Mover Mini- Driver T TO Technical Training Organization 19

20 BIOS Mini Drivers  SIO Review  IOM Concepts  Writing Mini Drivers  DDK - Driver Developers Kit  Chip Support Library  Device Structures  IOM API Coding Basics T TO Technical Training Organization 20

21 Chip Support Library - CSL  CSL is a collection of :  Functions- to create/delete/ and interact with peripherals example: MCBSP_config() [Module_function]  Structures- that define the control registers of the peripheral example: MCBSP_Config() [Module_Type]  Macros- that allow complex register fields to be directly managed  Symbols- well defined to improve readability/maintainability  Goals of CSL :  Ease of use  Faster development time  Improved portability across TI DSPs  Enhanced readability / documentation of functionality  Hardware abstraction  Benefits of CSL :  Standardized protocol  Basic resource management  Peripheral symbol definitions T TO Technical Training Organization 21

22 Chip Support Library: CSL Create: mdBindDev() -->hMcBsp = MCBSP_open( channel, … ) McBSP channel can be : 0,1,2, ‘any’ CSL manages availability of ‘registered’ peripherals via “ChipDefine” CSL : BSP flags: 0 1 0 2 1 0 MCBSP_config(hMcBSP, …) MCBSP_start(hMcBSP, …) Execute: SIO_issue()--> mdSubmitChan()--> SIO_reclaim()-->ISR-->MCBSP_read(hMcBSP) MCBSP_write(hMcBSP, …) Delete: SIO_delete()-->mdDeleteChan()-->MCBSP_close(hMcBSP) T TO Technical Training Organization 22

23 CSL Coding Example – EDMA Peripheral // 1. include headers #include // 2. Initialize CSL CSL_init(); // 3. make a handle EDMA_Handle hMyChannel; // 4. open a periph, get handle – periph ‘checked out’ by CSL hMyChannel = EDMA_open(EDMA_CHA_ANY, EDMA_OPEN_RESET); // 5. define config structure EDMA_Config myConfig {…specify all register/bit values here…} // 6. configure the channel EDMA_config (hMyChannel, &myConfig); T TO Technical Training Organization 23

24 CSL Macro and Structure Example EDMA_Config myConfig = { EDMA_OPT_RMK(// “Register Make” macro EDMA_OPT_PRI_LOW,// Priority? EDMA_OPT_ESIZE_16BIT,// Element size? EDMA_OPT_2DS_NO,// 2 dimensional source? EDMA_OPT_SUM_INC,// Src update mode? EDMA_OPT_2DD_NO,// 2 dimensional dest? EDMA_OPT_DUM_INC,// Dest update mode? EDMA_OPT_TCINT_YES,// Cause EDMA interrupt? EDMA_OPT_TCC_OF(0),// Transfer complete code? EDMA_OPT_LINK_YES,// Enable link parameters? EDMA_OPT_FS_YES,// Use frame sync? ), EDMA_SRC_OF(gBuffer0 ),// src address? EDMA_CNT_OF(BUFFSIZE ),// Count = buffer size EDMA_DST_OF(gBuffer1 ),// dest address? EDMA_IDX_OF( 0 ),// frame/element index value? EDMA_RLD_OF( 0 )// reload }; T TO Technical Training Organization 24

25 CSL Coding – Interrupt Management // 1. include headers #include // 2. enable specific interrupt IRQ_enable(IRQ_EVT_EDMAINT); // 3. enable interruptability IRQ_globalEnable( ); // option – adjust configuration using Field Make (FMK) macro myConfig.opt | = EDMA_FMK (reg, field, value); T TO Technical Training Organization 25

26 /* Open DMA and MCBSP */ hDmaRx = DMA_open( DMA_CHAANY, DMA_OPEN_RESET ); hMcbsp = MCBSP_open( MCBSP_PORT0, MCBSP_OPEN_RESET ); /* Set up configuration for DMA and MCBSP */ DMA_config( hDmaRx, &dmaMcbspRx ); MCBSP_config( hMcbsp, &mcbspCfg0 ); /* Start the DMA and MCBSP */ DMA_start( hDmaRx ); MCBSP_start( hMcbsp, MCBSP_RCV_START ); McBSP CSL API’s T TO Technical Training Organization 26

27 BIOS Mini Drivers  SIO Review  IOM Concepts  Writing Mini Drivers  DDK - Driver Developers Kit  Chip Support Library  Device Structures  IOM API Coding Basics T TO Technical Training Organization 27

28 IOM Functions typedef struct IOM_Fxns { IOM_TmdBindDev mdBindDev; initialize port on BIOS startup IOM_TmdUnBindDev mdUnBindDev; currently null fxn, poss. future use IOM_TmdControlChan mdControlChan; response to SIO_ctrl() IOM_TmdCreateChan mdCreateChan; response to SIO_create() IOM_TmdDeleteChan mdDeleteChan; response to SIO_delete() IOM_TmdSubmitChan mdSubmitChan; SIO_issue, _idle, _abort response } IOM_Fxns; Also, an ISR/HWI is required within the IOM to collect/output the data to/from the buffer issued to the IOM, and route the completed buffer back to the processing thread (TSK, SWI) as a response to the SIO_reclaim() API T TO Technical Training Organization 28

29 IOM Packet Descriptor typedef struct IOM_Packet { QUE_Elem link; // used by SIO to manage buffer queue Ptr addr; // address of buffer Uns size; // size of buffer Arg misc; // callback fxn for packet stored here Arg arg; // anything you like (usually nothing) Uns cmd; // for ‘submit’, action for IOM to perform on this packet Int status; // IOM writes return status of packet here } IOM_Packet;  IOM_Packet descriptors are filled in by DSP/BIOS (in SIO and DIO) using:  properties defined via stream creation  arguments of SIO_issue  IOM authors will reference IOM_Packet fields to know what it needs to do and how typedef DEV_Frame IOM_Packet; in iom.h : T TO Technical Training Organization 29

30 Example Channel Object typedef struct ChanObj { Boolinuse; // know if channel currently ‘open’ Intmode; // options: IOM_INPUT or IOM_OUTPUT IOM_Packet*dataPacket; // packet (descriptor) of buffer currently in use QUE_ObjpendList; // queue of packets waiting to be used Uns*bufptr;// ptr to next element in buffer for service Unsbufcnt; // how many elements left to service IOM_TiomCallbackcbFxn; // function to call when done with this buffer PtrcbArg;// return status of buffer } ChanObj, *ChanHandle;  Driver and Channel Objects are defined by the IOM author (not a universal standard across all IOMs, like an IOM_Packet is)  This example contains elements that most IOMs will likely require  More sophisticated IOMs will likely require more extensive objects T TO Technical Training Organization 30

31 Information Exchange Between Structures status = SIO_issue(hStream, pBuf, uSize, arg); uSize = SIO_reclaim(hStream, *pBuf, pArg); IOM_Packet QUE_Elem link; Ptr addr; Uns size; Arg misc; Arg arg; Uns cmd; Int status; ChanObj Boolinuse; Intmode; IOM_Packet*dataPacket; QUE_ObjpendList; Uns*bufptr; Unsbufcnt; IOM_TiomCallbackcbFxn; PtrcbArg; hChan T TO Technical Training Organization 31

32 IOM Status and Error Codes IOM_COMPLETED0Successful completion IOM_PENDING1I/O queued & pending IOM_FLUSHED2Packet flushed IOM_ABORTED3Packet aborted IOM_EBADIO- 1Generic failure IOM_ETIMEOUT- 2Timeout occurred IOM_ENOPACKETS- 3No packets available IOM_EFREE- 4Unable to free resources IOM_EALLOC- 5Unable to allocate resources IOM_EABORT- 6I/O aborted uncompleted IOM_EBADMODE- 7Illegal device mode IOM_EOF- 8End-of-file encountered IOM_ENOTIMPL- 9Operation not supported IOM_EBADARGS-10Illegal arguments used IOM_ETIMEOUTUNREC-11Unrecoverable timeout IOM_EINUSE-12Device already in use T TO Technical Training Organization 32

33 BIOS Mini Drivers  SIO Review  IOM Concepts  Writing Mini Drivers  DDK - Driver Developers Kit  Chip Support Library  Device Structures  IOM API Coding Basics T TO Technical Training Organization 33

34 Code Example : dsk5402_mcbsp_ad50.c  McBSP/AD50: sample-by-sample mini-driver  App example processing thread type: TSK  Uses SIO/DIO Class Driver ‘C5402 McBSP AD50 TSK SIO_reclaim DSP... SIO_issue SIO DIO  Inclusions, Definitions, Declarations, Globals  mdBindDev, mdUnBindDev  mdChannelCreate() mdChannelDelete()  mdChannelSubmit(), mdChannelControl()  Interrupt functions  Header file  Inclusions, Definitions, Declarations, Globals T TO Technical Training Organization 34

35 Code Example : dsk5402_mcbsp_ad50.c  Inclusions, Definitions, Declarations, Globals  mdBindDev, mdUnBindDev  mdCreateChan() mdDeleteChan()  mdSubmitChan(), mdControlChan()  Interrupt functions  Header file ‘C5402 McBSP AD50 TSK SIO_reclaim DSP... SIO_issue SIO DIO T TO Technical Training Organization 35

36 Includes, Globals, Local Fxn Prototypes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include BIOS Modules used CSL Modules used BSL Modules used static MCBSP_Handle hMcbsp; // CSL McBSP object handle DSK5402_MCBSP_AD50_DevParams DSK5402_MCBSP_AD50_DEVPARAMS = { AD50_DEFAULTPARAMS }; // default AD50 properties static Void rxIsr(void); // isr fxns – ‘heart’ of any IOM static Void txIsr(void); static Void updateChan(ChanHandle chan); // local fxns static Void abortio(ChanHandle chan); static MCBSP_Handle hMcbsp; // CSL McBSP object handle DSK5402_MCBSP_AD50_DevParams DSK5402_MCBSP_AD50_DEVPARAMS = { AD50_DEFAULTPARAMS }; // default AD50 properties static Void rxIsr(void); // isr fxns – ‘heart’ of any IOM static Void txIsr(void); static Void updateChan(ChanHandle chan); // local fxns static Void abortio(ChanHandle chan); T TO Technical Training Organization 36

37 Channel Object and Device Object typedef struct ChanObj { Boolinuse; know if channel currently ‘open’ Intmode; options: IOM_INPUT or IOM_OUTPUT IOM_Packet*dataPacket; packet (descriptor) of buffer currently in use QUE_ObjpendList; queue of packets waiting to be used Uns*bufptr;ptr to next element in buffer for service Unsbufcnt; how many elements left to service IOM_TiomCallbackcbFxn; function to call when done with this buffer PtrcbArg;return status of buffer } ChanObj, *ChanHandle; #define INPUT 0 input chan is chanObj 0 #define OUTPUT 1 output channel obj is 2 nd struc in chans array #define NUMCHANS2 chans ‘master’ object holds 2 channel objects static ChanObj chans[NUMCHANS] = { ‘chans’ is an array of 2 channel objects { FALSE, INPUT, NULL, { NULL, NULL }, ‘chans’ is also the Device Object in this example NULL, 0, NULL, NULL }, { FALSE, OUTPUT, NULL, { NULL, NULL }, both channels initially begin in null state NULL, 0, NULL, NULL } two bracketed nulls are for queue head & tail ptrs }; T TO Technical Training Organization 37

38 Example Device Object typedef struct MyDevObj { ChanObjInput; // know if channel currently ‘open’ ChanObjOutput; // options: IOM_INPUT or IOM_OUTPUT McBSP_HandlehMcBSP; // packet (descriptor) of buffer currently in use BoolcurInit; // queue of packets waiting to be used DSK5402_...Params PARAMS } MyDevObj, *MyDevHandle; static MyDevObjdObj;  Driver Object is defined by the IOM author (not an IOM standard)  This example is just a pair of Channel Objects  Most IOMs will likely require more extensive objects  The AD50 example could have used a Dev Object as follows: static ChanObj chans[NUMCHANS] = { ‘chans’ is an array of 2 channel objects { FALSE, INPUT, NULL, { NULL, NULL }, ‘chans’ is also the Device Object in this example NULL, 0, NULL, NULL }, { FALSE, OUTPUT, NULL, { NULL, NULL }, both channels initially begin in null state NULL, 0, NULL, NULL } two bracketed nulls are for queue head & tail ptrs }; T TO Technical Training Organization 38

39 IOM Fxn Prototypes and vTab // ========== Forward declaration of IOM interface functions / Prototypes static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams); static Int mdControlChan(Ptr chanp, Uns cmd, Ptr args); static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode, Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg); static Int mdDeleteChan(Ptr chanp); static Int mdSubmitChan(Ptr chanp, IOM_Packet *packet); // =========== Public IOM interface table / vTab IOM_Fxns DSK5402_MCBSP_AD50_FXNS = { mdBindDev, IOM_UNBINDDEVNOTIMPL, mdControlChan, mdCreateChan, mdDeleteChan, mdSubmitChan }; // ========== Forward declaration of IOM interface functions / Prototypes static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams); static Int mdControlChan(Ptr chanp, Uns cmd, Ptr args); static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode, Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg); static Int mdDeleteChan(Ptr chanp); static Int mdSubmitChan(Ptr chanp, IOM_Packet *packet); // =========== Public IOM interface table / vTab IOM_Fxns DSK5402_MCBSP_AD50_FXNS = { mdBindDev, IOM_UNBINDDEVNOTIMPL, mdControlChan, mdCreateChan, mdDeleteChan, mdSubmitChan };  Most IOMs will provide a nearly identical copy of the above code  The only likely difference will be the name of the FXNS table T TO Technical Training Organization 39

40 Code Example : dsk5402_mcbsp_ad50.c ‘C5402 McBSP AD50 TSK SIO_reclaim DSP... SIO_issue SIO DIO  Inclusions, Definitions, Declarations, Globals  mdBindDev, mdUnBindDev  mdCreateChan() mdDeleteChan()  mdSubmitChan(), mdControlChan()  Interrupt functions  Header file T TO Technical Training Organization 40

41 md Handle Passing BIOS_init()mdBindDev() SIO_create()mdCreateChan() SIO_issue()mdSubmitChan() hDev “devp” hChan “chanp” *IOP T TO Technical Training Organization 41

42 mdBindDev() status = mdBindDev(*devp, devid, devParams); TypeParameter Description Ptr*devp return address for global device data pointer Intdevid device id - used if more than one instance of the driver is to be created PtrdevParams pointer to config parameters IntStatus returns success/failure of function T TO Technical Training Organization 42

43 mdBindDev() #pragma CODE_SECTION(mdBindDev, ".text:init“) static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams) DevHandle, InstanceNo, Params { DSK5402_MCBSP_AD50_DevParams *params = (DSK5402_MCBSP_AD50_DevParams *)devParams; get params from arguments static Bool curinit = FALSE; tests if this fxn already ran – init ‘no’ static MCBSP_Config mcbspCfg0 = { values for the McBSP config CSL API 0x0021, 0x0201, 0x0040, 0x0000, 0x0040, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000c, 0x0000, 0x0000, 0x0000, 0x0000 }; static volatile ioport unsigned port04; for CPLD CTRL 2 – DSK detail... if (curinit) { return (IOM_EBADIO); } if already setup, return as error curinit = TRUE; we are now ‘set up’ if (params == NULL){ params = &DSK5402_MCBSP_AD50_DEVPARAMS; } if no params provided, use defaults hMcbsp = MCBSP_open(MCBSP_PORT1, MCBSP_OPEN_RESET); get a handle to a SP1 via CSL MCBSP_config(hMcbsp, &mcbspCfg0); use values above to config SP1 port04 &= 0xf5; DSK5402 bd s/u: audio codec on SP1 MCBSP_start(hMcbsp, MCBSP_XMIT_START | MCBSP_RCV_START, 0x0); McBSP xmt & rcv now ‘on’ AD50_setParams(hMcbsp, &(params->ad50) ); apply params to codec HWI_dispatchPlug(IRQ_EVT_RINT1, (Fxn)rxIsr, NULL); bind Rx/Tx ints, use BIOS dispatcher HWI_dispatchPlug(IRQ_EVT_XINT1, (Fxn)txIsr, NULL); *devp = chans; return (IOM_COMPLETED); } T TO Technical Training Organization 43

44 mdBindDev() #pragma CODE_SECTION(mdBindDev, ".text:init“ static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams) DevHandle, InstanceNo, Params { DSK5402_MCBSP_AD50_DevParams *params = (DSK5402_MCBSP_AD50_DevParams *)devParams; get params from arguments static Bool curinit = FALSE; tests if this fxn already ran – init ‘no’ static MCBSP_Config mcbspCfg0 = { values for the McBSP config CSL API 0x0021, 0x0201, 0x0040, 0x0000, 0x0040, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000c, 0x0000, 0x0000, 0x0000, 0x0000 }; static volatile ioport unsigned port04; for CPLD CTRL 2 – DSK detail... if (curinit) { return (IOM_EBADIO); } if already setup, return as error curinit = TRUE; we are now ‘set up’ if (params == NULL){ params = &DSK5402_MCBSP_AD50_DEVPARAMS; } if no params provided, use defaults hMcbsp = MCBSP_open(MCBSP_PORT1, MCBSP_OPEN_RESET); get a handle to a SP1 via CSL MCBSP_config(hMcbsp, &mcbspCfg0); use values above to config SP1 port04 &= 0xf5; DSK5402 bd s/u: audio codec on SP1 MCBSP_start(hMcbsp, MCBSP_XMIT_START | MCBSP_RCV_START, 0x0); McBSP xmt & rcv now ‘on’ AD50_setParams(hMcbsp, &(params->ad50) ); apply params to codec HWI_dispatchPlug(IRQ_EVT_RINT1, (Fxn)rxIsr, NULL); bind Rx/Tx ints, use BIOS dispatcher HWI_dispatchPlug(IRQ_EVT_XINT1, (Fxn)txIsr, NULL); *devp = chans; return (IOM_COMPLETED); } static locals could have been incorporated into the DevObject port04 is a DSK routing switch address – unlikely for single purpose board curinit test not essential, but nice dispatchPlug frees system integrator from needing to specify the HWI connections in the config tool Could pass MCBSP_PORTn as devid, then used devid as first arg in MCBSP_open() Can also test devid for valid value and return error if not so: if(devid != MCBSP_PORT0 | MCBSP_PORT1){return(IOM_EBADARGS);} T TO Technical Training Organization 44

45 Code Example : dsk5402_mcbsp_ad50.c ‘C5402 McBSP AD50 TSK SIO_reclaim DSP... SIO_issue SIO DIO  Inclusions, Definitions, Declarations, Globals  mdBindDev, mdUnBindDev  mdCreateChan() mdDeleteChan()  mdSubmitChan(), mdControlChan()  Interrupt functions  Header file T TO Technical Training Organization 45

46 mdCreateChan(), mdDeleteChan() status = mdCreateChan (*chanp, devp, name, mode, chanParams, cbFxn, cbArg); TypeParameter Description Ptr*chanp Return address for channel handle Ptrdevp Handle to device (global data structure) Stringname Name of device or instance Intmode Direction of data flow: INPUT or OUTPUT PtrchanParams Pointer to channel parameters IOM_TiomCallback cbFxn Pointer to callback function PtrcbArg Pointer to callback function argument IntStatus Returns success/failure of function status = mdDeleteChan (Ptr chanp) TypeParameter Description Ptrchanp Handle to channel IntStatus Returns success/failure of function hStrmIn = SIO_create("/a2d", SIO_INPUT, BUFSIZE, &attrs); struct SIO_Attrs { Intnbufs; Intsegid; Intalign; Boolflush; Unsmodel; Unstimeout; DEV_Callback callback } T TO Technical Training Organization 46

47 mdCreateChan() static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode, Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg) { ChanHandle chans = (ChanHandle)devp; device obj ‘chans’ ChanHandle chan; chan obj ‘chan’ if (mode == IOM_INPUT) { chan = &chans[INPUT];} if in chan, hChan => in chan obj else if (mode == IOM_OUTPUT) { chan = &chans[OUTPUT]; } else, hChan => out chan obj else { return (IOM_EBADMODE);} if neither in nor out, return error if (ATM_setu((Uns *)&chan->inuse, TRUE)) { return (IOM_EBADIO);} if chan already in use, rtn error QUE_new(&chan->pendList); empty the queue for the chan chan->dataPacket = NULL; no active buffer yet chan->cbFxn = cbFxn; set the callback fxn from args chan->cbArg = cbArg; set callback arg from args if (chan->mode == INPUT) { IRQ_enable(IRQ_EVT_RINT1);} if input, enable rcvr ints else { IRQ_enable(IRQ_EVT_XINT1); } if output, enable xmit ints *chanp = chan; rtn handle to chan obj via arg return (IOM_COMPLETED); rtn indicating ‘success’ } inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg chan T TO Technical Training Organization 47

48 inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg chan mdCreateChan() static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode, Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg) { ChanHandle chans = (ChanHandle)devp; device obj ‘chans’ ChanHandle chan; chan obj ‘chan’ if (mode == IOM_INPUT) { chan = &chans[INPUT];} if in chan, hChan => in chan obj else if (mode == IOM_OUTPUT) { chan = &chans[OUTPUT]; } else, hChan => out chan obj else { return (IOM_EBADMODE);} if neither in nor out, return error if (ATM_setu((Uns *)&chan->inuse, TRUE)) { return (IOM_EBADIO);} if chan already in use, rtn error QUE_new(&chan->pendList); empty the queue for the chan chan->dataPacket = NULL; no active buffer yet chan->cbFxn = cbFxn; set the callback fxn from args chan->cbArg = cbArg; set callback arg from args if (chan->mode == INPUT) { IRQ_enable(IRQ_EVT_RINT1);} if input, enable rcvr ints else { IRQ_enable(IRQ_EVT_XINT1); } if output, enable xmit ints *chanp = chan; rtn handle to chan obj via arg return (IOM_COMPLETED); rtn indicating ‘success’ } for an audio pass-thru system, turning on the interrupts now is OK, but for most systems will want to wait for an IOP to be on hand before enabling ints. For this, the IRQ_enable here would be moved to the md_SubmitChan() function, as will be seen there more descriptive return code might have been IOM_EINUSE T TO Technical Training Organization 48

49 mdDeleteChan() static Int mdDeleteChan(Ptr chanp) { ChanHandle chan = (ChanHandle)chanp; get channel ID from arguments chan->inuse = FALSE; channel is no longer in use if (chan->mode == INPUT) { if channel is input, then IRQ_disable(IRQ_EVT_RINT1); disable receiver interrupts } else { otherwise, channel is output IRQ_disable(IRQ_EVT_XINT1); and transmit interrupt is disabled } return (IOM_COMPLETED); return indicating deleteChan completed } inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg chan T TO Technical Training Organization 49

50 Code Example : dsk5402_mcbsp_ad50.c ‘C5402 McBSP AD50 TSK SIO_reclaim DSP... SIO_issue SIO DIO  Inclusions, Definitions, Declarations, Globals  mdBindDev, mdUnBindDev  mdCreateChan() mdDeleteChan()  mdSubmitChan(), mdControlChan()  Interrupt functions  Header file T TO Technical Training Organization 50

51 mdSubmitChan(), mdControlChan status = mdSubmitChan (chanp, *packet); TypeParameter Description Ptrchanp Handle to channel IOM_Packet*packet Descriptor of buffer sent to md IntStatus returns success/failure of function status = mdControlChan (chanp, cmd, arg); TypeParameter Description Ptrchanp Handle to channel Unscmd Control function to perform PtrArg Optional – for driver specific data structure IntStatus returns success/failure of function T TO Technical Training Organization 51

52 mdSubmitChan() static Int mdSubmitChan(Ptr chanp, IOM_Packet *packet) { ChanHandle chan = (ChanHandle)chanp; Uns imask; if (packet->cmd == IOM_FLUSH || packet->cmd == IOM_ABORT){ abortio(chan); packet->status = IOM_COMPLETED; return (IOM_COMPLETED); } imask = HWI_disable(); if (chan->dataPacket == NULL) { chan->bufptr = (Uns *)packet->addr; chan->bufcnt = packet->size; chan->dataPacket = packet; } else { QUE_put(&chan->pendList, packet); } HWI_restore(imask); return (IOM_PENDING); } handle to ChanObj pGIE if API was SIO_flush or SIO _abort call the abort fxn (later slide) mark the packet ‘done’ return “OK” if API was SIO_issue, turn off ints if there is no current packet (buffer) point to the top of the new buffer reset the buffer counter set this packet as the ‘current’ packet if I already have a packet in progress put this one in the queue for later put GIE back to prior state return ‘buffer in progress’ inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg chan T TO Technical Training Organization 52

53 mdSubmitChan() static Int mdSubmitChan(Ptr chanp, IOM_Packet *packet) { ChanHandle chan = (ChanHandle)chanp; Uns imask; if (packet->cmd == IOM_FLUSH || packet->cmd == IOM_ABORT){ abortio(chan); packet->status = IOM_COMPLETED; return (IOM_COMPLETED); } imask = HWI_disable(); if (chan->dataPacket == NULL) { chan->bufptr = (Uns *)packet->addr; chan->bufcnt = packet->size; chan->dataPacket = packet; } else { QUE_put(&chan->pendList, packet); } HWI_restore(imask); return (IOM_PENDING); } handle to ChanObj pGIE if API was SIO_flush or SIO _abort call the abort fxn (later slide) mark the packet ‘done’ return “OK” if API was SIO_issue, turn off ints if there is no current packet (buffer) point to the top of the new buffer reset the buffer counter set this packet as the ‘current’ packet if I already have a packet in progress put this one in the queue for later put GIE back to prior state return ‘buffer in progress’ inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg chan perhaps returning IOM_ABORTED would have been more appropriate here? add if (chan->mode == INPUT) { IRQ_enable(IRQ_EVT_RINT1); } else { IRQ_enable(IRQ_EVT_XINT1); } here if ints on/off to be controlled by IOP availability Better: IE specific approach T TO Technical Training Organization 53

54 mdControlChan() static Int mdControlChan(Ptr chanp, Uns cmd, Ptr args) { if (cmd == IOM_CHAN_TIMEDOUT) { if DIO has declared a timout abortio(chanp); abort packet processing } else { return (IOM_ENOTIMPL); used to reply to all other (unsupported) commands } return (IOM_COMPLETED); }  IOM author can select any number of control operations desired  In this example, only a handler for stream timout was implemented  DIO manages the test for timeout. If timeout occurs, DIO calls mdControlChan  Final option to return ‘not implemented’ should be present in all mdControlChan functions to respond to commands not supported by the IOM T TO Technical Training Organization 54

55 mdControlChan() – “Volume” Example static Int mdControlChan(Ptr chanp, Uns cmd, Ptr args) { if (cmd == IOM_CHAN_TIMEDOUT) { if DIO has declared a timout abortio(chanp); abort packet processing } else if (cmd == MY_IOM_VOL) { if TSK requested a new volume value chanp->vol = (short) args; update volume setting in channel object } else { return (IOM_ENOTIMPL); used to reply to all other (unsupported) commands } return (IOM_COMPLETED); }  Example: adding an IOM control option - suppose this IOM had a ‘volume control’ (eg: ranging scale on ADC)  Add the volume parameter “vol” to the channel object  Test for the VOL command – if present, adjust “vol” in the chanObj  Refer to chanp.vol for ADC ranging option in IOM code as applicable  Note in IOM documentation /.h file MY_IOM_VOL command, type and allowed range of args values (generally a structure, here a simple short) inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg vol chanp T TO Technical Training Organization 55

56 abortio static Void abortio(ChanHandle chan) { IOM_Packet *tmpPacket; HWI_disable(); critical section – atomic mode tmpPacket = chan->dataPacket; save a copy of the curr data pkt info chan->dataPacket = NULL; now there is no active data pkt HWI_enable(); critical section over,Ints back on if (tmpPacket) { if there was a good packet... tmpPacket->status = IOM_ABORTED; mark it ‘aborted’ (*chan->cbFxn)(chan->cbArg, tmpPacket); run the cbFxn to rtn the pkt tmpPacket = QUE_get(&chan->pendList); get another pkt frm the Q while (tmpPacket != (IOM_Packet *)&chan->pendList) as long as there are pkts { tmpPacket->status = IOM_ABORTED; as above... mark the pkt ‘aborted’ (*chan->cbFxn)(chan->cbArg, tmpPacket); run the cbFxn to rtn the pkt tmpPacket = QUE_get(&chan->pendList); get another pkt frm the Q } } } inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg chan Called in response to:  TSK: SIO_flush()  TSK: SIO_abort()  DIO: stream timeout T TO Technical Training Organization 56

57 abortio static Void abortio(ChanHandle chan) { IOM_Packet *tmpPacket; HWI_disable(); critical section – atomic mode tmpPacket = chan->dataPacket; save a copy of the curr data pkt info chan->dataPacket = NULL; now there is no active data pkt HWI_enable(); critical section over,Ints back on if (tmpPacket) { if there was a good packet... tmpPacket->status = IOM_ABORTED; mark it ‘aborted’ (*chan->cbFxn)(chan->cbArg, tmpPacket); run the cbFxn to rtn the pkt tmpPacket = QUE_get(&chan->pendList); get another pkt frm the Q while (tmpPacket != (IOM_Packet *)&chan->pendList) as long as there are pkts { tmpPacket->status = IOM_ABORTED; as above... mark the pkt ‘aborted’ (*chan->cbFxn)(chan->cbArg, tmpPacket); run the cbFxn to rtn the pkt tmpPacket = QUE_get(&chan->pendList); get another pkt frm the Q } } } inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg chan Called in response to:  TSK: SIO_flush()  TSK: SIO_abort()  DIO: stream timeout add if (chan->mode == INPUT) { IRQ_disable(IRQ_EVT_RINT1); } else { IRQ_disable(IRQ_EVT_XINT1); } here if ints on/off to be controlled by IOP availability for easier to read code, this could have been: while (!QUE_empty(&chan->pendList); this does add a few cycles, since a QUE operation will be longer than a simple equality test, as was done here if the QUE_empty version is used, move the QUE_get (last line) to the beginning of the while loop Restore instead of enable ! ! T TO Technical Training Organization 57

58 Code Example : dsk5402_mcbsp_ad50.c ‘C5402 McBSP AD50 TSK SIO_reclaim DSP... SIO_issue SIO DIO  Inclusions, Definitions, Declarations, Globals  mdBindDev, mdUnBindDev  mdCreateChan() mdDeleteChan()  mdSubmitChan(), mdControlChan()  Interrupt functions  Header file T TO Technical Training Organization 58

59 ISR functions static Void rxIsr(Void) { ChanHandle chan = &chans[INPUT]; if (chan->dataPacket == NULL) { MCBSP_read(hMcbsp); // dummy read return; } *chan->bufptr = MCBSP_read(hMcbsp); updateChan(chan); } static Void txIsr(Void) { ChanHandle chan = &chans[OUTPUT]; if (chan->dataPacket == NULL) { MCBSP_write(hMcbsp, 0); // dummy write return; } MCBSP_write(hMcbsp, *chan->bufptr & 0xfffe); updateChan(chan); } inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg chan T TO Technical Training Organization 59

60 ISR functions static Void rxIsr(Void) { ChanHandle chan = &chans[INPUT]; if (chan->dataPacket == NULL) { MCBSP_read(hMcbsp); // dummy read return; } *chan->bufptr = MCBSP_read(hMcbsp); updateChan(chan); } static Void txIsr(Void) { ChanHandle chan = &chans[OUTPUT]; if (chan->dataPacket == NULL) { MCBSP_write(hMcbsp, 0); // dummy write return; } MCBSP_write(hMcbsp, *chan->bufptr & 0xfffe); updateChan(chan); } inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg chan if ints are turned off when no IOP is present, then the if{} clause can be removed in both ISRs could have done bufptr++ here, instead of in updateChan T TO Technical Training Organization 60

61 ISR subroutine: updateChan static Void updateChan(ChanHandle chan) { IOM_Packet *tmpPacket; temporary holder for packet ptr chan->bufptr++; increment ISR’s buffer ptr chan->bufcnt - -; decrement ISR’s buffer counter if (chan->bufcnt == 0) { when the buffer is completed chan->dataPacket->status = IOM_COMPLETED; mark the packet completed tmpPacket = chan->dataPacket; save packet ptr in tmp chan->dataPacket = QUE_get(&chan->pendList); get a new packet from the queue if(chan->dataPacket == (IOM_Packet *)&chan->pendList) if the queue was empty {chan->dataPacket = NULL; } mark current packet ‘null’ else { otherwise, for the new packet chan->bufptr = chan->dataPacket->addr; reset the ISR’s buffer pointer chan->bufcnt = chan->dataPacket->size; and the ISR’s buffer size var’s } (*chan->cbFxn)(chan->cbArg, tmpPacket); run callback fxn & } rtn completed packet } inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg chan T TO Technical Training Organization 61

62 ISR subroutine: updateChan static Void updateChan(ChanHandle chan) { IOM_Packet *tmpPacket; temporary holder for packet ptr chan->bufptr++; increment ISR’s buffer ptr chan->bufcnt - -; decrement ISR’s buffer counter if (chan->bufcnt == 0) { when the buffer is completed chan->dataPacket->status = IOM_COMPLETED; mark the packet completed tmpPacket = chan->dataPacket; save packet ptr in tmp chan->dataPacket = QUE_get(&chan->pendList); get a new packet from the queue if(chan->dataPacket == (IOM_Packet *)&chan->pendList) if the queue was empty {chan->dataPacket = NULL; } mark current packet ‘null’ else { otherwise, for the new packet chan->bufptr = chan->dataPacket->addr; reset the ISR’s buffer pointer chan->bufcnt = chan->dataPacket->size; and the ISR’s buffer size var’s } (*chan->cbFxn)(chan->cbArg, tmpPacket); run callback fxn & } rtn completed packet } inuse mode *dataPacket pendList *bufptr bufcnt cbFxn cbArg rtLost chan this line can be removed and incorporated in main ISR code as noted earlier, this could instead be a QUE_empty test to inhibit INTs when no IOP present, add if (chan->mode == INPUT) { IRQ_disable(IRQ_EVT_RINT1); } else { IRQ_disable(IRQ_EVT_XINT1); } to know if (and how many times) real- time was lost (no IOP available) add this line and 1 new element to the chan obj rtLost +=1; T TO Technical Training Organization 62

63 Code Example : dsk5402_mcbsp_ad50.c ‘C5402 McBSP AD50 TSK SIO_reclaim DSP... SIO_issue SIO DIO  Inclusions, Definitions, Declarations, Globals  mdBindDev, mdUnBindDev  mdCreateChan() mdDeleteChan()  mdSubmitChan(), mdControlChan()  Interrupt functions  Header file T TO Technical Training Organization 63

64 Header File: dsk5402_mcbsp_ad50.h #ifndef DSK5402_MCBSP_AD50_ #define DSK5402_MCBSP_AD50_ #include /* Driver function table to be used by applications. */ extern IOM_Fxns DSK5402_MCBSP_AD50_FXNS; /* Setup structure for the driver (contains only codec registers) */ typedef struct DSK5402_MCBSP_AD50_DevParams { AD50_Params ad50; /* codec parameters (registers) */ } DSK5402_MCBSP_AD50_DevParams; /* Name of the default device params structure, defined in the driver module */ extern DSK5402_MCBSP_AD50_DevParams DSK5402_MCBSP_AD50_DEVPARAMS; /* Mini-driver init function -- initializes driver variables, if any */ extern Void DSK5402_MCBSP_AD50_init( Void ); #endif #pragma CODE_SECTION(DSK5402_MCBSP_AD50_init, ".text:init") Void DSK5402_MCBSP_AD50_init(Void) { } init function from.c file – as is often the case, it is an empty function... T TO Technical Training Organization 64

65 ti Technical Training Organization 65


Download ppt "Copyright © 2004 Texas Instruments. All rights reserved. 1.Introduction 2.Real-Time System Design Considerations 3.Hardware Interrupts (HWI) 4.Software."

Similar presentations


Ads by Google