How to operate gpio in Windows CE (EVC) -- reprinted

Source: Internet
Author: User
How to operate gpio in Windows CE
How to operate gpio in Windows CE
Released on: 14:16:27 Author: Source:

How to operate gpio in Windows CE (using arm9-s3c2410 as an example)

 

Gpio is the most basic input and output channel of the ARM chip. In ads, operations are performed by a single-chip microcomputer and its registers are directly read and written. On the arm9-7 platform, the Windows CE system maps the real IP address of gpio (for example, the base IP address of gpio 2410 is 0x56000000) to the virtual IP address space (the gpio corresponds to 0xb1600000, by performing operations on this virtual address space, you can control, input, and output gpio or other on-chip resources.
To operate the gpio of a platform, find the virtual address in the corresponding BSP according to the base address, and find the data structure that facilitates the operation of this address. The key functions are virtualalloc and virtualcopy. The convenience of CE is that user-Mode Applications can still use these two functions to access all these virtual spaces. for less complex programs, the write driver can even be omitted and operated directly in the application. In fact, before ce6, these drivers also work in the user State.
The following describes how to operate gpio of Samsung S3C2410:
1. First, in the s2410.h file of the BSP, find the virtual address ing and the register structure that operates the gpio (this will be changed as needed when you create some special device BSP)
//
// Registers: I/O port
//

# Define iop_base 0xb1600000 // 0x56000000
Typedef struct {
Unsigned int rgpacon; // 00
Unsigned int rgpadat;
Unsigned int rpad1 [2];

Unsigned int rgpbcon; // 10
Unsigned int rgpbdat;
Unsigned int rgpbup;
Unsigned int rpad2;

Unsigned int rgpccon; // 20
Unsigned int rgpcdat;
Unsigned int rgpcup;
Unsigned int rpad3;

Unsigned int rgpdcon; // 30
Unsigned int rgpddat;
Unsigned int rgpdup;
Unsigned int rpad4;

Unsigned int rgpecon; // 40
Unsigned int rgpedat;
Unsigned int rgpeup;
Unsigned int rpad5;

Unsigned int rgpfcon; // 50
Unsigned int rgpfdat;
Unsigned int rgpfup;
Unsigned int rpad6;

Unsigned int rgpgcon; // 60
Unsigned int rgpgdat;
Unsigned int rgpgup;
Unsigned int rpad7;

Unsigned int rgphcon; // 70
Unsigned int rgphdat;
Unsigned int rgphup;
Unsigned int rpad8;

Unsigned int rmiscr; // 80
Unsigned int rdckcon;
Unsigned int rextint0;
Unsigned int rextint1;
Unsigned int rextint2; // 90
Unsigned int reintflt0;
Unsigned int reintflt1;
Unsigned int reintflt2;
Unsigned int reintflt3; // A0
Unsigned int reintmask;
Unsigned int reintpend;
Unsigned int rgstatus0; // AC
Unsigned int rgstatus1; // B0
Unsigned int rgstatus2; // B4
Unsigned int rgstatus3; // B8
Unsigned int rgstatus4; // BC
 
} Iopreg;
Replace these copies.

2. create an application project in EVC, because the virtualcopy function is not defined in the header file, but in coredll. the LIB provides symbolic connections, so we can simply add a function definition here.
# Ifdef _ cplusplus
Extern "C"
{
# Endif

Bool virtualcopy (lpvoid, lpvoid, DWORD, DWORD );

# Ifdef _ cplusplus
}
# Endif
At the same time, copy the definition in step 1 here.

3. Write the gpio operation function in the application according to the operation method in the driver.
(1) define a register struct variable
Volatile iopreg * v_piopregs;
(2) Allocate space for this variable and map it to the register space.
V_piopregs = (volatile iopreg *) virtualalloc (0, sizeof (iopreg), mem_reserve, page_noaccess );
If (v_piopregs = NULL)
{
Debugmsg (1, (text ("v_piopregs is not allocated/n/R ")));
Return true;
}
If (! Virtualcopy (pvoid) v_piopregs, (pvoid) iop_base, sizeof (iopreg), page_readwrite | page_nocache )){
Debugmsg (1, (text ("v_piopregs is not mapped/n/R ")));
Return true;
}
Debugmsg (1, (text ("v_piopregs is mapped to % x/n/R"), v_piopregs ));
After these three steps, the v_piopregs operation will be directly associated with the gpio register
For example, set the GPB control register to all output
V_piopregs-> rgpbcon = 0x155555;
Set GPB data register output high level
V_piopregs-> rgpbdat = 0x3ff;

For more operations, you need to check the datasheet of arm and the source code of BSP of wince.

For non-arm platforms, you can refer to this idea for CE operations.

Basic I/O operations under WinCE
Released on: 12:16:06 Author: Source:
I/O operations on peripherals are actually the registers for reading and writing peripherals. The x86 or ARM processor we usually use determines on the hardware that the physical address cannot be directly accessed after the wince system is started, therefore, we need to do some work to implement I/O operations.

First, you must understand the address ing mechanism in Windows CE. There are two types of address for wince: physical address and virtual address. The difference between CPU Hardware in different architectures leads to different address ing. MIPS and sh x processors, without MMU, define a 1g physical address directly in the CPU and kernel; while x86 and arm have MMU units, define the ing between physical addresses and virtual addresses in oemaddresstable, or call createstaticmapping and nkcreatestaticmapping after the OS starts to implement static ing from virtual addresses to physical addresses. static ing addresses can be used by the operating system kernel to access devices by ISR. If we want to access peripherals in the application, we must establish a dynamic ing relationship between the physical address and the virtual address. We can use virtualalloc and virtualcopy (or directly call the mmmapiospace function) to achieve this.

Second, if you are operating on the I/O or storage attached through the bus, you must first convert the BUS address to the system address on the CPU, and then map the physical address to the virtual address. Check the CPU datasheet to find the I/O address. call haltranslatebusaddress () to convert the BUS address to the system address on the CPU, and then call the mmmapiospace function to implement the ing between the virtual and the virtual networks. You can also use transbusaddrtovirtual () directly convert the online address to the virtual address of the system.

Third, in general applications, accessing I/O is the virtual address of the cache segment, and the driver must access the virtual address of the non-Cache segment. Simply put, no cache segment virtual address = cache segment virtual address + 0x20000000.

To sum up, if the wince kernel (such as Hal) accesses external I/O, you only need to define the ing between physical addresses and virtual addresses in oemaddresstable; if the application or driver wants to access I/O, the work to be done includes: 1. Perform a dynamic ing between the physical and virtual addresses of the CPU, 2. Operate on virtual addresses.

In the x86 and ARM-based CPUs, the method for accessing the system memory varies with the program's mode hierarchy.
1. in the kernel mode of the system, you only need to perform static ing between virtual and real addresses in oemaddresstable for access at the oal layer. for example, the ing table of the X86 architecture is as follows:
; Oemaddresstable defines the mapping between physical and virtual address // defines the ing between 4 GB virtual address and MB Storage
; O must be in a readonly Section
; O first entry must be Ram, mapping from 0x80000000-> 0x00000000
; O each entry is of the format (va, Pa, cbsize)
; O cbsize must be multiple of 4 m
; O last entry must be (0, 0, 0)
; O must have at least one non-zero entry
; Ram 0x80000000-> 0x00000000, size 64 m // map the physical address 0x00000000 to the virtual address 0x80000000
Dd 80000000 H, 0, 04000000 H
; Flash and other memory, if any
; Dd flashva, flashpa, flashsize
; Last entry, all zeros
Dd 0 0 0
2. to Access RAM in a driver or application (user mode), you can either use oemaddresstable + virtualcopy, or directly use the mmmapiospace function to create a ing between the physical address and the virtual address of the current process.
After oemaddresstable, the physical address of the CPU is mapped to the virtual address of the OS kernel layer. If you need to access the memory in a common application, you also need to use unzip aalloc + virtualcopy to perform a secondary ing from the kernel to the current process (in one case, your OS is configured to full kernel mode, in this case, any application can access the OS Kernel address ).
Several key functions are briefly described:
Virtualalloc is used to reserve or submit space in the virtual address space of the current process. The unit is 64 kB when it is retained, and 4 kb when it is submitted. Its function prototype is

Lpvoid virtualalloc (

Lpvoid lpaddress, // The starting pointer for allocating virtual addresses

DWORD dwsize, // size, in bytes

DWORD flallocationtype, // type, set to mem_reserve

DWORD flprotect // access protection, set to page_noaccess

);

Virtualcopy is used to bind a physical address to a static ing virtual address:

Bool virtualcopy (

Lpvoid lpvdest, // virtual Destination Address pointer, accept the returned value of virtualalloc

Lpvoid lpvsrc, // source physical address pointer

DWORD cbsize, // The size must be the same as the virtual address

DWORD fdwprotect // access protection type

);

Note the fdwprotect parameter. For driver access, you must set it to page_nocache to access the virtual address without a cache segment. If the physical address range of the ing is above 0x1fffffff, page_physical must be used. In this case, lpvsrc must be shifted to eight places to achieve address alignment. (This is determined by the implementation of virtualcopy in the kernel. In that function, if page_physical is used, physaddr is removed from the left to the back, the source code is stored in memory MEM in the private/winceos/coreos/nk/kernel directory. dovirtualcopy in C)

Mmmapiospace is used to map physical addresses directly to virtual addresses unrelated to processes. Function prototype:

Pvoid mmmapiospace (

Physical_address physicaladdress,

Ulong numberofbytes,

Boolean cacheenable

);

An example of using virtualalloc + copy: the physical address 0x10000000 is mapped to the virtual address space.

# Include <windows. h>

# Define physaddr (pvoid) 0x10000000)

// Physaddr is the physical address of the peripheral

// Registers

# Define size (4800*4)

Lpvoid LPV;

Bool Bret;

LPV = virtualalloc (0, size, mem_reserve, page_noaccess );

// For a user mode driver, always leave the first

// Parameter 0 and use only the flags mem_reserve

// And page_noaccess check the return value: LPV = 0

// Is an error

Printf (text ("virtualalloc reservation @ % 8.8lx/R/N"), LPV );

Bret = virtualcopy (LPV, physaddr> 8, size, page_readwrite | page_nocache | page_physical );

// The LPV parameter is the virtual address returned

// By virtualalloc ().

// Always use page_nocache */

// Check the return value: Bret = 0 is an error */

Printf (text ("virtualcopy returned: % d/R/N"), Bret );

// At this point LPV is a virtual address which maps

// The I/O registers

// At physaddr for size bytes */

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.