Presentation is loading. Please wait.

Presentation is loading. Please wait.

Copyright © 2003 Texas Instruments. All rights reserved.

Similar presentations


Presentation on theme: "Copyright © 2003 Texas Instruments. All rights reserved."— Presentation transcript:

1 Copyright © 2003 Texas Instruments. All rights reserved.
DSP C5000 Chapter 7 DSP BIOS Copyright © 2003 Texas Instruments. All rights reserved.

2 DSP BIOS Offers the Following:
Real-time scheduler Preemptive thread management kernel Real-time analysis tools Allows application to run uninterrupted while displaying debug data Real-time data exchange (RTDX) Allows two-way communication (target  host) while target is running Programming of DSP peripherals Graphical input to peripheral initialization through Chip Support Library (CSL) Think of debugging our software as we might do with hardware. When working with hardware we have instruments (probes, scopes, logic analyzers, meters) that give us clues to what’s going on in our system. DSP/BIOS and CCS give us similar capabilities for software debugging. Well, using instruments is fairly intuitive for hardware - you hold or connect a probe to each point you want to see. Then look at the meter/display. How is this done for software? DSP/BIOS provides two types of instruments. Let’s describe each of these: 1. Built-in (or embedded) instrumentation. You don’t have to do anything to get this data. The various parts of DSP/BIOS, in particular the scheduler, provides this data automatically to CCS. 2. User defined “probes”. The most common software debugging instrument is probably printf. But we’ve already found out that it’s a bad tool for real-time analysis. To that end, DSP/BIOS provides a set of real-time optimized versions of printf. The most basic is called LOG_printf. You can use these to send data from your DSP to the CCS whenever you need to.

3 DSP/BIOS Configuration Tool
Creating a New Configuration File Configures System Creates and defines objects (ex. IDL) Configure hardware interrupts and creates interrupt vectors Configures memory and creates linker command file Calculates estimated data and minimum stack size needed DSP BIOS gives a graphical tools and framework to build a software project

4 Files Generated by the Configuration Tool
Configuration database file Save program.cdb programcfg.h## programcfg.s## programcfg.cmd programcfg_c.c programcfg.h Allocated at link time

5 File Extensions prog.out Linker Compiler/ Assembler prog.h prog.c
prog.asm prog.cdb prog.cmd (optional) progcfg.s## progcfg.h## progcfg.cmd progcfg.obj Linker prog.out mod.h Compiler/ Assembler prog.obj user.lib *.lib

6 Startup Sequence BIOS_reset() main() BIOS_init() BIOS_start()
system code user code interrupt enable bits OFF “other” initialization BIOS_reset() do hardware initialization enable individual interrupts return main() interrupt flag bits OFF vector table pointer initialized BIOS_init() HWI_startup() enables HWI start DSP/BIOS scheduler BIOS_start() Note here that the main() function can do any system initialization that needs to be performed before interrupts and the thread schedulers are enabled. The main() function MUST return before the rest of the BIOS initialization steps complete. interrupt enables interrupt flags global int enable IMR IFR INTM C5000

7 Startup Sequence Initialize the DSP and the hardware
The software stack pointer, memory wait states, memory configuration registers This is part of the boot.c file that is part of the DSP/BIOS library BIOS_init( ) is called automatically Initializes DSP/BIOS modules main() System initialization that needs to be performed Enable selected interrupts before interrupts are enabled globally Must return to complete the program initialization!!!! BIOS_start( ) is called automatically Start DSP/BIOS Enables interrupts globally Drops into the DSP/BIOS “background loop” Initializes communication with the host for real-time analysis

8 Real-time Systems Systems that respond in a correct and timely way to events Events are occurrences that cause a non-sequential change in the software flow of control Driven by hardware and software events Interrupt signals IF-THEN and CASE statements Real-time System inputs outputs

9 Real-time Systems attributes
Events driven: Synchronous (end of internal timer counting). Asynchronous (ADC or DAC interrupt). Time constrained: Hard (Critical deadlines, catastrophic). Soft (Non-critical deadlines, non-catastrophic). Concurrency: Processing more than one event apparently “simultaneously” to meet deadlines Means: Preemption & multi-tasking. Deterministic & reliable: Will always have the same behaviour within a known response time. It is necessary to be able to determine how and when a real-time system will respond to each possible combination and sequence of events. A real-time system may need to be able to handle virtual simultaneous responses to events. Not true of all applications but increasing so with advance applications.

10 Audio Example For this system to function properly, the filter needs to calculate the correct output before the next sample arrives What events drive this system? Receive and Transmit Interrupts Asynchronous Event - could happen at different points in code Polling of Receive and Transmit conditions Synchronous Event - always happens at the same place in code Audio Filter Sample

11 Real-time System Requirements
Period Compute CPU Usage Routine A: 22 s 11 s (50%) TI DSP Filter Period = 1/fs A running idle Deadline! To function correctly real-time systems must produce the correct result within a specified time for each event Correct output Meet timing constraints - deadlines More than one event may occur in a given period and deadlines must be met System must always meet the above requirements Time 1 2 3 5 4 6 7

12 Adding new function (new task)
TI DSP Previous Requirement DSP filters audio signal Filter New Requirement Add DTMF function DTMF is independent of filter Issues: Do we have enough bandwidth (MIPS)? Will one routine conflict with the other? How do we create the compound system? DTMF DTMF : Dual Tone Multi Frequencies.

13 System Implementation Considerations
main { while(1) } One method: put each algo into an endless loop under main Problems: What if algorithms run at differing rates? (eg: our filter runs ~ 44 KHz and the DTMF algo ~ 8 KHz) What if one algorithm overshadows another, starving it for recognition or delaying it’s response beyond the limits of the system? Filter DTMF

14 Interrupt Driven System - Problem
Period Compute CPU Usage Routine A: 22 s 11 s (50%) Routine B: 125 s 33 s (26%) 76% TI DSP main { while(1); } Timer1_ISR Timer2_ISR Missed ! running A y1 y2 y3 y4 idle A B The second interrupt A is shadowed by ISR B. When ISR B finished a new interrupt A occurs, the previous is then lost ! Here Preemption would mean that, considering that ISR A has a higher priority than ISR B, this one will be suspended until ISR A is finished. Time 1 2 3 5 4 6 7 B Only one can run at a time... There are two elements of CPU loading: average & instantaneous

15 DSP/BIOS Scheduling A B Time DSP/BIOS B suspended
DSP/BIOS provides scheduling: Tasks are marked to be run by event processing or other task. Scheduler supervises task running depending on status (mark to be run), priority, … main { return; } Timer1_ISR start A; Timer2_ISR start B; running A idle B Time 1 2 3 4 5 6 7 DSP/BIOS B suspended A Modules written independently Easier to maintain - Module interaction minimized Built-in Scheduling - Managed by DSP/BIOS B

16 DSP/BIOS Preemptive Scheduler
Foreground Hard Real-time Hardware Interrupts 1st-TIER RESPONSE Sample-by-sample processing Microsecond duty cycles Software Interrupts 2nd-TIER RESPONSE Frame-by-frame processing Millisecond duty cycles Idle Best Effort Soft Real-time Background

17 Preemption The act of changing the flow of control from one process to another based on priority Higher priority always runs Allows one process to asynchronously interrupt the execution of the currently executing process Concurrent processing Preemption needs “context switch”. It is the action of switching the processor between one process and another due to preemption Saving (push) and restoring (pop) the context of the processor on the data stack : Registers Program counter Stack pointer Completed Posted Started Inactive Ready Running Resume Preempted

18 DSP BIOS Scheduler The Scheduler provides both h/w and s/w interrupt management DMAC2 INT SWI Pending HWI_enter h/w real-time code Post s/w interrupt (SWI) HWI_exit SWI: filter code HWI SWI Fast response to interrupts Minimal context switching High priority for CPU Can post SWI Danger of missing an interrupt while executing ISR Latency in response time Context switch performed Selectable priority levels Can post another SWI Execution managed by scheduler HWI (HardWare Interrupt): program interruption which are caused by hardware events (see Chapter 6). SWI (Software Interrupt): program interruption which are caused by soft events (ie special assembly instructions INTR ). ISR (Interrupt Service Routine): program which is run when an interrupt occurs either HWI or SWI. When you’re looking at a scheduler, it needs to be able to handle two different types of interrupts: hardware and software. Hardware needs to run NOW, minimum latency, high priority. These tasks are typically short. Software is not so time critical, and may take longer to complete. Shown above we can see a hardware interrupt that posts a software interrupt. Let’s say the hardware interrupt determines the frame and re-programs the DMA. The software interrupt processes the filter and keys off the output process. Let’s look at a scheduling example...

19 Priority Based Thread Scheduling
HWI 2 HWI 1 SWI 3 SWI 2 SWI 1 MAIN IDLE post3 rtn subroutine ISR function A thread may be a: (highest) post2 rtn post1 rtn int2 rtn rtn rtn First while we have HWI1 and 2 at the top of the screen, you won’t actually see this in the real-time analysis tool. All hardware interrupts will be grouped in “other threads”. Start at main on the bottom left. Main runs until a return were the only process running is BIOS idle. Hardware interrupt 1 occurs and starts running. It posts software interrupt 2. SWI 2 can’t run until HWI 1 completes. Until it does SWI 2 is pending. When HWI1 completes SWI2 begins until HWI2 occurs. HWI2 posts SWI3 three which cannot run until HWI2 completes. When HWI2 completes, the highest priority pending interrupt will run. In this case that’s SWI3. SWI 3 posts SWI1 during its run. When SWI 3 completes, the highest priority pending interrupt is allowed to run ... which is SWI2. When SWI 2 completes there are no other pending interrupts so we return to the idle process. The priority of hardware interrupts is hard wired into the device. The user can determine the priority of software interrupts. int1 (lowest) User sets the priority...BIOS does the scheduling How do you set the priorities ?

20 Interrupts that Post SWI
HWI_enter HWI_exit post isr Running p = 2 Ready p = 1 Idle API: Application Programming Interface This diagram shows two task of unequal priority. First the lower priority task is running and is interrupted by an ISR which then runs a higher priority task. The lower priority task running is preempted and rescheduled. After the higher priority task is completed it prompts the lower priority task to run time Use HWI_enter and HWI_exit assembly macros APIs that may affect scheduling: SWI_andn, SWI_dec, SWI_inc, SWI_or, SWI_post, PIP_alloc, PIP_free, PIP_get, PIP_put, PRD_tick, SEM_post

21 HWI_enter and HWI_exit
Saves selected registers Sets interrupt mask to disable/enable nested interrupts Informs scheduler to delay running newly posted SWI HWI_exit Restores selected registers Restores interrupt mask Returns from interrupt These APIs can only be called from assembly.

22 Writing an ISR in Assembly(C54x)
SWI_post example .include hwi.h54 .include swi.h54 .def isr1 isr1: HWI_enter MASK,IMRDISABLEMASK SWI_post ;other ISR code HWI_exit MASKS,IMRRESTOREMASK Template ISR with no scheduling APIs called .def isr1 isr1: ;save context (PUSHM) ;ISR code ;restore context (POPM) ;return from interrupt Complete discussion on Program Startup sequence coming up. Note here that the main() function can do any system initialization that needs to be performed before interrupts and the thread schedulers are enabled. The main() function MUST return before the rest of the BIOS initialization steps complete. Pros/Cons of HWI_enter and HWI_exit Easy way to save/restore registers Able to call scheduling APIs Allows for nested interrupts (preemption) Execution overhead Callable only from Assembly

23 HWI_enter and HWI_exit (C54x)
.include c54.h54 ; mask constants .include hwi.h54 ; HWI module definitions HWI_enter MASK IMRDISABLEMASK HWI_exit MASK IMRRESTOREMASK MASK - registers to save/restore IMRDISABLEMASK, IMRRESTOREMASK - IMR bits to mask (1s) or restore (1s) HWI_enter C54_A|C54_B,0x0008 Saves the A and B accumulators, disables TINT0, all other INTs nested Complete discussion on Program Startup sequence coming up. Note here that the main() function can do any system initialization that needs to be performed before interrupts and the thread schedulers are enabled. The main() function MUST return before the rest of the BIOS initialization steps complete. HWI_enter C54_CNOTPRESERVED,0xFFFF Saves C “Save on Call” registers, disables all nested interrupts

24 Hardware Interrupt Dispatcher
Automatically includes HWI_enter and exit via a stub function Can be used with ISR’s written in C Easy to use Not as optimized as calling HWI_enter and exit in your code which allow you to save selected registers. Stub function (or temporary function) returns a common value that is used use until the full implementation of the function is written. It is a function header with no body that is used. to create a compilable level 1 of a program.

25 Writing an ISR in C Int i; /*global var*/ { HWI_enter(MASKS) i++; SWI_post(&swiAudio) HWI_exit(MASKS) } void isr1(void) ISR can be purely in C if no scheduling APIs are called Declare as interrupt void isr1(void) Don’t use interrupt keyword if calling with HWI_enter and HWI_exit ISR! HWI_exit does a return from interrupt Complete discussion on Program Startup sequence coming up. Note here that the main() function can do any system initialization that needs to be performed before interrupts and the thread schedulers are enabled. The main() function MUST return before the rest of the BIOS initialization steps complete.

26 DSP/BIOS (SWI) Software Interrupts
Defer hardware interrupt service routines to software interrupts Preemptive Priority 0-14 Context Switch Automatic for SWI Single stack model (Application Stack) Adding priority levels will increase stack size requirements HARDWARE INTERRUPT IDLE minpri maxpri 15 XXXX Software signals are patterned after interrupt service routines. They are triggered through kernel API calls. When a software signal is triggered, the SIG module internally schedules execution of the corresponding function (written in C or assembler) at a point forward in time. Software signals can have 15 different priorities. All software signals have higher priority than the background processes but lower priority than any hardware interrupt. When the function corresponding to a software signal starts to execute, it will run to completion UNLESS it is preempted by a hardware ISR or by a signal of higher priority. Software signals DO NOT BLOCK. Once scheduled for execution, the corresponding function will get called immediately if there’s no higher priority signal or hardware ISR that is currently executing. Otherwise, the function will be invoked at a later time. Signals are triggered through a call to SIG_post. SIG_post triggers signals much in the way hardware interrupts are triggered. A new call to SIG_post before the signal function is executed does NOT have the effect of causing the signal to be executed twice.(This may mean that we’re missing real time as the signal’s function did not get a chance to execute before the signal was triggered again). Besides SIG_post, the kernel supports a series of additional functions for triggering a signal, each of which modifies a 16 bit mailbox associated with the signal object. in response to client programs triggering individual signal objects through kernel API calls. Once triggered, execution of a signal handler will strictly preempt any current background activity within the program as well as any signals of lower priority; interrupt routines on the other hand take precedence over software signals and remain enabled during execution of all handlers, allowing timely response to hardware peripherals within the target system. As the following diagram portrays, DSP/BIOS software signals enrich familiar embedded designs limited to only two classes of program processes — high- priority interrupt routines and low-priority background functions — by introducing an additional band of prioritized foreground processes that dovetails nicely between the extremities.

27 Software Interrupt Objects
SWI_Obj (example) Pointer to a function Arg0 and Arg1 Priority Initial Bit/Count value Will cover later All interrupts run on a common stack Stores local variables Nested function calls SWI_obj fxn arg0 arg1 priority mailbox FIR SWI_obj fxn C func arg0 arg1 priority mailbox SWI_obj fxn Common .stack FFT arg0 arg1 ASM func priority mailbox

28 Scheduling Rules and SWI API
post Highest Priority isr p = 2 Running p = 1 Ready p = 1 post Idle If a higher priority process becomes ready, the running process is preempted Processes of same priority are scheduled first-in first-out Lowest Priority time SWI_post() Unconditionally post a software interrupt Software interrupt is posted in the ready state

29 DSP/BIOS Software Interrupt Mailbox
Used to conditionally or unconditionally post software interrupt Can be used as a counter or a bit field Set a bit to notify how SWI was posted Allows multiple conditions to be met before a SWI can run Allows to monitor missed SWI Mailbox is an int value (16 bits for C5000) SWI_inc increments the mailbox and posts SWI C The Mailbox is reset when SWI C runs Use SWI_getmbox() to get previous mailbox value (must be 1)

30 Calling DSP/BIOS API from Assembly(C54x)
Example: Void SWI_post(SWI_Obj *swi); Preconditions: cpl = ovm = c16 = frct = cmpt = 0 dp = GBL_A_SYSPAGE ar2 = address of SWI Object intm = 0 (if outside an ISR) Post conditions: none Modifies: ag, ah, al, ar0, ar2, ar3, ar4, ar5, bg, bh, bl, c, dp, t, tc .include swi.h54 ; SWI module definitions ; Setup preconditions and save context stm _swiAudio,ar2 ; argument to SWI_post SWI_post ret ; return Only include the xxx.hxx header files for those API modules the assembly program uses. This modular approach reduces the assembly time of programs that do not use all the modules. Preconditions: all registers that must be set before using the macro. Postconditions: all registers set by the macro. Modifies: all registers modified by the macro, including registers in the postconditions list. Several macros modify a 32-bit register. In these cases, the “Modifies” list includes both the high and low registers that make up the 32-bit register.

31 Counting Events: SWI_dec()
HWI SP Buffer SWI_dec(&SWI) SWI B 11 Mailbox SWI_dec() decrements the mailbox value SWI is posted if mailbox = 0 Set the initial mailbox value in the SWI’s properties Mailbox is resets to initial value when SWI runs

32 Who Called: SWI_or SWI_or(1) SWI A SWI SUB SWI_or(2) SWI B SWI_or(4)
Int mailbox; mailbox = SWI_getmbox(); SWI_or(2) SWI B switch(mailbox) { case 1: {do this} case 2: {do this} case 4: {do this} case 8: {do this} } SWI_or(4) SWI C SWI_or(8) SWI D SWI_or() sets a bit in the mailbox and posts the SWI Use SWI_getmbox() to read the mailbox and determine which routine posted the instance of the SWI Mailbox is reset when SWI runs

33 Handling Conditions: SWI_andn
Adaptive Filter swiGetData swiAdapt swiFilter Mailbox 1 SWI_andn(1) SWI_andn(2) Note: SWI_andn => mailbox AND ( NOT MASK ) SWI_andn() clears a bit in the mailbox value SWI is posted if mailbox = 0 Set the initial mailbox value in the SWI’s properties Mailbox is resets to initial value when SWI runs

34 Posting SWIs - A Summary
Mailbox is a bitmask Mailbox is a counter N/A Always post SWI_or SWI_inc SWI_post Post if mailbox = 0 SWI_andn SWI_dec Use SWI_getmbox() to read the mailbox Set initial value of the mailbox in the SWI’s properties Mailbox is reset when SWI runs

35 Timer Services Clock Manager Periodic Functions CPU clock rate 4
Hi-res Clock N interrupt Low-res Clock Clock Manager max clock rate timer counter timer period System Tick The Clock Manager configures: Period of the system tick - Timer Period Functions that run as part of the timer ISR - CLK_Objects DSP/BIOS configures a CLK Object, PRD_clock, to manage A low and a high resolution time stamp Periodic Functions

36 Periodic Function Manager
PRD_clock will conditionally trigger the DSP/BIOS central dispatcher via PRD_tick DSP/BIOS central dispatcher runs a software interrupt called PRD_swi PRD_swi contains a list of periodic processes in a table PRD_swi will select the periodic functions to run based on the period Run at the same priority - FIFO f1(t) P1 P2 P3 P4 f2(t) f3(t) f4(t) When defining PRD objects from the configuration file, their period is defined in system ticks. When the number of system ticks specified have elapsed, the function associated with the PRD object is called, so that the function will be executed periodically. PRD objects can be defined to have 2 modes of execution: continuous, this could also be called ‘real periodic’. It means that the function will be executed when the number of systems ticks have elapsed. The second mode of execution is called one shot. If a function is associated to a one-shot periodic object it will only execute after the application calls PRD_start for the corresponding periodic object. In this case, the period does not reflect a regular interval of time between executions of the function. Rather, it represents the time elapsed between the call to PRD_start and when the function is scheduled for execution. When using functions written in C, the user must be careful and add a ‘_’ to the name of the functioning the conf tool. This is so that it matches the _ that will be added by the compiler. (Otherwise linking errors result). DSP/BIOS PRD_tick() Timer Interrupt PRD_swi / P PRD_clock

37 Periodic Objects Period is the # of system ticks in which object’s function will run Function is the routine you want to executed Type defines the nature of the periodic function Continuous vs. One-shot prdFunc1 Period 4 Function func1() Type continuous DSP/BIOS PRD_tick() / P The kernel’s PRD module manages a set of objects called PRD objects that schedule the execution of functions periodically. In order to do so, the PRD module needs a time base. This is provided by calls to PRD_tick. The execution of PRD_tick constitutes a ‘system tick’, that provides the time base for scheduling functions to be executed periodically. The call to PRD_tick can be associated with the time interrupt. In this case, the time base will be provided by the system’s low resolution clock. Alternatively, any other hardware interrupt that executes periodically can be used to drive the calls to PRD_tick. PRD_swi prdFunc2 Period 9 Function func2() Type continuous Timer Interrupt PRD_clock

38 Continuous Periodic Functions
Call the function every N ticks Triggered by the system tick Timer interrupt or Periodic interrupt that calls PRD_tick() Execution timeline tick func1() func1() func2() 1 2 3 4 5 6 7 8 9 10 The kernel’s PRD module manages a set of objects called PRD objects that schedule the execution of functions periodically. In order to do so, the PRD module needs a time base. This is provided by calls to PRD_tick. The execution of PRD_tick constitutes a ‘system tick’, that provides the time base for scheduling functions to be executed periodically. The call to PRD_tick can be associated with the time interrupt. In this case, the time base will be provided by the system’s low resolution clock. Alternatively, any other hardware interrupt that executes periodically can be used to drive the calls to PRD_tick. prdFunc1 Period 4 Function func1() Type continuous prdFunc2 Period 9 Function func2() Type continuous

39 Communication Techniques
Process 0 Process 1 Global variables Can corrupt global data while preempted Queues (linked list) Useful for first-in, first-out sequencing Buffering of data using shared memory Time-relative buffering Useful for time-relative data transferred or for slow data Double or ping-pong buffering Ring or circular buffering Use queues to pass pointers to arrays of data buffers in memory See Chapter 3 for more information on circular bufferring.

40 Queue Simple data structure for basic communication
Useful for first-in, first-out processing Manages a linked list of elements Includes atomic and non-atomic APIs Allows insertion and deletion anywhere in the Queue Elements can be any data structure Must include QUE_Elem QUE module provides a set of functions to manage a linked list of QUE elements. Elements can be inserted or deleted anywhere within the list. QUE module is mainly used to implement FIFO queues, elements are inserted at the tail and removed from the head of the list. QUE_Elem is used by QUE module to enqueue the structure while the remaining fields contain the actual data to be enqueued. Atomic operation because they modify kernel data structure. Unlimited in length because it is a double linked list. Only limited by memory 54

41 Data Pipes I/O building blocks between processes (and interrupts)
PIP buffers Software Interrupt Software Interrupt I/O building blocks between processes (and interrupts) A pipe object has 2 sides - writer and reader Built-in notify functions are used to synchronize Queued data buffers are allocated at link time Divided into a fixed number of frames of a particular size nframes framesize

42 Multitasking Multitasking Foreground Background Hard Real-time
Hardware Interrupts Hard Real-time Foreground Software Interrupts Multitasking Advanced scheduling technique that uses tasks for scheduling Provides a multi-tiered response to events Number and state of tasks can dynamically vary over execution timeline Block or terminate tasks before completion Change the priority of tasks dynamically while executing a function Scheduling is achieved by programmatically calling a central dispatcher Priority levels State of readiness Soft Real-time Idle Background

43 Task Control Block Model
DSP/BIOS Startup READY Task is deleted Preemption TSK_delete() TSK_yield() TSK_setpri() Task is readied SEM_post() RUNNING TSK_tick() Task exits Task suspends TERMINATED BLOCKED TSK_setpri(task, newpri): sets a task’s execution priority dynamically. It can be used to raise priority as deadline approaches TSK_sleep(Uns sleeptime): Blocks execution for n ticks of system clock TSK_tick(): Advances the task alarm tick by one. Default - called from PRD_clock (system tick): Similar to PRD_tick for PRD TSK_exit() TSK_sleep() SEM_pend() Task is deleted TSK_delete()

44 Semaphores and Priority
SEM_pend(semObj) block! interrupt Priority=2 C Not dependent on A SEM_pend(semObj) block! Priority=1 Not dependent on A Depends on A B SEM_post(semObj) preempted! Priority=1 Precondition for B and C A Semaphores act as a synchronization mechanism, either to synchronize two or more tasks between them or to share a physical resource between multiple tasks. The point of this slide is to show that semaphores have a fifo Q. If a lower priority task pends on a semaphore, then a higher priority task pends on the same semaphore, when the semaphore is posted, the lower priority task will run first because it pended first. time Both B and C depend on A B pends on the semaphore first, then C When A posts, B runs first because it pended first Semaphores use a FIFO Queue for pending tasks!

45 - / Mailbox API MBX_post MBX_pend Copies a message into a buffer
Block if mailbox is full or if another writer is waiting MBX_pend Copies a message out of a buffer Block if mailbox is empty or if another reader is waiting task2 task0 - / MBX_post task3 MBX_pend task1 task4

46 Interfacing to Mailboxes
Void writer(Int id){ MsgObj msg; Int i; for (i=0; ; i++) { msg.id = id; msg.val = i % NUMMSGS + (Int)('a'); if ( MBX_post(&mbx, &msg, TIMEOUT) == 0 ){ SYS_abort("timeout %s”, TSK_getname()); }}} typedef struct MsgObj { Int id; Char val; }; Void reader(Void){ MsgObj msg; Int i; for (i=0; ;i++) { if (MBX_pend(&mbx, &msg, TIMEOUT) == 0) { SYS_abort("timeout %s”, TSK_getname()); } LOG_printf(&logTrace,"%c from (%d)", msg.val, msg.id); }}

47 Each Task has its own Stack
SWI vs. TSK SWI TSK Stack Configuration Uses the System Stack Each Task has its own Stack Blocking & Suspending No Yes Deleted Prior to Completion by other Threads No Yes User Name, Error Number, Environment Pointer No Yes API Interface Assembly and C C

48 Disabling and Enabling Interrupts
Hardware interrupts Atomic Functions Scheduler Can be nested oldCSR = HWI_disable(); `critical section` HWI_restore(oldCSR); It’s really easy. HWI_disable to disable interrupts. and HWI_enable to enable them around critical code in your signals. SWI_disable(); `critical section` SWI_enable(); TSK_disable(); `critical section` TSK_enable();

49 Built-in Real-Time Analysis Tools
What is “Real-Time” ? Gather data on target (3-10 CPU cycles) Send data during BIOS IDLE (100s of cycles) Format data on host (1000s of cycles) Data gathering does NOT stop target CPU Execution Graph Software Logic Analyzer Debug Scheduling Tick: specified time period based on hardware timer CPU Load Graph Analyze time NOT spent in IDLE

50 Built-in Real-Time Analysis Tools
Statistics View Profile routines without halting the CPU Message LOG Send debug msgs to host Std printf requires: K bytes K CPU cycles LOG_printf requires: bytes CPU cycles LOG_printf (&trace, “Loopback enabled”);

51 APPLICATION PROGRAM INTERFACE
DSP/BIOS Modules DSP/BIOS Library LOG CLK HST HWI IDL TRC PIP PRD RTDX SWI STS LOG STS APPLICATION PROGRAM INTERFACE ? USER FUNCTIONS func1 { } func2 { } #include <log.h> func1 { LOG_printf(...); } #include <sts.h> func2 { STS_set(…); }

52 Creating and Reference Instances
Instances are created in the Configuration Tool Code that creates them is in audiocfg.s## Object declaration is in mod.h (i.e. log.h) Function #include <std.h> #include <log.h> extern far LOG_Obj logTrace1; extern far LOG_Obj logTrace2; func() { LOG_printf( &logTrace1, … ); LOG_printf( &logTrace2, … ); } Instances must be referenced (extern) by files that use them Header file is needed for the declaration of the type

53 Interface to Statistics Accumulators
Count the number of occurrences of an event Track the maximum and average for a variable Tracking minimum value of a variable Timing events or monitoring incremental differences in a value STS_add(&stsObj); /* count an event */ STS_add(&stsObj, value); /* track the maximum and average */ STS_add(&stsObj, -value); /* track the minimum */ STS_set(&stsObj, CLK_gethtime()); STS_delta(&stsObj, CLK_gethtime()); /* algorithm OR event */

54 STS API Effect on STS Object Fields
STS_add(x) STS_set(y) STS_delta(z) STS_reset Count Total Max Previous* +1 +x replaced if x > Max y z +1 +(z-Previous) replaced if (z-Previous) > Max largest negative number *Previous field is set using Config tool, STS_set, or STS_delta

55 Clock Interface CLK_getltime() CLK_gethtime() CLK_countspms()
Returns the number of timer interrupts that have occurred CLK_gethtime() Returns the number of high resolution clock cycles that have occurred CLK_countspms() Returns the number of timer register ticks per millisecond

56 Trace Control Allows the user to enable and disable instrumentation on the target Limit the effects of instrumentation on program execution Two interfaces Host interface RTA Control Panel User Program TRC API Control Panel can be used to change trace control bits. Global Host Enable can be used to control RTA without changing individual settings. Explanation on TRC module (trace manager) can be found in spru404c.pdf pages to 2.

57 Target Trace Control Masks
Trace Control Mask - declared in trc.h TRC_LOGCLK LOG timer interrupts TRC_LOGPRD LOG periodic ticks and PRD functions TRC_LOGSWI LOG software interrupt events TRC_LOGTSK TSK events TRC_STSHWI Gather statistics on HWI TRC_STSPIP Count number of frames in data pipes TRC_STSPRD Gather statistics on PRD function execution TRC_STSSWI Gather statistics on SWI execution TRC_STSTSK Gather statistics on TSK execution TRC_USER0 User defined TRC_USER1 User defined TRC_USER2 User defined TRC_GBLTARG Global target TRC_GBLHOST Global host

58 RTDX: Real-Time Data Exchange
RTDX enables non-obtrusive two-way communication between the host PC and the DSP (during IDLE) Transfer speed limited by JTAG bandwidth (~10 MHz serial), connection type (parallel vs. XDS) and DSP activity level Transfers made via RTDX calls in DSP application code PC TMS320 DSP Display CCS User TI 3rd Party JTAG E M U R T D X USER CODE RTDX answers the challenge of debugging real-time data. There’s no need to set break points or probe points and let CCS up load data. RTDX transfers the specified information hearing idle time in BIOS. The transfer rate can be affected by many factors. If you’re not in idle long enough the data can’t be transferred. If your working with the parallel cable interface, this is extremely slow and you will not be able to transfer significant amounts of data. Best case, with enough time in idle and working with the XDS you can achieve near audio rates using RTDX. RTDX API: RTDX_createOutput/InputChannel RTDX_enableOutput/Input RTDX_disableOutput/Input RTDX_write RTDX_read RTDX_readNB RTDX_channelBusy RTDX_sizeofInput Third Party Display

59 RTDX Target APIs Declarations in main() Read from channel
#include <rtdx.h> RTDX_CreateInputChannel(writeload); RTDX_CreateOutputChannel(readload); Declarations RTDX_enableInput(&writeload); RTDX_enableOutput(&readload); in main() if(!RTDX_channelBusy(&writeload)) { RTDX_readNB(&writeload, &loadVal, sizeof(loadVal)); } Read from channel RTDX_write(&readload, &loadVal, sizeof(loadVal)); Write to channel

60 Host Side RTDX (VB code)
set r = CreateObject(“RTDX”) status = r.open(“readload”, “R”) Open read channel set w = CreateObject(“RTDX”) status = w.open(“writeload”, “W”) Open write channel status = r.ReadI4(data) Read 32-bit integer status = w.WriteI4(value,bufferstate) Write 32-bit integer

61 Sequence Diagram VB or OLE application Code Composer DSP
Initialization RTDX: Create Input Channel Create RTDX Connection RTDX: Create Output Channel Get handle for RTDX channel RTDX handle Send RTDX commands to DSP rtdxToDSP.write Send some control commands to DSP rtdxCommandHandler RTDX: Get control commands rtdxCommandHandler

62 Why CSL? Why do we need a Chip Support Library (CSL)?
To support increasingly complex on-chip peripherals and applications Frees the user from necessity of defining and maintaining code for peripheral configuration and control Provide standard method for accessing and controlling peripherals Let’s begin by discussing why we even need a Chip Support Library. In today’s market signal processing applications and the on-chip peripherals needed to support them have become increasingly complex, leading to significant investment in software needed to configure and control on-chip peripherals. A development tool such as CSL frees the user from having to write and maintain their own code to configure and control on-chip peripherals. By providing a standard method for accessing and controlling peripherals that can be shared amongst teams and projects, it encourages code re-use and TI frees the user from having to define, develop, and maintain code for peripheral configuration and control on their own, helping to decrease time-to-market and promoting rapid prototyping of applications.

63 CSL Introduction CSL – Chip Support Library
Runtime library designed to configure, control, and manage on-chip peripherals Adapted for both C6000™ and C5000™ DSP platforms Written mostly in C, optimized for code size and speed Partitioned into scalable/expandable API modules Module granularity is structured such that each peripheral is covered by a single API Having discussed why we need a product such as CSL, let’s turn to what TI offers in its Chip Support Library. CSL is a runtime library designed to promote easy configuration, control and management of on-chip peripherals. CSL is adapted for both C6000™ and C5000™ DSP platforms. The CSL library is written mostly in C and is optimized for code size and speed. The API for each peripheral is implemented in a separate module, guaranteeing module granularity, scalability, and expandability. For example, if CSL is used to configure McBSP, only code and functions directly used from the McBSP API will be included in the source. Because the API module for each peripheral is independent, if new APIs are added to better support McBSP, this will have no effect on module code for any other peripheral.

64 CSL: On-Chip Peripherals
C54x™ DSP Modules CHIP DAA DAT DMA EBUS GPIO HPI IRQ MCBSP PLL PWR UART WDTIM C55x™ DSP Modules ADC CHIP DAT DMA EMIF GPIO IRQ I2C MCBSP PLL PWR RTC USB WDTIM This is a list of the peripherals CSL supports for the C5000™ DSP processor platforms. Note that many of the same modules are supported by all of the processor platforms. The basic APIs for these modules are the same across processor platforms, increasing code portability when migrating between processors. For more details about the modules supported on various devices, please refer to the CSL User’s Guide for your processor platform.

65 CSL Features Standard protocol for programming on-chip peripherals: set of APIs (functions, data types, macros) Symbolic peripheral description (hardware abstraction) set of macros for accessing and building register and field values Basic resource management for multi-resource peripherals Integrated into DSP/BIOS™ build: CSL Graphic User Interface Peripheral ease-of-use: shortened development time, portability CSL does not provide an expert system for peripheral configuration and control. The user must have knowledge about how to use the peripheral and know which fields in which registers need to be set in order to configure the peripheral for use in their application. CSL is a tool to help make configuration easy once the proper register settings are understood by the user. CSL does not require the use of any other DSP/BIOS™ component in order to work properly. Although it is a component of DSP/BIOS, because of the scalability and granularity of DSP/BIOS, CSL may be accessed without reference to any other DSP/BIOS module. In addition, the CSL functions are contained in a separate library file. This allows CSL to be used in a stand-alone mode, when no other DSP/BIOS components are needed by the application. CSL is a standard protocol for programming on-chip peripherals. It provides a symbolic interface to the hardware by abstracting the hardware registers and register fields necessary for controlling the peripheral devices from within C. It contains a definition for every register and every bit field for each supported peripheral. CSL provides basic resource management for targets with multiple peripherals of the same type, such as multiple McBSPs. Or for single peripherals which have multiple resources, such as multi-channel DMAs. CSL is fully integrated into the DSP/BIOS build. Because of this, it also provides a graphical user interface (GUI) for peripheral configuration and resource management. The CSL GUI is accessed via the DSP/BIOS™ graphical configuration tool (GCONF). CSL promotes shortened development time because it frees the user from having to develop and maintain code to access the on-chip peripherals. Because the APIs are standard it promotes code re-use and eases porting when migrating from one processor to another.

66 TI Foundation Software
Chip Support Library is Dedicated to the On-Chip Peripherals User Application Drivers Dsplib Imglib CSL DSP/BIOS™ Kernel/Scheduler CSL is a component within TI’s Foundation Software. The TI Foundation Software consists of DSP/BIOS™, of which CSL is a component, and a complementary set of signal- and image-processing libraries. DSP/BIOS is a compact operating system kernel and scheduler. As an operating system kernel, it provides device control through the CSL component. The Foundation software also includes a set of signal- and image-processing kernels, DSPLIB and IMGLIB, for fast application code prototyping and development. This combination of software provides a basic code set upon which device drivers and applications may be built, promoting rapid prototype development, decreasing development time and time-to-market. CODEC Timer McBSP EMIF CPU DIP Switches DSP Target Board

67 CSL Naming Conventions
All data structures, functions and macros begin with the capitalized 3–4 letter module/peripheral name followed by an underscore, PER_ . (e.g. MCBSP_xxx, DMA_xxx) All data structures begin with a capital letter in the word immediately following the underscore, PER_Xxxx (e.g. DMA_Config, I2C_Init) All functions begin with lowercase letter in the word immediately following the underscore, PER_xxx (e.g. DMA_open, MCBSP_config) All macros are in upper case, PER_XXX (e.g. MCBSP_RGETH(…), DMA_ADDRH(…)) Before introducing the central features of CSL, let’s look at the naming convention that the CSL API uses. Names of all data structures, functions, and macros begin with the capitalized 3–4 letter module/peripheral name followed by an underscore. In this presentation and in the CSL User’s Guide, PER is used as the place marker for the actual API module name. Any valid module name may be substituted wherever PER appears in the text. All data structures begin with a capital letter in the word immediately following the underscore. For example DMA_Config, or I2C_Init. All functions begin with a lowercase letter in the word immediately following the underscore. Two examples are DMA_open function and MCBSP_config function. All macro names are in uppercase. For example MCBSP_RGETH and DMA_ADDRH.

68 CSL Resource Management Data Types and Functions
CSL handle data type PER_Handle: pointer to data structure returned from call to PER_open() for multi-resource modules (e.g. McBSP, DMA, etc.) CSL functions Handle = PER_open(): allocation of a multi-resource peripheral device. Returns handle associated to the allocated resource (e.g. McBSP port or DMA channel) Ex: hDma = DMA_open(DMA_CHA2,DMA_OPEN_RESET); PER_close(Handle): de-allocation of a previously opened multi-resource device Ex: DMA_close(hDma); CSL provides data types and functions to manage resources for those APIs that support multiple devices. For example, a target may have more than one serial port, or may have multi-channel DMAs. Resource management is provided in order to avoid multiple tasks/threads attempting to use the same peripheral. The PER_Handle data type is a structure pointer returned from a call to the PER_open() function for an API that services peripherals with multiple ports or channels such as McBSP or DMA. The Handle returned from the open function is used in subsequent calls to other API functions. It is a required argument passed to most functions in CSL modules supporting multiple devices/channels. The PER_open() and PER_close() functions perform the basics of resource management. PER_open() reserves a resource for exclusive use. After the task using this device is completed, a call to PER_close() then frees the device for use by other processes.

69 CSL Configuration Register-based configuration
PER_Config: data structure containing values for all control registers needed to configure the peripheral PER_config([handle], PER_Config *config): configure the peripheral by setting the full values of memory-map registers. Ex: EMIF_config(&myconfig); DMA_config(hDma,&myconfig); Parameter-based configuration PER_Init: data structure containing functional parameters needed to configure the peripheral PER_init(PER_Init *init) configure the peripheral via a set of parameters. Ex: I2C_init(&myParams); CSL supports two models of peripheral configuration, register-based configuration and parameter-based configuration. Register-based configuration is accomplished by defining and initializing a configuration structure and passing this structure as an argument to a PER_config() function. The structure consists of a value for each register needed to control the device. There is very little intelligence built into the PER_config() functions. They simply copy the register values from the configuration structure into the corresponding control register. For example, EMIF_config, takes the address of an EMIF_Config structure. The data contained in the EMIF_Config structure is copied directly to the EMIF control registers. Because DMA has multiple resources, the DMA_config() function takes two arguments, a pointer to a DMA_Handle and the address of a DMA_Config structure. The DMA_config() function copies the register values from the configuration structure directly into the DMA control registers for the channel specified by the DMA_Handle. For peripherals that have a large number of control registers, such as USB, using a configuration structure for initialization of the device is undesirable. Modules such as this use parameter-based initialization instead. Parameter-based initialization uses a data structure that defines the essential operating parameters needed to configure the peripheral. This data structure is passed as argument to a PER_init() function. The PER_init() function calculates the correct register settings based on the parameter values. Using parameter-based data structures allows the user to configure the peripheral without having detailed knowledge of each register and bit field. Because the PER_init()function must decide what values need to be placed in which control registers for the configuration, the PER_init() functions have larger code size and execution times than the register-based configuration functions. Not all CSL modules support parameter-based initialization. Please refer to the CSL documentation for further information on the initialization models supported for a given peripheral.

70 Sample CSL Configuration Structure
typedef struct { Uint16 dmacsdp; Uint16 dmaccr; Uint16 dmacicr; DMA_AdrPtr dmacssal; Uint16 dmacssau; DMA_AdrPtr dmacdsal; Uint16 dmacdsau; Uint16 dmacen; Uint16 dmacfn; Uint16 dmacfi; Uint16 dmacei; } DMA_Config; Here we show the C definition for the DMA_Config data type. All of the PER_Config data types have a similar structure in that there is a structure member defined for each configurable peripheral control register. Some structures may contain additional elements when required.

71 Initializing CSL Config Structures
Creating register masks User generated Use PER_REG_RMK macros provided by CSL DMA_DMAGCR_RMK(0,0,1) Use other pre-defined CSL macros such as PER_FMK(reg,field,val) to create mask DMA_FMK(DMAGCR,FREE,1) CSL provides several macros that can be used to create register values for initializing the configuration data structure. The PER_REG_RMK macros may be used to create register values based on the values of individual bit fields. The _RMK macros take as arguments the values for each writable bit field within a peripheral control register. This requires a that a value be passed for each writable field. This is a valuable tool when a large number of fields or an initial value for each field must be set. If only one or two fields need to be set, then the PER_FMK macros can be used to form values for a single field. The values created by PER_FMK macros may be ORed together to form a complete register value.

72 CSL Coding Checklist Include the appropriate CSL API headers (csl.h, csl_per.h) Declare and initialize CSL configuration data structures and handles (DMA_Config myDmaCfg = {…}; DMA_Handle hDma0;) Call CSL_init() prior to calling or using any other CSL API function For multi-resource peripherals such as McBSP and DMA, call PER_open() function to reserve resource (MCBSP_open(), DMA_open()…) Call PER_config() to configure peripheral Call PER_start() to begin peripheral operation Call PER_close() to free resources of multi-resource peripherals Having discussed CSL data type and configuration functions, lets now move on to outlining the essential steps in writing code using the CSL APIs. There are seven steps in using the CSL API. Step 1: Include the appropriate API headers. For example, when configuring DMA, include csl_dma.h Step 2: Declare and initialize CSL configuration structures and handles. For example, if using DMA, declare a DMA_Config structure to pass to the DMA_Config function and a DMA_Handle that will be used to store the return value from the call to DMA_open(). Step 3: CSL_init() must be called once to initialize the library state before calls to any other CSL API. Because this should be done only once, it is best to locate this call in a generic initialization function for the application. Step 4: For multi-resource peripherals such as McBSP and DMA, call the appropriate PER_open function to reserve exclusive use of the resource. Step 5: Call PER_config() to write values to the control registers for peripheral operation. Step 6: Start the peripheral by calling PER_start(). Step 7: When the peripheral is no longer required by the process, call PER_close to free the resource. This checklist is the same for both C6000™ and C5000™ DSP platforms.

73 CSL Example (DMA) #include <csl.h> #include <csl_dma.h>
DMA_Handle hDma0; DMA_Config dmaCfg0 = { …}; void main() { CSL_init(); hDma0 = DMA_open(DMA_CHA0, DMA_OPEN_RESET); DMA_config(hDma0,&dmaCfg0); DMA_start(hDma0); while(!(DMA_FGETH(hDma0,DMACSR,FRAME)); // Process data DMA_close(hDma0); } 1. Include Headers 2. Declare CSL Data Objects 3. Initialize Library 4. Open DMA Channel (returns DMA_Handle to hDma0) 5. Configure Channel (note use of hDma0) Having discussed CSL data type and configuration functions, lets now move on to outlining the essential steps in writing code using the CSL APIs. There are seven steps in using the CSL API. Step 1: Include the appropriate API headers. For example, when configuring DMA, include csl_dma.h Step 2: Declare and initialize CSL configuration structures and handles. For example, if using DMA, declare a DMA_Config structure to pass to the DMA_Config function and a DMA_Handle that will be used to store the return value from the call to DMA_open(). Step 3: CSL_init() must be called once to initialize the library state before calls to any other CSL API. Because this should be done only once, it is best to locate this call in a generic initialization function for the application. Step 4: For multi-resource peripherals such as McBSP and DMA, call the appropriate PER_open function to reserve exclusive use of the resource. Step 5: Call PER_config() to write values to the control registers for peripheral operation. Step 6: Start the peripheral by calling PER_start(). Step 7: When the peripheral is no longer required by the process, call PER_close to free the resource. This is a simple example of how to use the CSL DMA API. The steps are the same regardless of how the DMA is being used. The first step is to include the appropriate header files. In this case we need to include csl.h to initialize the CSL library and csl_dma.h to include the definitions for the DMA API. Second, declare the CSL data objects that will be needed to call the DMA API functions. hDma0 will contain the pointer to the DMA_Handle that will be returned from the call to DMA_open() function. dmaCfg0 will contain the register values necessary to configure the DMA transfer. The hDma0 and dmaCfg0 objects will be passed as arguments to the DMA_config() API function. Third, call CSL_init() to initialize the state of the CSL library. This must be called prior to calling any other CSL API. Fourth, open a DMA channel via call to the DMA_open API. If DMA_CHA0 is not in use, the function returns a pointer to a structure containing information about the channel that was opened. This “Handle” is then used as an argument to all subsequent DMA API function calls to identify the channel being used. The DMA_Handle, hDma0, is passed along with the address of the DMA_Config structure, dmaCfg0, to the DMA_config() function. Fifth, configure the DMA channel by calling the DMA_config function. DMA_config() copies the register values from the dmaCfg0 strucutre directly into the DMA control registers for DMA channel 0. Sixth, begin the DMA transfer by calling DMA_start. Seventh, after the transfer is complete, and the DMA channel is no longer needed, de-allocate the resource by calling DMA_close(). This frees DMA channel 0 for use by other processes. 6. Start Transfer 7. Close/Free DMA Channel

74 CSL Compile/Link CheckList
Use –dCHIP_XXXX to select the correct target device. (e.g. CHIP_5510PG1_0) cl55 –dCHIP_5510PG1_0 myFile.c For C5000™ DSPs, in a linker command file always include .csldata in the SECTIONS directive of the linker command file. The .csldata section should be linked into data RAM Include the correct library, cslXXXX.lib, (e.g. csl5510PG1_0.lib) There are three important things to remember when compiling and linking code that accesses CSL modules. 1) Use the –d option of the compiler to define the correct target. This enables CSL to compile code for the correct device and make sure that no attempts are made to access modules that are not defined for the selected device. 2) For C5000™ DSP, is to include the .csldata section in the SECTIONS directive of a linker command file. This section must be placed in data RAM. The .csldata section contains state information for the CSL library. Placing this data in a separate section allows the CSL library code to be ROMable. 3) Include the correct CSL library for the target device.

75 1. Select A Default Configuration Database Seed
Using the CSL GUI 1. Select A Default Configuration Database Seed Step 1: Choose a default configuration database seed file. Invoke the graphical user interface from within Code Composer Studio™ by selecting the FILE menu, Click New from the resulting pull-down menu, then click DSP/BIOS™ configuration. This will bring up a screen titled New which will display a choice of several default configuration database files (with extension .cdb). The .cdb files store all configuration information. The .cdb files are used by the code generation phase to create all assembly source files, C source files, C header files, and linker command files. Select the .cdb file that is appropriate for your board by clicking on the icon for that board and then click on OK, or simply double click on the icon. If you are not sure which .cdb file to select, choose the generic one for your target.

76 These are the only two elements needed for CSL configuration
After selecting the appropriate cdb seed file, the GCONF utility displays the current configuration. By default the name of the configuration is Config1. The configuration database name is displayed at the top left hand side of the window. The name may be changed when the configuration file is saved. There are many elements on the DSP/BIOS™ configuration tree. But only two of these are needed to configure peripherals using CSL. These elements are the System tree and the Chip Support Library tree. These are the only trees we will focus on in this presentation.

77 2. Select target Go to the Global Settings menu in the System tree.
When you expand the System tree the Global Settings icon is displayed. A right click on Global Settings displays a pull-down menu. From this pull-down menu select Properties. Notice that the current property values are displayed in a separate window on the right-hand side of the display. Step 2: Now select target processor. From the pull down menu next to the label Chip Support Library (CSL), select the target processor. Doing this ensures that the CSL GUI presents options that are compatible with the target and that automatic code generation will include the appropriate CSL library in the generated linker command file.

78 Peripheral Configuration Peripheral Resource Management
3. Expand CSL Tree Peripheral Configuration Peripheral Resource Management Step 3: Expand the CSL tree. We can now see all of the peripherals that are currently supported by the graphical user interface. Not all CSL modules have a GUI. Please refer to the CSL User’s Guide for your device for more detailed information on which modules are supported by the GUI. For our current example, we are going to expand the DMA tree to create a DMA configuration. Expanding the DMA tree reveals the two central capabilities provided by CSL, configuration and resource management. Therefore, the DMA tree has a DMA Configuration Manager and a DMA Resource Manager. Note, that the Resource Manager already has pre-defined objects, one for each DMA channel on the target device. The DMA Configuration Manager currently has no objects.

79 4. Use Configuration Manager to insert a new configuration object
Step 4: Use the configuration manager of the module to insert a new configuration object. This is done by right clicking on the configuration manager icon and selecting Insert. In our current example we are inserting a DMA configuration object using DMA Configuration Manager, however all configuration managers in CSL GUI operate the same.

80 Inserted DMA Configuration Object
The DMA Configuration Manager allows the creation of multiple configuration structures/objects that can be used to initialize any one of the six DMA channels. This slide shows the configuration object that was just inserted. The configuration object has a default name of “dmaCfg0”. The object name may be changed by either clicking on the object name or right clicking on the object and selecting “Rename” from the pull-down menu. Now that we have an object inserted, we can customize the configuration by right clicking on the configuration object and selecting Properties from the pull-down menu.

81 DATA TYPE has pull-down menu Number of Elements uses input box
Step 5: Set/change configuration parameters for the peripheral using the “Property Pages” of the object. The property pages of all modules have a “General” tab which is displayed first. There are no configuration elements on the General tab for DMA, so we have pre-selected the Frame tab by clicking on “Frame”. Any properties page may be selected simply by clicking on the tab for that page. The Frame property page contains settings for number of elements per frame, number of frames, and for setting frame indexing. Let’s note some things about the layout of the property page. If an input box contains a downward arrow in the right-hand corner, such as for DATA TYPE. This means that there is a pull-down list of available values. The CLS GUI will implement a pull-down menu when there is a fixed set of integral values for the specified field. If there is a wide range of possible values it simply uses a input box such as is used for Number of Elements. All property pages are displayed with an initial set of default values. These are the power-on default values for the peripheral. In this case we have typed 128 into the input box for the number of elements to transfer. And have pre-selected the DATA TYPE as 16 bits.

82 5. Use Properties pages to set/change configuration parameters
Step 5: Use properties pages of configuration object to set/change configuration. To configure the parameters for the source of the transfer, we click on the “Source” tab. The source tab defines all of the parameters necessary to configure the source side of the transfer. The source may be specified either Symbolic or Numeric. Symbolic indicates the use of the address of a user defined symbol that will be defined in C source. In this case we are using a symbolic address for a buffer called “src” that we will declare in our application. The source and destination pages have identical parameters. To complete the configuration we need only to go to each tab and select the settings needed for the transfer. Each CSL module (with a few exceptions) has an “Advanced” tab. The Advanced tab displays what the register contents would be with the currently selected parameters. The Advanced tab is automatically updated when a parameter is changed on any of the other property pages.

83 Scroll bar indicates more information available
User may choose to set register values manually The Advanced tab can be used to manually set the needed register values. When this is done, you simply type the register value directly into the input box provided. The remaining property pages will automatically be updated to reflect the settings that correspond to the register value. This allows the user to check the settings associated with a specific register. Once the configuration is complete, click on OK to accept the current settings.

84 6. Select resource object and set its properties
Resource Object Properties Step 6: If resource manager exists and resource needs to be pre-opened, then select appropriate resource object and set its properties. Now that a configuration object has been defined, we can attach that particular object to a DMA resource using the DMA Resource Manager. The DMA Resource Manager has pre-defined resource objects for each DMA channel. So we don’t need to insert a resource management object. We are going to use DMA Channel 0. To select DMA Channel 0, right click on DMA0 resource object and select Properties from the pull-down menu. The properties page of the DMA0 resource object will then be displayed. The resource manager allows the user to decide if they want to pre-open the device. Selecting this option automatically creates a DMA_Handle object and the generated code will call DMA_open to reserve the channel. The DMA handle object will get the return value from the call to DMA_open(). Note, that currently all other options on this page are “grayed-out”. When an field is “grayed-out” this means that the correponding option is not currently available to you. When the “Open Handle to DMA” option is checked the other input boxes on this page will be un-grayed allowing the user to select these options.

85 The pull-down menu displays all DMA configuration objects currently defined
In this example, we have accepted the default name of the handle, hDma0, and selected pre-initialization using the configuration object just created, dmaCfg0. To preserve the current settings for the resource object, click OK to close. We are now finished with the DMA channel 0 configuration. The DMA channel configuration is now complete. We could also configure any other peripheral at this time. For the purposes of this example we will not do so, but all available peripherals may be configured within the same GUI session.

86 8. Save the new configuration file.
(Note:The base name of the saved configuration database file determines the name of the generated files) Step 8: Save the new configuration (project.cdb) To save the current settings, close the configuration tool. A dialog box will appear that asks if you want to save the new configuration. Click “yes” to save the file. When saving the file, note that the configuration tool will use the base name of the saved configuration file to name all of the generated files it creates.

87 Generated Files myproject.cdb – updated configuration database containing all inserted objects and all current property settings myprojectcfg.h – extern declaration of all created objects, definition of CHIP_XXXX, plus #include of CSL module headers myprojectcfg_c.c – definition and initialization of created objects. Contains function calls to PER_open,PER_config/PER_init() for pre-opened/ pre-initialized objects myprojectcfg.sXX – defines which DSP/BIOS™ elements are present and provides initialization for those elements myprojectcfg.cmd – linker command file, includes CSL library and .csldata placement When the new configuration database file is saved, in this case named, myproject.cdb, the following files are automatically generated: myprojectcfg.h myprojectcfg_c.c myprojectcfg.sXX myprojectcfg.cmd Where dma2 is the base name of the .cdb file that was created. To completely integrate the new code into the project, add the new dma2.cdb to the files in the project. When the project is built, the generated files will automatically be included in the build.

88 myprojectcfg.h #include <csl_dma.h> extern DMA_Config dmaCfg0;
extern DMA_Handle hDma0; extern void CSL_cfgInit(); myprojectcfg.h file contains the extern declarations for the objects created by the configuration tool. This file must be included in your C source to access these objects.

89 myprojectcfg_c.c DMA_Config dmaCfg0 = { 0x0205, /* (CSDP) */
0x5060, /* (CCR) */ 0x0008, /* (CICR) */ (DMA_AdrPtr)&src, /* (CSSA_L) */ NULL, /* (CSSA_U) */ (DMA_AdrPtr)&dst, /* (CSDA_L) */ NULL, /* (CSDA_U) */ 0x0080, /* (CEN) */ 0x0001, /* (CFN) */ 0x0000, /* (CFI) */ 0x /* (CEI) */ }; DMA_Handle hDma0; The projectcfg_c.c file contains the actual object definition and initialization. This is just an excerpt from this file for full file contents please see the additional material included with this presentation.

90 CSL_cfgInit() void CSL_cfgInit() { …
Choosing Pre-Open in CSL GUI results in code generated to call PER_open function void CSL_cfgInit() { hDma0 = DMA_open(DMA_CHA0,DMA_OPEN_RESET); DMA_config(hDma0, &dmaCfg0); } In addition to declaration and initialization of the data objects, the projectcfg_c.c file defines a function call CSL_cfgInit(). This function is automatically called by the DSP/BIOS™ boot routine. It contains the code to pre-open and pre-initialize the selected resources. Notice that this function does not call CSL_init(). CSL_init() is automatically called by the DSP/BIOS boot routine. Choosing Pre-Initialization in CSL GUI results in code to call PER_config function

91 C Source Using GUI-Generated Files
Include generated C header file #include “myprojectcfg.h" #define N 128 Uint16 src[N]; Uint16 dst[N]; void main(void) { DMA_start(hDma0); while (!DMA_FGETH(hDma0,DMACSR,FRAME)); DMA_close(hDma0); } Start DMA Because the code generated by the configuration tool is automatically called by DSP/BIOS™ init, it greatly reduces the amount of code required in the application source code that accesses and uses the peripheral. Note that now in the C source, there are no calls to CSL_init(), DMA_open(), or DMA_config(). There are no #includes for csl.h and csl_dma.h header files. There are no declarations or initializations for the DMA_Config structure nor the DMA_Handle. All of these have been provided by the source generated by the configuration tool and are automatically invoked via the DSP/BIOS boot routine. The code only needs to begin the transfer by calling DMA_start, wait for the frame to complete and close the DMA channel after its done. Free Resource

92 Note: Handle-based macros are also available.
CSL Macros Macros for accessing field and register values PER_ADDR(reg) Gets the memory address of the specified peripheral register reg PER_RGET(reg) Returns the value of the specified peripheral register reg PER_RSET(reg,val) Writes the value val to the peripheral register reg PER_FGET(reg,field) Returns the value of the specified field of the register PER_FSET(reg,field,val) Writes the value val to the specified field of the register CSL provides a number of macros that provide access to peripheral control registers and their values. Each module API defines its own set of macros that allow access to peripheral registers and the individual logical register fields that control peripheral operation. Each macro name begins with the three- or four-letter module name. The PER_ADDR macro returns the address of the specified register. PER_RGET returns the current value of the specified register, PER_RSET, sets the value of the specified register. PER_FGET returns the right justified value of the specified logical bit field within the given register. PER_FSET sets the value of the specified logical bit field in the given register. The PER_REG_RMK and PER_FMK macros are used to define values for specified register or bit fields. These values can be used in macros/functions that set the register value, or as initialization values within a C declaration. Macros for building field and register values PER_REG_RMK( fieldmsb ,…, fieldlsb ) Creates a register value to store in the register PER_FMK(reg, field, val() Creates a shifted version of the fieldvalue could be used by PER_REG _RMK() Note: Handle-based macros are also available.

93 Literature System Software TMS320C54X
SPRU328 Code Composer Studio User's Guide SPRU423 TMS320 DSP/BIOS User's Guide SPRU TMS320C5000 DSP/BIOS API Reference Guide SPRU420 TMS320C54x Chip Support Library API User’s Guide SPRU433 TMS320C55x Chip Support Library API User’s Guide Refer to Digital Library on this CD.

94 DSP/BIOS Application Notes
SPRA697 How to Get Started with DSP/BIOS II SPRA646 DSP/BIOS II Technical Overview SPRA648 Understanding the Functional Enhancements of DSP/BIOS II and their Utilization in Real-Time DSP Applications SPRA640 Programming and Debugging Tips for DSP/BIOS SPRA660 Building DSP/BIOS Programs in UNIX SPRA653 Understanding Basic DSP/BIOS Features SPRA663 Benchmarking DSP/BIOS II on the TMS320C54x SPRA692 DSP/BIOS II Sizing Guidelines for the TMS320C54x DSP SPRA689 Using DSP/BIOS I/O in Multichannel Systems SPRA700 Writing Flexible Device Drivers for DSP/BIOS SPRA599 DSP/BIOS and TMS320C54X Extended Addressing SPRA695 Real-Time DSP Software Design for a Portable MP3 Player Using DSP/BIOS SPRA598 An Audio Example Using DSP/BIOS SPRA591 DSP/BIOS by Degrees: Using DSP/BIOS in an existing application


Download ppt "Copyright © 2003 Texas Instruments. All rights reserved."

Similar presentations


Ads by Google