Я пытаюсь прочитать до 6 входов и записать до 4 выходов, используя GPIO ... это относительно простое приложение (или я так думал), но я просто не могу пройти мимо Win CE, останавливая мое приложение с помощьючто выглядит как ошибка нарушения доступа к памяти всякий раз, когда я пытаюсь обратиться к выводу GPIO - даже просто настраивая направление вывода (вход или выход), не говоря уже о чтении или записи, используя GLPR0 / 1/2/3, GPCR0 / 1/2/ 3, GPSR) / 1/2/3 и т. Д.
Я, должно быть, что-то здесь упустил, но не вижу, что - приложение является частью УПРАВЛЕНИЯ РЕЛЕ НАСОСА I / O с:
- 6 х входов
- 4 х выходов
- Код драйвера низкого уровня, поток постоянно зацикливает чтение значений 6 входов, записывает значения в регистры состояния / память-сопоставленные адреса для приложения с графическим интерфейсом для чтения (защелкиваются).
- Каждые ~ 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
Вот код (ниже, в классе IoRelayControl) для конфигурации / чтения / записи GPIO.Windows CE 6.0 на eSOM270 (PAX270) убивает меня при первом обращении (конфигурация GPIO направления выводов ввода / вывода в функции GPIOConfig ()).
Любой совет, с благодарностью полученный ..
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);
}
}
}