C# PXA270 GPIO(eSOM270/SPARK开发工具包)-Windows CE 6.0 R2

C# PXA270 GPIO(eSOM270/SPARK开发工具包)-Windows CE 6.0 R2,c#,arm,mmap,C#,Arm,Mmap,我试图读取多达6个输入和写入多达4个输出使用GPIO。。。这是一个相对简单的应用程序(或者我是这么认为的),但每当我尝试引用GPIO引脚时,我无法通过Win CE停止我的应用程序,在我看来,这就像内存访问冲突错误一样——即使只是配置引脚方向(输入或输出),更不用说使用GLPR0/1/2/3、GPCR0/1/2/3、GPSR)/1/2/3等进行读写 我一定错过了什么,但我看不出有什么——该应用程序是I/O泵继电器控制的一部分,具有: 6 x输入 4倍输出 低级驱动程序代码,线程永久循环读取6个输

我试图读取多达6个输入和写入多达4个输出使用GPIO。。。这是一个相对简单的应用程序(或者我是这么认为的),但每当我尝试引用GPIO引脚时,我无法通过Win CE停止我的应用程序,在我看来,这就像内存访问冲突错误一样——即使只是配置引脚方向(输入或输出),更不用说使用GLPR0/1/2/3、GPCR0/1/2/3、GPSR)/1/2/3等进行读写

我一定错过了什么,但我看不出有什么——该应用程序是I/O泵继电器控制的一部分,具有:

  • 6 x输入
  • 4倍输出
  • 低级驱动程序代码,线程永久循环读取6个输入值,将值写入状态寄存器/内存映射地址,以便GUI应用程序读取(锁定)
  • 每隔1秒钟,GUI读取上述6个输入,然后调用低级驱动程序功能清除6个输入
输入引脚

  • 输入1=gpio24
  • 输入2=gpio 25
  • 输入3=gpio108
  • 输入4=gpio93
  • 输入5=gpio94
  • 输入6=gpio95
输出引脚

  • 输出A1=gpio103
  • 输出A2=gpio104
  • 输出A3=gpio105
  • 输出A4=gpio27
下面是GPIO配置/读/写的代码(在IoRelayControl类中)。在eSOM270(PAX270)上运行的Windows CE 6.0在第一次引用(函数GPIOConfig()中I/O引脚方向的GPIO配置)时杀死我

感激地接受任何建议

using System;
using System.Text;
using System.Threading;

namespace Sampler
{
    unsafe class IoRelayControl
    {
        const byte GPIO24   = 24;
        const byte GPIO25   = 25;
        const byte GPIO108  = 108;
        const byte GPIO93   = 93;
        const byte GPIO94   = 94;
        const byte GPIO95   = 95;

        const byte GPIO103  = 103;
        const byte GPIO104  = 104;
        const byte GPIO105  = 105;
        const byte GPIO27   = 27;

        const bool INVALID_HANDLE_ERROR = false;
        const byte GPIO_AF_0 = 0;
        const byte GPIO_AF_1 = 1;
        const byte GPIO_AF_2 = 2;
        const byte GPIO_AF_3 = 3;
        const bool GPIO_OUTPUT = true;
        const bool GPIO_INPUT = false;
        const byte NO_GPIO_ERROR = 0;
        const byte CONFIG_FAILED_ERROR = 100;
        const byte SET_FAILED_ERROR = 102;
        const byte FAILED_ERROR = 103;
        const byte GPIO_INVALID_HANDLE = 104;
        const byte READ_FAILED_ERROR = 105;
        const byte INVALID_GPIO_ERROR = 106;

        public volatile UInt32* GPDR0_Address = (UInt32*)0x40E0000C;      // GPIO Pin Direction Register 0
        public volatile UInt32* GPDR1_Address = (UInt32*)0x40E00010;      // GPIO Pin Direction Register 1
        public volatile UInt32* GPDR2_Address = (UInt32*)0x40E00014;      // GPIO Pin Direction Register 2
        public volatile UInt32* GPDR3_Address = (UInt32*)0x40E0010C;      // GPIO Pin Direction Register 3

        public volatile UInt32* GPSR0_Address = (UInt32*)0x40E00018;      // GPIO Pin-Output Set Register 0
        public volatile UInt32* GPSR1_Address = (UInt32*)0x40E0001C;      // GPIO Pin-Output Set Register 1
        public volatile UInt32* GPSR2_Address = (UInt32*)0x40E00020;      // GPIO Pin-Output Set Register 2
        public volatile UInt32* GPSR3_Address = (UInt32*)0x40E00118;      // GPIO Pin-Output Set Register 3

        public volatile UInt32* GPCR0_Address = (UInt32*)0x40E00024;      // GPIO Pin-Output Clear Register 0
        public volatile UInt32* GPCR1_Address = (UInt32*)0x40E0001C;      // GPIO Pin-Output Clear Register 1
        public volatile UInt32* GPCR2_Address = (UInt32*)0x40E00020;      // GPIO Pin-Output Clear Register 2
        public volatile UInt32* GPCR3_Address = (UInt32*)0x40E00118;      // GPIO Pin-Output Clear Register 3

        public volatile UInt32* GAFR0L_Address = (UInt32*)0x40E00054;      // GPIO GAFR0_L Alt Func Reg 0
        public volatile UInt32* GAFR0U_Address = (UInt32*)0x40E00058;      // GPIO GAFR0_U Alt Func Reg 0

        public volatile UInt32* GAFR1L_Address = (UInt32*)0x40E0005C;      // GPIO GAFR1_L Alt Func Reg 1
        public volatile UInt32* GAFR1U_Address = (UInt32*)0x40E00060;      // GPIO GAFR1_L Alt Func Reg 1

        public volatile UInt32* GAFR2L_Address = (UInt32*)0x40E00064;      // GPIO GAFR2_L Alt Func Reg 2
        public volatile UInt32* GAFR2U_Address = (UInt32*)0x40E00068;      // GPIO GAFR2_L Alt Func Reg 2

        public volatile UInt32* GAFR3L_Address = (UInt32*)0x40E0006C;      // GPIO GAFR3_L Alt Func Reg 3
        public volatile UInt32* GAFR3U_Address = (UInt32*)0x40E00070;      // GPIO GAFR3_L Alt Func Reg 3

        public volatile UInt32* GPLR0_Address = (UInt32*)0x40E00000;       // GPIO Pin-Level Register 0
        public volatile UInt32* GPLR1_Address = (UInt32*)0x40E00004;       // GPIO Pin-Level Register 1
        public volatile UInt32* GPLR2_Address = (UInt32*)0x40E00008;       // GPIO Pin-Level Register 2
        public volatile UInt32* GPLR3_Address = (UInt32*)0x40E00100;       // GPIO Pin-Level Register 3


        public bool IoInput0 = false;       // input from gpio24
        public bool IoInput1 = false;       // input from gpio25
        public bool IoInput2 = false;       // input from gpio108
        public bool IoInput3 = false;       // input from gpio93
        public bool IoInput4 = false;       // input from gpio94
        public bool IoInput5 = false;       // input from gpio95

        public bool IoOutputA1 = false;     // output to gpio103
        public bool IoOutputA2 = false;     // output to gpio104
        public bool IoOutputA3 = false;     // output to gpio105
        public bool IoOutputA4 = false;     // output to gpio27

        public bool bRunIoRelayCtrlThread = true;

        /// <summary>
        /// 
        /// </summary>
        public void IoPumpRelayCtrlThreadBody()
        {
            do
            {
                // forever loop, permanently reads 6 input values for the GUI app
                // to read (latched)
                IoReadInputs();
                System.Threading.Thread.Sleep(100);             // ms
            } while (bRunIoRelayCtrlThread);
        } 

        /// <summary>
        /// 
        /// </summary>
        /// <param name="gpionum"></param>
        /// <param name="opvalue"></param>
        public void IoSetOutput(byte gpionum, bool opvalue)
        {
            switch(gpionum)
            {
                case GPIO103:
                    IoOutputA1 = opvalue;
                    if (opvalue)
                        GPIOSet(GPIO103);
                    else
                        GPIOClear(GPIO103);
                    break;

                case GPIO104:
                    IoOutputA2 = opvalue;
                    if (opvalue)
                        GPIOSet(GPIO104);
                    else
                        GPIOClear(GPIO104);
                    break;

                case GPIO105:
                    IoOutputA3 = opvalue;
                    if (opvalue)
                        GPIOSet(GPIO105);
                    else
                        GPIOClear(GPIO105);
                    break;

                case GPIO27:
                    IoOutputA4 = opvalue;
                    if (opvalue)
                        GPIOSet(GPIO27);
                    else
                        GPIOClear(GPIO27);
                    break;     

                default:
                    break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void IoReadInputs()
        {
            // Called from IoPumpRelayCtrlThread
            IoInput0 = GPIORead(GPIO24);
            IoInput1 = GPIORead(GPIO25);
            IoInput2 = GPIORead(GPIO108);
            IoInput3 = GPIORead(GPIO93);
            IoInput4 = GPIORead(GPIO94);
            IoInput5 = GPIORead(GPIO95);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ipnum"></param>
        /// <param name="ipvalue"></param>
        public void IoClearInput(byte ipnum)
        {
            // Called from GUI
            // Clear specified input
            if (ipnum > 5) return;

            switch (ipnum)
            {
                case 0:
                    IoInput0 = false;
                    break;

                case 1:
                    IoInput1 = false;
                    break;

                case 2:
                    IoInput2 = false;
                    break;

                case 3:
                    IoInput3 = false;
                    break;

                case 4:
                    IoInput4 = false;
                    break;

                case 5:
                    IoInput5 = false;
                    break;

                default:
                    break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool GPIOConfig()
        {
            // Configure outputs
            *GPDR3_Address |= (0x1 << 7);       // gpio103 as output0 (A1)
            *GPDR3_Address |= (0x1 << 8);       // gpio104 as output1 (A2)
            *GPDR3_Address |= (0x1 << 9);       // gpio105 as output2 (A3)
            *GPDR0_Address |= (0x1 << 27);      // gpio27  as output3 (A4)

            // Configure inputs
            *GPDR0_Address |= (0x0 << 24);      // gpio24 as input0
            *GPDR0_Address |= (0x0 << 25);      // gpio25 as input1
            *GPDR3_Address |= (0x0 << 12);      // gpio108 as input2
            *GPDR2_Address |= (0x0 << 29);      // gpio93 as input3
            *GPDR2_Address |= (0x0 << 30);      // gpio94 as input4
            *GPDR2_Address |= (0x0 << 31);      // gpio95 as input5

            return (false); //for now
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="PinNo"></param>
        /// <returns></returns>
        private bool GPIOSet(byte PinNo)
        {
            switch (PinNo)
            {
                case GPIO103:
                    // OutputA1: GPIO103
                    *GPSR3_Address |= (0x1 << 7);
                    break;

                case GPIO104:
                    // OutputA2: GPIO104
                    *GPSR3_Address |= (0x1 << 8);
                    break;

                case GPIO105:
                    // OutputA3: GPIO105
                    *GPSR3_Address |= (0x1 << 9);
                    break;

                case GPIO27:
                    // OutputA4: GPIO27
                    *GPSR0_Address |= (0x1 << 27);
                    break;
                default:
                    break;
            }

            return (false); //for now
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="PinNo"></param>
        /// <returns></returns>
        private bool GPIOClear(byte PinNo)
        {
            switch (PinNo)
            {
                case GPIO103:
                    // OutputA1: GPIO103
                    *GPCR3_Address |= (0x1 << 7);
                    break;

                case GPIO104:
                    // OutputA2: GPIO104
                    *GPCR3_Address |= (0x1 << 8);
                    break;

                case GPIO105:
                    // OutputA3: GPIO105
                    *GPCR3_Address |= (0x1 << 9);
                    break;

                case GPIO27:
                    // OutputA4: GPIO27
                    *GPCR0_Address |= (0x1 << 27);
                    break;

                default:
                    break;
            }
            return (false); //for now
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="PinNo"></param>
        /// <returns></returns>
        private bool GPIORead(byte PinNo)
        {
            bool res = false;

            switch (PinNo)
            {
                case GPIO24:
                    // Input1: GPIO24
                    res = (*GPLR0_Address | (1 << 24)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure. Sample pulse from
                        // e.g. AQL will be ~ 600ms long.
                        System.Threading.Thread.Sleep(100);                         // Sleep for 100ms
                        res = (*GPLR0_Address | (1 << 24)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                case GPIO25:
                    // Input 2: GPIO25
                    res = (*GPLR0_Address | (1 << 25)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure.
                        System.Threading.Thread.Sleep(20);                          // Sleep for 20ms
                        res = (*GPLR0_Address | (1 << 25)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                case GPIO108:
                    // Input 3: GPIO108
                    res = (*GPLR3_Address | (1 << 12)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure.
                        System.Threading.Thread.Sleep(20);                          // Sleep for 20ms
                        res = (*GPLR3_Address | (1 << 12)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                case GPIO93:
                    // Input4: GPIO93
                    res = (*GPLR2_Address | (1 << 29)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure.
                        System.Threading.Thread.Sleep(20);                          // Sleep for 20ms
                        res = (*GPLR0_Address | (1 << 24)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                case GPIO94:
                    // Input5: GPIO94
                    res = (*GPLR2_Address | (1 << 30)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure.
                        System.Threading.Thread.Sleep(20);                          // Sleep for 20ms
                        res = (*GPLR0_Address | (1 << 24)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                case GPIO95:
                    // Input6: GPIO95
                    res = (*GPLR2_Address | (1 << 30)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure.
                        System.Threading.Thread.Sleep(20);                          // Sleep for 20ms
                        res = (*GPLR0_Address | (1 << 24)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                default:
                    break;
            }

            return (res);
        }
    }
}
使用系统;
使用系统文本;
使用系统线程;
名称空间采样器
{
不安全类IoRelayControl
{
常量字节GPIO24=24;
常量字节GPIO25=25;
常量字节GPIO108=108;
常量字节GPIO93=93;
常量字节GPIO94=94;
常量字节GPIO95=95;
常量字节GPIO103=103;
常量字节GPIO104=104;
常量字节GPIO105=105;
常量字节GPIO27=27;
const bool INVALID\u HANDLE\u ERROR=false;
常量字节GPIO_AF_0=0;
常量字节GPIO_AF_1=1;
常量字节GPIO_AF_2=2;
常量字节GPIO_AF_3=3;
常量布尔GPIO_输出=真;
常量布尔GPIO_输入=假;
常量字节无GPIO错误=0;
常量字节配置失败错误=100;
常量字节集\u失败\u错误=102;
常量字节失败\u错误=103;
常量字节GPIO_无效_句柄=104;
常量字节读取失败错误=105;
常量字节无效\u GPIO\u错误=106;
公共易失性UInt32*GPDR0_地址=(UInt32*)0x40E0000C;//GPIO引脚方向寄存器0
公共易失性UInt32*GPDR1_地址=(UInt32*)0x40E00010;//GPIO引脚方向寄存器1
公共易失性UInt32*GPDR2_地址=(UInt32*)0x40E00014;//GPIO引脚方向寄存器2
公共易失性UInt32*GPDR3_地址=(UInt32*)0x40E0010C;//GPIO引脚方向寄存器3
公共易失性UInt32*GPSR0_地址=(UInt32*)0x40E00018;//GPIO引脚输出设置寄存器0
公共易失性UInt32*GPSR1_地址=(UInt32*)0x40E0001C;//GPIO引脚输出设置寄存器1
公共易失性UInt32*GPSR2_地址=(UInt32*)0x40E00020;//GPIO引脚输出设置寄存器2
公共易失性UInt32*GPSR3_地址=(UInt32*)0x40E00118;//GPIO引脚输出设置寄存器3
公共易失性UInt32*GPCR0_地址=(UInt32*)0x40E00024;//GPIO引脚输出清除寄存器0
公共易失性UInt32*GPCR1_地址=(UInt32*)0x40E0001C;//GPIO引脚输出清除寄存器1
公共易失性UInt32*GPCR2_地址=(UInt32*)0x40E00020;//GPIO引脚输出清除寄存器2
公共易失性UInt32*GPCR3_地址=(UInt32*)0x40E00118;//GPIO引脚输出清除寄存器3
公共易失性UInt32*GAFR0L_地址=(UInt32*)0x40E00054;//GPIO GAFR0_L Alt Func Reg 0
公共易失性UInt32*GAFR0U地址=(UInt32*)0x40E00058;//GPIO GAFR0\U Alt Func Reg 0
公共易失性UInt32*GAFR1L_地址=(UInt32*)0x40E0005C;//GPIO GAFR1_L Alt Func Reg 1
公共易失性UInt32*GAFR1U地址=(UInt32*)0x40E00060;//GPIO GAFR1\u L Alt Func Reg 1
公共易失性UInt32*GAFR2L_地址=(UInt32*)0x40E00064;//GPIO GAFR2_L Alt Func Reg 2
公共易失性UInt32*GAFR2U地址=(UInt32*)0x40E00068;//GPIO GAFR2\u L Alt Func Reg 2
公共易失性UInt32*GAFR3L_地址=(UInt32*)0x40E0006C;//GPIO GAFR3_L Alt Func Reg 3
公共易失性UInt32*GAFR3U地址=(UInt32*)0x40E00070;//GPIO GAFR3\u L Alt Func Reg 3
公共易失性UInt32*GPLR0_地址=(UInt32*)0x40E00000;//GPIO引脚电平寄存器0
公共易失性UInt32*GPLR1_地址=(UInt32*)0x40E00004;//GPIO引脚电平寄存器1
公共易失性UInt32*GPLR2_地址=(UInt32*)0x40E00008;//GPIO引脚电平寄存器2
公共易失性UInt32*GPLR3_地址=(UInt32*)0x40E00100;//GPIO引脚电平寄存器3
public bool IoInput0=false;//来自gpio24的输入
public bool IoInput1=false;//来自gpio25的输入
public bool IoInput2=false;//来自gpio108的输入
public bool IoInput3=false;//来自gpio93的输入
public bool IoInput4=false;//来自gpio94的输入
public bool IoInput5=false;//来自gpio95的输入
public bool IoOutputA1=false;//输出到gpio103
public bool IoOutputA2=false;//输出到gpio104
public bool IoOutputA3=false;//输出到gpio105
public bool IoOutputA4=false;//输出到gpio27
public bool bRunIoRelayCtrlThread=true;
/// 
/// 
/// 
公共无效IoPumpRelayCtrlThreadBody()
{
做
{