控制LED灯的流驱动开发文档
2011-07-26 22:33
369 查看
n 数据结构:
Ø 首先要了解T13端口的一些配置:主要用到了3个管脚,配置如下:
GPB5 | 红色指示灯控制 | 初始化置1,置0时红色指示灯亮 |
GPB6 | 绿色指示灯控制 | 初始化置1,置0时绿色指示灯亮 |
GPB7 | 蓝色指示灯控制 | 初始化置1,置0时蓝色指示灯亮 |
Ø 利用已有的一些结构,这些结构是将硬件设备管脚的物理地址传递给这些结构,然后通过改变这些结构中的一些参数来达到控制硬件设备。如:
#define IOP_BASE 0xB1600000 // 0x56000000 虚拟地址和物理地址typedefstruct { 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; unsignedint rPAD8; unsigned int rMISCCR; //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 ;;; SHL unsigned int rGSTATUS3; //B8 unsigned int rGSTATUS4; //BC unsigned int rFLTOUT; //C0 unsigned int rDSC0; unsigned int rDSC1; unsigned int rMSLCON; unsigned int rGPJCON; //D0 unsigned int rGPJDAT; unsigned int rGPJUP; unsigned int rPAD9; }IOPreg;Ø 导出的函数:大部分只留接口,只实现其中的三个主要函数。
LIBRARY LED_driver EXPORTS LED_Close //实现LED_Deinit LED_Init //实现LED_IOControl //实现LED_Open LED_PowerDown LED_PowerUp LED_Read LED_Seek LED_WriteØ 通过位运算来实现管脚的配置。
n 测试:
Ø 我写了一个测试程序,但是要想完成测试,必须先配置一下:
1、将LED_driver.dll和注册表文件拷贝到掌机上2、用DM驱动调试助手加载驱动并激活。3、然后直接打开测试程序,点击相应的按钮,可以看到LED的灯颜色的变化。Ø 也可以将两个xpi文件通过DNW工具烧到掌机上,这样也可以直接运行测试程序。
测试代码:
// LEDDriverTestDlg.cpp : implementation file//
#include "stdafx.h"
#include "LEDDriverTest.h"
#include "LEDDriverTestDlg.h"
extern HANDLE hSerial;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CLEDDriverTestDlg dialog
CLEDDriverTestDlg::CLEDDriverTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLEDDriverTestDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CLEDDriverTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CLEDDriverTestDlg, CDialog)
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
ON_WM_SIZE()
#endif
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON_OPEN_RED, &CLEDDriverTestDlg::OnBnClickedButtonOpenRed)
ON_BN_CLICKED(IDC_BUTTON_CLOSE_RED, &CLEDDriverTestDlg::OnBnClickedButtonCloseRed)
ON_BN_CLICKED(IDC_BUTTON_OPEN_GREEN, &CLEDDriverTestDlg::OnBnClickedButtonOpenGreen)
ON_BN_CLICKED(IDC_BUTTON_CLOSE_GREEN, &CLEDDriverTestDlg::OnBnClickedButtonCloseGreen)
ON_BN_CLICKED(IDC_BUTTON_OPEN_BLUE, &CLEDDriverTestDlg::OnBnClickedButtonOpenBlue)
ON_BN_CLICKED(IDC_BUTTONC_LOSE_BLUE, &CLEDDriverTestDlg::OnBnClickedButtoncLoseBlue)
ON_BN_CLICKED(IDC_BUTTON_ALL_ON, &CLEDDriverTestDlg::OnBnClickedButtonAllOn)
ON_BN_CLICKED(IDC_BUTTON_ALL_OFF, &CLEDDriverTestDlg::OnBnClickedButtonAllOff)
END_MESSAGE_MAP()
// CLEDDriverTestDlg message handlers
BOOL CLEDDriverTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
hSerial = INVALID_HANDLE_VALUE;全局变量在.h文件中声明
// TODO: Add extra initialization here
hSerial = CreateFile(L"LED1:", GENERIC_READ | GENERIC_WRITE, 0x00, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSerial == INVALID_HANDLE_VALUE)
{
return false;
}
return TRUE; // return TRUE unless you set the focus to a control
}
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
void CLEDDriverTestDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
{
DRA::RelayoutDialog(
AfxGetInstanceHandle(),
this->m_hWnd,
DRA::GetDisplayMode() != DRA::Portrait ?
MAKEINTRESOURCE(IDD_LEDDRIVERTEST_DIALOG_WIDE) :
MAKEINTRESOURCE(IDD_LEDDRIVERTEST_DIALOG));
}
#endif
void CLEDDriverTestDlg::OnBnClickedButtonOpenRed()
{
// TODO: Add your control notification handler code here
if (hSerial == INVALID_HANDLE_VALUE)
{
return ;
}
else
{
DeviceIoControl(hSerial, 0x01, NULL, NULL, NULL, NULL, NULL, NULL);
}
}
void CLEDDriverTestDlg::OnBnClickedButtonCloseRed()
{
// TODO: Add your control notification handler code here
if (hSerial == INVALID_HANDLE_VALUE)
{
return ;
}
else
{
DeviceIoControl(hSerial, 0x05, NULL, NULL, NULL, NULL, NULL, NULL);
}
}
void CLEDDriverTestDlg::OnBnClickedButtonOpenGreen()
{
// TODO: Add your control notification handler code here
if (hSerial == INVALID_HANDLE_VALUE)
{
return ;
}
else
{
DeviceIoControl(hSerial, 0x02, NULL, NULL, NULL, NULL, NULL, NULL);
}
}
void CLEDDriverTestDlg::OnBnClickedButtonCloseGreen()
{
// TODO: Add your control notification handler code here
if (hSerial == INVALID_HANDLE_VALUE)
{
return ;
}
else
{
DeviceIoControl(hSerial, 0x06, NULL, NULL, NULL, NULL, NULL, NULL);
}
}
void CLEDDriverTestDlg::OnBnClickedButtonOpenBlue()
{
// TODO: Add your control notification handler code here
if (hSerial == INVALID_HANDLE_VALUE)
{
return ;
}
else
{
DeviceIoControl(hSerial, 0x03, NULL, NULL, NULL, NULL, NULL, NULL);
}
}
void CLEDDriverTestDlg::OnBnClickedButtoncLoseBlue()
{
// TODO: Add your control notification handler code here
if (hSerial == INVALID_HANDLE_VALUE)
{
return ;
}
else
{
DeviceIoControl(hSerial, 0x07, NULL, NULL, NULL, NULL, NULL, NULL);
}
}
void CLEDDriverTestDlg::OnBnClickedButtonAllOn()
{
// TODO: Add your control notification handler code here
if (hSerial == INVALID_HANDLE_VALUE)
{
return ;
}
else
{
DeviceIoControl(hSerial, 0x04, NULL, NULL, NULL, NULL, NULL, NULL);
}
}
void CLEDDriverTestDlg::OnBnClickedButtonAllOff()
{
// TODO: Add your control notification handler code here
if (hSerial == INVALID_HANDLE_VALUE)
{
return ;
}
else
{
DeviceIoControl(hSerial, 0x08, NULL, NULL, NULL, NULL, NULL, NULL);
}
}
reg:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\LEDdriver]"Index"=dword:1
"Prefix"="LED"
"Dll"="LED_driver.dll"
驱动代码:
#include <windows.h>//#include <ceddk.h>
#include <nkintr.h>
#include <pm.h>
#include "pmplatform.h"
#include "Pkfuncs.h"
#include "s2440.h"
#define IO_CTL_LED_1_ON 0x01
#define IO_CTL_LED_2_ON 0x02
#define IO_CTL_LED_3_ON 0x03
//#define IO_CTL_LED_4_ON 0x04
#define IO_CTL_LED_ALL_ON 0x04
#define IO_CTL_LED_1_OFF 0x05
#define IO_CTL_LED_2_OFF 0x06
#define IO_CTL_LED_3_OFF 0x07
//#define IO_CTL_LED_4_OFF 0x09
#define IO_CTL_LED_ALL_OFF 0x08
volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
volatile INTreg *s2440INT = (INTreg *)INT_BASE;
#ifdef DEBUG
DBGPARAM dpCurSettings = {
TEXT("LED"), {
TEXT("Error"), TEXT("Warn"), TEXT("Init"), TEXT("Open"),
TEXT("Read"), TEXT("Write"), TEXT("IOCTL"), TEXT("IST"),
TEXT("Power"), TEXT("9"), TEXT("10"), TEXT("11"),
TEXT("12"), TEXT("13"), TEXT("14"), TEXT("Trace"),
},
0x0003 // ZONE_WRN|ZONE_ERR
};
#endif // DEBUG
BOOL mInitialized;
void Virtual_Alloc(); // Virtual allocation
void Virtual_Alloc()
{
// GPIO Virtual alloc
s2440IOP = (volatile IOPreg *) VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
if(s2440IOP == NULL) {
RETAILMSG(1,(TEXT("For s2440IOP: VirtualAlloc faiLED!\r\n")));
}
else {
if(!VirtualCopy((PVOID)s2440IOP,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE | PAGE_NOCACHE )) {
RETAILMSG(1,(TEXT("For s2440IOP: VirtualCopy faiLED!\r\n")));
}
}
}
BOOL WINAPI
DllEntry(HANDLE hinstDLL,
DWORD dwReason,
LPVOID /* lpvReserved */)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
DEBUGREGISTER((HINSTANCE)hinstDLL);
return TRUE;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
#ifdef UNDER_CE
case DLL_PROCESS_EXITING:
break;
case DLL_SYSTEM_STARTED:
break;
#endif
}
return TRUE;
}
BOOL LED_Deinit(DWORD hDeviceContext)
{
BOOL bRet = TRUE;
RETAILMSG(1,(TEXT("USERLED: LED_Deinit\r\n")));
return TRUE;
}
BOOL LEDGpioInit()
{
RETAILMSG(1,(TEXT("LED_Gpio_Setting----\r\n")));
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 10)) | (1<< 10); // GPB5 == OUTPUT.
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 12)) | (1<< 12); // GPB6 == OUTPUT.
s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 14)) | (1<< 14); // GPB7 == OUTPUT.
//s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 16)) | (1<< 16); // GPB8 == OUTPUT.return TRUE;
}
DWORD LED_Init(DWORD dwContext)
{
RETAILMSG(1,(TEXT("LED_Init----\r\n")));
// 1. Virtual Alloc
Virtual_Alloc();
LEDGpioInit();
mInitialized = TRUE;
return TRUE;
}
主要的都在这里:
//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------
BOOL LED_IOControl(DWORD hOpenContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
//RETAILMSG(1, (TEXT("****************************************\r\n")));
LEDGpioInit();
switch(dwCode)
{
case IO_CTL_LED_1_ON:
//MessageBox(NULL, _T("red"), NULL, MB_OK);
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<5);//red-on
break;
case IO_CTL_LED_2_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<6);//green-on
break;
case IO_CTL_LED_3_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<7);//blue-on
break;
//case IO_CTL_LED_4_ON:
// s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<8);
// break;
case IO_CTL_LED_ALL_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x7<<5);//red,grean,blue-all-on
break;
case IO_CTL_LED_1_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<5);//red-off
break;
case IO_CTL_LED_2_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<6);//green-off
break;
case IO_CTL_LED_3_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<7);//blue-off
break;
//case IO_CTL_LED_4_OFF:
// s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<8);
// break;
case IO_CTL_LED_ALL_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x7<<5);//red,grean,blue-all-off
break;
default:
break;
}
RETAILMSG(1,(TEXT("LED:Ioctl code = 0x%x\r\n"), dwCode));
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD LED_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
{
RETAILMSG(1,(TEXT("USERLED: LED_Open\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL LED_Close(DWORD hOpenContext)
{
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x7<<5);
RETAILMSG(1,(TEXT("USERLED: LED_Close\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void LED_PowerDown(DWORD hDeviceContext)
{
RETAILMSG(1,(TEXT("USERLED: LED_PowerDown\r\n")));
//RETAILMSG(1,(TEXT("CAMERA: LED_PowerDown, m_Dx = D%u, init %d \r\n"), m_Dx, mInitialized));
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void LED_PowerUp(DWORD hDeviceContext)
{
RETAILMSG(1,(TEXT("USERLED: LED_PowerUp\r\n")));
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD LED_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
RETAILMSG(1,(TEXT("USERLED: LED_Read\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD LED_Seek(DWORD hOpenContext, long Amount, DWORD Type)
{
RETAILMSG(1,(TEXT("USERLED: LED_Seek\r\n")));
return 0;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD LED_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes)
{
RETAILMSG(1,(TEXT("USERLED: LED_Write\r\n")));
return 0;
}
直接找一个在上面改就行很简单。
相关文章推荐
- 嵌入式Linux驱动开发(二)——字符设备驱动之控制LED
- Linux驱动开发--通过按键控制led灯
- 用查询方式去控制led灯(ARM 驱动开发)
- openWRT自学---对官方的开发指导文档的解读和理解 记录2:如何控制内核模块的编译
- Linux 字符设备驱动开发基础(一)—— 编写简单 LED 设备驱动
- Linux驱动开发之S3C2440按键点亮LED
- Linux驱动开发-字符设备控制技术笔记 3
- “手把手教你学linux驱动开发”OK6410系列之03---LED字符设备驱动
- platform_driver与file_operations两种方法开发led驱动
- 第七章 驱动开发_第一个字符型设备(LED)驱动
- 通用GPIO驱动和apk(含jni),支持所有GPIO,支持LED控制,支持友善6410/210开发板,支持安卓2.3/4.0,内核2.6/3.0
- 慢慢学Linux驱动开发,第九篇,tiny6410_LED驱动
- 黑莓开发新手入门教学帖,如何制作一个能控制LED颜色的程序(六)
- 第20章 驱动开发之LED应用程序
- Linux设备驱动开发详解-Note(14)--- Linux 设备驱动中的并发控制(1)
- Android深度探索:HAL与驱动开发学习笔记--并发控制之原子操作
- real6410开发板Uboot中添加控制LED驱动
- 手把手教你学linux驱动开发”OK6410系列之03---LED字符设备驱动
- x6818开发板安卓驱动开发(1)-LED-APP
- Linux驱动程序开发(4) - 字符设备驱动(3)-LED设备驱动和应用程序