页次: 1
现在写代码大多是utf-8码了吧,
不过几大门户网站缺返祖了
这是 http://www.163.com/
<meta http-equiv="Content-Type" content="text/html; charset=gbk">
这是 http://www.qq.com/
<meta charset="gb2312">
感谢大佬推荐!
请教一个问题, 作者是用
2. 内核framebuffer的地址要指定与uboot相同的地址, 因为uboot已经将图片数据加载到内存进行显示了, 内核使用相同的地址便能显示相同的图片
这个方案吗?
CONFIG_FB_PRE_INIT_FB
https://www.denx.de/wiki/DULG/LinuxSplashScreen
我也没试过,抛砖引玉把
感谢大佬提供的方案,正在搜索中,有进展前来报告。
欸,一点都偷不了懒么?~~~
应该可以偷懒了:
Small Modbus slave, RTU (serial) for Arduino (arduino modbus从机):
https://github.com/stephane/modbusino
Simple Makefile to compile and upload Arduino sketches:
https://github.com/stephane/arduinoMakefile
果然可以,以前modbus代码都是自己撸的,发现这个libmodbus更简洁:
简书上面找到一个demo
RTU:
#include <modbus.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
modbus_t *ctx=NULL; // context
int addr=0; // address
int rc=0; // received
int nb = 3; // the number of bit
uint16_t *tab_rq_registers=NULL;
uint16_t *tab_rp_registers=NULL;
/* RTU */
ctx = modbus_new_rtu("/dev/ttySAC3",9600,'N',8,1);
modbus_set_debug(ctx, TRUE);
modbus_set_slave(ctx, 0x01); // 设置从机地址
// connect
if (-1 == modbus_connect(ctx))
{
fprintf(stderr, "Conncetion failed: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
// 读取数据
uint16_t tab_reg[2]; // 存放要读的数据
int regs=modbus_read_registers(ctx,0,2,tab_reg);
/* Close the connection */
modbus_close(ctx);
modbus_free(ctx);
return 0;
}
TCP:
/*
* The client of modbus tcp.
* test 2 register
*
* 2017-10-26
*/
#include <modbus.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
modbus_t *ctx=NULL; // context
int addr=0; // address
int rc=0; // received
int nb = 3; // the number of bit
uint16_t *tab_rq_registers=NULL;
uint16_t *tab_rp_registers=NULL;
/* TCP */
ctx = modbus_new_tcp("192.168.2.29", 1502);
modbus_set_debug(ctx, TRUE);
// connect
if (-1 == modbus_connect(ctx))
{
fprintf(stderr, "Conncetion failed: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
/* Allocate and initialize the memory spaces. */
tab_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
memset(tab_rq_registers, 0, nb * sizeof(uint16_t));
tab_rp_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
memset(tab_rp_registers, 0, nb * sizeof(uint16_t));
// write
tab_rq_registers[0] = 25;
tab_rq_registers[1] = 2;
tab_rq_registers[2] = 88;
rc = modbus_write_registers(ctx, addr, nb, tab_rq_registers);
if (rc != nb)
{
printf("ERROR modbus_write_bits single (%d)\n", rc);
printf("address = %d\n", addr);
}
// read
rc = modbus_read_registers(ctx, addr, nb, tab_rp_registers);
if (rc != nb)
{
printf("ERROR modbus_read_bits single (%d)\n", rc);
printf("address = %d\n", addr);
}
for (int i = 0; i < nb; ++i)
{
printf("%d%c", tab_rp_registers[i], (i==nb-1)?'\n':' ');
}
free(tab_rq_registers);
free(tab_rp_registers);
/* Close the connection */
modbus_close(ctx);
modbus_free(ctx);
return 0;
}
这个项目地址里我看到了完整的配置文件,与镜像文件;
没有找到对应的linux 内核源代码,请问镜像文件对应版本的linux 内核源代码在哪里可以下载到呢,谢谢了哦!
https://github.com/torvalds/linux
源码在这里
这个作者用的是 The mainline linux kernel (4.21) has support for
刚刚试了一下:
git clone https://github.com/torvalds/linux --branch v4.21
结果提示分支错误, 后来想起来根本没有v4.21嘛, 最后一个版本是v4.20
所以你可以试一试:
git clone https://github.com/torvalds/linux --branch v5.0
root@me:/opt# git clone https://github.com/torvalds/linux --branch v5.0
Cloning into 'linux'...
remote: Enumerating objects: 7335096, done.
Receiving objects: 5% (417762/7335096), 186.67 MiB | 7.55 MiB/s
给力给力, 核心就是这个了:
https://github.com/malasy/SDCardWriter/blob/master/SDCardWriter/SDCardWriterDlg.cpp#L396
https://github.com/malasy/SDCardWriter/blob/master/SDCardWriter/SDCardWriterDlg.cpp#L594
// SDCardWriterDlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "SDCardWriter.h"
#include "SDCardWriterDlg.h"
#include "afxdialogex.h"
#include <Dbt.h>
#include "winioctl.h"
#include "ioapiset.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define SECTION_NAME "SDCardWriter"
#define BLOCK_SIZE_KEY "block_size"
#define BLOCK_COUNT_KEY "block_count"
#define WINDOW_X "left"
#define WINDOW_Y "top"
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CSDCardWriterDlg 对话框
CSDCardWriterDlg::CSDCardWriterDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_SDCARDWRITER_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_SD);
}
void CSDCardWriterDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_DEVICE_COMB, m_cbDevice);
}
BEGIN_MESSAGE_MAP(CSDCardWriterDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_DEVICECHANGE()
ON_BN_CLICKED(IDC_INPUT_BTN, &CSDCardWriterDlg::OnBnClickedInputBtn)
ON_CBN_SELCHANGE(IDC_DEVICE_COMB, &CSDCardWriterDlg::OnCbnSelchangeDeviceComb)
ON_BN_CLICKED(IDC_BTN_BURN, &CSDCardWriterDlg::OnBnClickedBtnBurn)
ON_STN_CLICKED(IDC_STATIC_LINK, &CSDCardWriterDlg::OnStnClickedStaticLink)
END_MESSAGE_MAP()
// CSDCardWriterDlg 消息处理程序
BOOL CSDCardWriterDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
initCombobox();
//读取配置文件
CString blockSize = AfxGetApp()->GetProfileString(_T(SECTION_NAME), _T(BLOCK_SIZE_KEY));
CString blockCount = AfxGetApp()->GetProfileString(_T(SECTION_NAME), _T(BLOCK_COUNT_KEY));
GetDlgItem(IDC_EDIT_BLOCK_SIZE)->SetWindowTextW(blockSize);
GetDlgItem(IDC_EDIT_OFFSET)->SetWindowTextW(blockCount);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CSDCardWriterDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CSDCardWriterDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CSDCardWriterDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
//监听USB设备的插入和移除
BOOL CSDCardWriterDlg::OnDeviceChange(UINT nEventType, DWORD dwData)
{
if (nEventType == DBT_DEVICEREMOVECOMPLETE) {
initCombobox();
}
if (nEventType == DBT_DEVICEARRIVAL) {
initCombobox();
}
return false;
}
//打开资源管理器选择文件
void CSDCardWriterDlg::OnBnClickedInputBtn()
{
filePath = _T("");
CFileDialog dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Bin文件(*.bin)|*.bin|All Files(*.*)|*.*||"), NULL);
if (dlgFile.DoModal()) {
filePath = dlgFile.GetPathName();
if (!filePath.IsEmpty()) {
GetDlgItem(IDC_INPUT_ET)->SetWindowTextW(filePath);
}
}
}
//获取所有的USB设备盘符(一个字母)
int CSDCardWriterDlg::get_usb_disk(char usb_paths[])
{
DWORD all_disk = GetLogicalDrives();
int usb_cnt = 0;
int i = 0;
char disk_path[5] = { 0 };
char device_path[10] = { 0 };
char device_name[100] = {0};
while (all_disk && usb_cnt < 5) {
if ((all_disk & 0x1) == 1) {
sprintf_s(device_path, "%c:\\", 'A' + i);
if (GetDriveType(CString(device_path)) == DRIVE_REMOVABLE) {
usb_paths[usb_cnt++] = 'A' + i;
}
}
all_disk = all_disk >> 1;
i++;
}
return usb_cnt;
}
//重新填充下拉列表数据
void CSDCardWriterDlg::initCombobox()
{
//清空下拉列表
m_cbDevice.ResetContent();
int count = get_usb_disk(devicePaths);
if (count == 0) {
m_cbDevice.AddString(_T(""));
m_cbDevice.SetCurSel(0);
deviceLabel = '#';
return;
}
CString strInfo;
for (int i = 0; i < count; i++) {
strInfo.Format(_T("%c:"), devicePaths[i]);
m_cbDevice.InsertString(i, strInfo);
}
//默认选中第一个
m_cbDevice.SetCurSel(0);
deviceLabel = devicePaths[0];
}
HANDLE CSDCardWriterDlg::getHandleOnFile(LPCWSTR filelocation, DWORD access)
{
HANDLE hFile;
hFile = CreateFileW(filelocation, access, (access == GENERIC_READ) ? FILE_SHARE_READ : 0, NULL, (access == GENERIC_READ) ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred when attempting to get a handle on the file. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
LocalFree(errormessage);
}
return hFile;
}
HANDLE CSDCardWriterDlg::getHandleOnVolume(char volume, DWORD access)
{
HANDLE hVolume;
char volumename[] = "\\\\.\\A:";
volumename[4] = volume;
hVolume = CreateFile(CString(volumename), access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hVolume == INVALID_HANDLE_VALUE)
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred when attempting to get handle on volume. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
}
return hVolume;
}
bool CSDCardWriterDlg::getLockOnVolume(HANDLE handle)
{
DWORD bytesreturned;
BOOL bResult;
bResult = DeviceIoControl(handle, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &bytesreturned, NULL);
if (!bResult)
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred when attempting to lock the volume. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
}
return (bResult);
}
bool CSDCardWriterDlg::removeLockOnVolume(HANDLE handle)
{
DWORD junk;
BOOL bResult;
bResult = DeviceIoControl(handle, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &junk, NULL);
if (!bResult)
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred when attempting to unlock the volume. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
}
return (bResult);
}
bool CSDCardWriterDlg::unmountVolume(HANDLE handle)
{
DWORD junk;
BOOL bResult;
bResult = DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &junk, NULL);
if (!bResult)
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred when attempting to dismount the volume. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
}
return (bResult);
}
bool CSDCardWriterDlg::isVolumeUnmounted(HANDLE handle)
{
DWORD junk;
BOOL bResult;
bResult = DeviceIoControl(handle, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &junk, NULL);
return (!bResult);
}
DWORD CSDCardWriterDlg::getDeviceID(HANDLE hVolume)
{
VOLUME_DISK_EXTENTS sd;
DWORD bytesreturned;
if (!DeviceIoControl(hVolume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &sd, sizeof(sd), &bytesreturned, NULL))
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred when attempting to get information on volume. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
}
return sd.Extents[0].DiskNumber;
}
HANDLE CSDCardWriterDlg::getHandleOnDevice(int device, DWORD access)
{
HANDLE hDevice;
CString devicename;
devicename.Format(_T("\\\\.\\PhysicalDrive%d"), device);
hDevice = CreateFile(devicename, access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred when attempting to get a handle on the device. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
LocalFree(errormessage);
}
return hDevice;
}
char* CSDCardWriterDlg::readSectorDataFromHandle(HANDLE handle, unsigned long long startsector, unsigned long long numsectors, unsigned long long sectorsize)
{
unsigned long bytesread;
char* data = new char[sectorsize * numsectors];
LARGE_INTEGER li;
li.QuadPart = startsector * sectorsize;
SetFilePointer(handle, li.LowPart, &li.HighPart, FILE_BEGIN);
if (!ReadFile(handle, data, sectorsize * numsectors, &bytesread, NULL))
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred when attempting to read data from handle. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
delete[] data;
data = NULL;
}
if (data && bytesread < (sectorsize * numsectors))
{
memset(data + bytesread, 0, (sectorsize * numsectors) - bytesread);
}
return data;
}
bool CSDCardWriterDlg::writeSectorDataToHandle(HANDLE handle, char* data, unsigned long long startsector, unsigned long long numsectors, unsigned long long sectorsize)
{
unsigned long byteswritten;
BOOL bResult;
LARGE_INTEGER li;
li.QuadPart = startsector * sectorsize;
SetFilePointer(handle, li.LowPart, &li.HighPart, FILE_BEGIN);
bResult = WriteFile(handle, data, sectorsize * numsectors, &byteswritten, NULL);
if (!bResult)
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred when attempting to write data to handle. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
}
return (bResult);
}
unsigned long long CSDCardWriterDlg::getFileSizeInSectors(HANDLE handle, unsigned long long sectorsize)
{
unsigned long long retVal = 0;
if (sectorsize) // avoid divide by 0
{
LARGE_INTEGER filesize;
if (GetFileSizeEx(handle, &filesize) == 0)
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred while getting the file size. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
retVal = 0;
}
else
{
retVal = ((unsigned long long)filesize.QuadPart / sectorsize) + (((unsigned long long)filesize.QuadPart % sectorsize) ? 1 : 0);
}
}
return(retVal);
}
unsigned long long CSDCardWriterDlg::getNumberOfSectors(HANDLE handle, unsigned long long* sectorsize)
{
DWORD junk;
DISK_GEOMETRY_EX diskgeometry;
BOOL bResult;
bResult = DeviceIoControl(handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &diskgeometry, sizeof(diskgeometry), &junk, NULL);
if (!bResult)
{
wchar_t* errormessage = NULL;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, GetLastError(), 0, (LPWSTR)&errormessage, 0, NULL);
CString errInfo;
errInfo.Format(_T("An error occurred when attempting to get the device's geometry. Error:%d %s"), GetLastError(), errormessage);
MessageBox(errInfo);
return 0;
}
if (sectorsize != NULL)
{
*sectorsize = (unsigned long long)diskgeometry.Geometry.BytesPerSector;
}
return (unsigned long long)diskgeometry.DiskSize.QuadPart / (unsigned long long)diskgeometry.Geometry.BytesPerSector;
}
//下拉选中列表中的另外一项
void CSDCardWriterDlg::OnCbnSelchangeDeviceComb()
{
int sel = m_cbDevice.GetCurSel();
deviceLabel = devicePaths[sel];
}
//点击烧录按钮
void CSDCardWriterDlg::OnBnClickedBtnBurn()
{
//获取必须数据:烧录的文件,烧录的设备,偏移,块大小
if (filePath.IsEmpty() || deviceLabel == '#') {
MessageBox(_T("请选择设备和烧录的文件"));
return;
}
CString blockSizeStr;
CString blockCountStr;
GetDlgItem(IDC_EDIT_BLOCK_SIZE)->GetWindowTextW(blockSizeStr);
GetDlgItem(IDC_EDIT_OFFSET)->GetWindowTextW(blockCountStr);
if (blockSizeStr.IsEmpty() || blockCountStr.IsEmpty()) {
MessageBox(_T("请输入块大小和偏移量"));
return;
}
//保存数据
AfxGetApp()->WriteProfileStringW(_T(SECTION_NAME), _T(BLOCK_SIZE_KEY), blockSizeStr);
AfxGetApp()->WriteProfileStringW(_T(SECTION_NAME), _T(BLOCK_COUNT_KEY), blockCountStr);
//字符串-->数字
unsigned long long blockSize = _ttoi(blockSizeStr);
unsigned int blockCount = _ttoi(blockCountStr);
int status = STATUS_WRITING;
//获取卷句柄
HANDLE hVolume = getHandleOnVolume(deviceLabel, GENERIC_WRITE);
if (hVolume == INVALID_HANDLE_VALUE) {
status = STATUS_IDLE;
return;
}
//获取设备ID
DWORD deviceID = getDeviceID(hVolume);
if (!getLockOnVolume(hVolume))
{
CloseHandle(hVolume);
hVolume = INVALID_HANDLE_VALUE;
status = STATUS_IDLE;
return;
}
//卸载卷(不懂为什么要这样,猜测应该是需要卸载设备,解除系统对该设备的占用,然后我们才能直接操作该设备)
if (!unmountVolume(hVolume))
{
removeLockOnVolume(hVolume);
CloseHandle(hVolume);
hVolume = INVALID_HANDLE_VALUE;
status = STATUS_IDLE;
return;
}
//获取文件句柄
HANDLE hFile = getHandleOnFile(filePath, GENERIC_READ);
if (hFile == INVALID_HANDLE_VALUE)
{
removeLockOnVolume(hVolume);
CloseHandle(hVolume);
hVolume = INVALID_HANDLE_VALUE;
status = STATUS_IDLE;
return;
}
//得到设备的物理地址。hVolume是应用层使用的地址,hRawDisk是驱动层使用的地址(不太确定)
HANDLE hRawDisk = getHandleOnDevice(deviceID, GENERIC_WRITE);
if (hRawDisk == INVALID_HANDLE_VALUE)
{
removeLockOnVolume(hVolume);
CloseHandle(hFile);
CloseHandle(hVolume);
hVolume = INVALID_HANDLE_VALUE;
hFile = INVALID_HANDLE_VALUE;
status = STATUS_IDLE;
return;
}
unsigned long long numsectors,sectorsize, availablesectors, lasti,i;
//获取可用空间(以扇区为单位)和扇区大小,一般扇区大小为512Byte
availablesectors = getNumberOfSectors(hRawDisk, §orsize);
if (!availablesectors) {
removeLockOnVolume(hVolume);
CloseHandle(hRawDisk);
CloseHandle(hFile);
CloseHandle(hVolume);
hRawDisk = INVALID_HANDLE_VALUE;
hFile = INVALID_HANDLE_VALUE;
hVolume = INVALID_HANDLE_VALUE;
status = STATUS_IDLE;
return;
}
//获取文件大小(以扇区为单位)
numsectors = getFileSizeInSectors(hFile, sectorsize);
if (!numsectors)
{
removeLockOnVolume(hVolume);
CloseHandle(hRawDisk);
CloseHandle(hFile);
CloseHandle(hVolume);
hRawDisk = INVALID_HANDLE_VALUE;
hFile = INVALID_HANDLE_VALUE;
hVolume = INVALID_HANDLE_VALUE;
status = STATUS_IDLE;
return;
}
if (numsectors > availablesectors) {
MessageBox(_T("More space required than is available"));
}
lasti = 0ul;
char* sectorData;
//计算需要偏移的扇区数
unsigned long long offsetSector = (blockSize * blockCount)/sectorsize;
for (i = 0ul; i < numsectors && status == STATUS_WRITING; i += 1024ul) {
sectorData = readSectorDataFromHandle(hFile, i, (numsectors - i >= 1024ul) ? 1024ul : (numsectors - i), sectorsize);
if (sectorData == NULL)
{
removeLockOnVolume(hVolume);
CloseHandle(hRawDisk);
CloseHandle(hFile);
CloseHandle(hVolume);
status = STATUS_IDLE;
hRawDisk = INVALID_HANDLE_VALUE;
hFile = INVALID_HANDLE_VALUE;
hVolume = INVALID_HANDLE_VALUE;
return;
}
if (!writeSectorDataToHandle(hRawDisk, sectorData, offsetSector + i, (numsectors - i >= 1024ul) ? 1024ul : (numsectors - i), sectorsize))
{
delete[] sectorData;
removeLockOnVolume(hVolume);
CloseHandle(hRawDisk);
CloseHandle(hFile);
CloseHandle(hVolume);
status = STATUS_IDLE;
sectorData = NULL;
hRawDisk = INVALID_HANDLE_VALUE;
hFile = INVALID_HANDLE_VALUE;
hVolume = INVALID_HANDLE_VALUE;
return;
}
delete[] sectorData;
sectorData = NULL;
}
removeLockOnVolume(hVolume);
CloseHandle(hRawDisk);
CloseHandle(hFile);
CloseHandle(hVolume);
hRawDisk = INVALID_HANDLE_VALUE;
hFile = INVALID_HANDLE_VALUE;
hVolume = INVALID_HANDLE_VALUE;
MessageBox(_T("烧录成功!"));
}
void CSDCardWriterDlg::OnStnClickedStaticLink()
{
ShellExecute(0, NULL, _T("https://github.com/malasy/SDCardWriter"), NULL, NULL, SW_NORMAL);
}
费了九牛二虎之力终于搞定.
[ 44.119061] usb 1-1: new high-speed USB device number 2 using ehci-platform
[ 44.317009] rndis_host 1-1:1.0 eth1: register 'rndis_host' at usb-1c1a000.usb-1, RNDIS device, ac:92:48:f9:ea:08
[ 44.380705] option 1-1:1.2: GSM modem (1-port) converter detected
[ 44.411618] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB0
[ 44.445448] option 1-1:1.3: GSM modem (1-port) converter detected
[ 44.474551] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB1
[ 44.491664] option 1-1:1.4: GSM modem (1-port) converter detected
[ 44.524489] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB2
先按这个改: https://ask.openluat.com/article/37
再按这个改: https://ask.openluat.com/article/79
终于找到官方的文档了,
原来要打开 /dev/ttyUSB* 需要修改内核配置和源码:
https://ask.openluat.com/article/79
上面链接的云备份: air720_linux_rndis_ttyUSB.pdf
插入 ubuntu 18.04 也是这样:
[699934.369537] usb 3-2.1: USB disconnect, device number 19
[699934.369614] rndis_host 3-2.1:1.0 enxaca9def8f175: unregister 'rndis_host' usb-0000:03:00.0-2.1, RNDIS device
[699936.475885] usb 3-2.1: new high-speed USB device number 20 using xhci_hcd
[699936.689810] usb 3-2.1: New USB device found, idVendor=1286, idProduct=4e3d, bcdDevice= 1.00
[699936.689812] usb 3-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[699936.689813] usb 3-2.1: Product: Mobile Composite Device Bus
[699936.689814] usb 3-2.1: Manufacturer: Marvell
[699936.689815] usb 3-2.1: SerialNumber: 200806006809080000
[699936.702012] rndis_host 3-2.1:1.0 eth0: register 'rndis_host' at usb-0000:03:00.0-2.1, RNDIS device, ac:a9:de:f8:f1:75
[699936.749105] rndis_host 3-2.1:1.0 enxaca9def8f175: renamed from eth0
在群里问了下,有大佬说要x over ssh,这是个啥?
晕,我的gitee也超大,拒绝commit了。
$ git push gitee hua_uart0_800x480
Counting objects: 311, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (231/231), done.
Writing objects: 100% (311/311), 15.79 MiB | 2.17 MiB/s, done.
Total 311 (delta 27), reused 0 (delta 0)
remote: Resolving deltas: 100% (27/27), completed with 12 local objects.
remote: Checking connectivity: 311, done.
remote: Powered by GITEE.COM [GNK-3.8]
remote: This repository(including wiki) size 3.07 GB, exceeds 1024.00 MB.
remote: Push rejected for repository size exceeds limit.
remote: HelpLink: https://gitee.com/help/articles/4232
remote: Repository GC: https://gitee.com/qabcqabc/linux/settings#git-gc
remote: Enterprise Edition: https://gitee.com/enterprises#commerces
remote: Utilities: https://github.com/newren/git-filter-repo
remote: https://rtyley.github.io/bfg-repo-cleaner
remote: https://git-scm.com/docs/git-filter-branch
To gitee.qabcqabc/linux.git
! [remote rejected]
发现立创的数据乱得一批,
一会叫NXP(恩智浦): https://list.szlcsc.com/brand/89.html
一会叫 Nexperia(安世): https://list.szlcsc.com/brand/1101.html
到底是不是同一个马甲?
哥还以为后面那个是国产品牌呢
pcf8575 16bit 带中断
pcf8574 8bit 不带中断
PCF8575TS: https://item.szlcsc.com/12867.html
1+: ¥13.09
10+: ¥9.68
30+: ¥9.06
100+: ¥7.587
500+: ¥7.335
1000+: ¥7.218
PCF8574TS: https://item.szlcsc.com/58826.html
1+: ¥6.88
10+: ¥5.09
30+: ¥4.77
100+: ¥3.996
500+: ¥3.861
1000+: ¥3.798
gpio驱动: https://github.com/torvalds/linux/blob/master/drivers/gpio/gpio-pcf857x.c
dts配置: https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/gpio/gpio-pcf857x.txt
keyboard驱动: https://github.com/torvalds/linux/blob/master/drivers/input/misc/pcf8574_keypad.c
按照楼主的步骤,从tf启动内核, 进入控制下lsmod ,没有发现module ,然后我自己进入目录下安装,insmod ov5647_mipi.ko ,
显示:unknown symbol in module, or unknown parameter
https://whycan.cn/t_2794.html#p23005
ARCH=arm CROSS_COMPILE=arm-linux- INSTALL_MOD_PATH=/opt/f1c100s/buildroot-2019.02.2/output/target/ make modules_install
把 ko 文件用上面的命令安装到你的根文件系统(根据具体情况调整参数)
命令行执行: modprobe ov5647_mipi
https://www.kernel.org/doc/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
https://superuser.com/questions/1091697/setting-pwm-backlight-brightness-on-boot
https://developer.toradex.com/knowledge-base/backlight-(linux)echo 7 > /sys/class/backlight/backlight/brightness
这种驱动方式玩 LCD 背光, 有没有哪位试过?
这个好用, 我以前在别的平台就是这样调液晶背光的。
i2c 的 pwm 扩展芯片 PCA9685
芯片: https://item.szlcsc.com/93397.html
含增值税:
1+: ¥17.18 / 个
10+: ¥14.84 / 个
30+: ¥14.41 / 个
100+: ¥13.98 / 个
500+:¥13.79 / 个
1000+: ¥13.55 / 个
模块: https://list.szlcsc.com/catalog/11152.html
linux 驱动: https://github.com/torvalds/linux/blob/master/drivers/pwm/pwm-pca9685.c
立创链接: https://item.szlcsc.com/48028.html
1+:¥8.05
10+:¥5.96
30+:¥5.58
100+:¥4.68 ¥5.2
500+:¥4.518 ¥5.02
1000+:¥4.446
linux 驱动: https://github.com/torvalds/linux/blob/master/drivers/pinctrl/pinctrl-mcp23s08.c
是有点贵,先用着吧,等有订单再用STM8S003单片机模拟MCP23017吧。
编译u-boot又出问题了,是不是这个编译工具太老了?
ubuntu@VM-0-16-ubuntu:~/f1c100s/u-boot$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -j4
*** Your GCC is older than 6.0 and is not supported
make: *** [checkgcc6] Error 1
make: INTERNAL: Exiting with 5 jobserver tokens available; should be 4!
对,要用 gcc 7.x
页次: 1