最近使用node的串口库发现很慢,自己用c++写了个驱动使用node去调用它并测试通过,速度也很快,最初版本记录下:
https://pan.baidu.com/s/1MRtebBZZpsHFVzWP7GGhng
test.js
var test = require('./build/Release/test');
test.ArduinoDevice('test', function(data) {
console.log(data);
});
gyp配置:
{
"targets": [
{
"target_name": "test",
"sources": [ "test.cc"]
}
]
}
test.cc
#include <node.h>
#include <v8.h>
#include <stdio.h>
#include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART
#include <termios.h> //Used for UART
#include <string.h>
using namespace v8;
// 传入了两个参数,args[0] 字符串,args[1] 回调函数
void hello(const FunctionCallbackInfo<Value>& args) {
// 使用 HandleScope 来管理生命周期
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
///////////////////////////////////////////////////////////////////
int uart0 = -1;
printf("----------starting-------------------\n");
uart0 = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0 == -1)
{
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
struct termios options;
tcgetattr(uart0, &options);
options.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0, TCIFLUSH);
tcsetattr(uart0, TCSANOW, &options);
//----- TX BYTES -----
unsigned char tx_buffer[20];
unsigned char *p_tx_buffer;
unsigned char *p_tx_buffer2;
unsigned char str[] = "closel\0";
// p_tx_buffer = &tx_buffer[0];
// *p_tx_buffer++ = 'o';
// *p_tx_buffer++ = 'p';
// *p_tx_buffer++ = 'e';
// *p_tx_buffer++ = 'n';
// *p_tx_buffer++ = 'l';
printf("--1--\n");
p_tx_buffer2 = &tx_buffer[0];
printf("--then str is %s and strlen is %d--\n",(const char*)str,strlen((const char*)str));
//printf("%s",strlen(str));
for(int i=0;i<strlen(reinterpret_cast<const char*>(str));i++){
printf("--for inner 1 is %d--\n",i);
*p_tx_buffer2++ = str[i];
printf("--for inner 2 is %d--\n",i);
//printf("%s",str[i]);
}
printf("--2--\n");
if (uart0 != -1)
{
int count = write(uart0, &tx_buffer[0], (p_tx_buffer2 - &tx_buffer[0])); //Filestream, bytes to write, number of bytes to write
if (count < 0)
{
printf("UART TX error\n");
}
close(uart0);
}
///////////////////////////////////////////////////////////////////
// 判断参数格式和格式
if (args.Length() < 2 || !args[0]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate, "Wrong arguments")));
return;
}
// callback, 使用Cast方法来转换
Local<Function> callback = Local<Function>::Cast(args[1]);
Local<Value> argv[1] = {
// 拼接String
String::Concat(Local<String>::Cast(args[0]), String::NewFromUtf8(isolate, " fuck world"))
};
// 调用回调, 参数: 当前上下文,参数个数,参数列表
callback->Call(isolate->GetCurrentContext()->Global(), 1, argv);
}
// 相当于在 exports 对象中添加 { hello: hello }
void init(Handle<Object> exports) {
NODE_SET_METHOD(exports, "ArduinoDevice", hello);
}
// 将 export 对象暴露出去
// 原型 `NODE_MODULE(module_name, Initialize)`
NODE_MODULE(test, init);
unsigned char *foo();
std::string str;
str.append(reinterpret_cast<const char*>(foo()));
reinterpret_cast用法:
reinterpret_cast
type-id 必须是一个指针、引用、算术类型、函数指针或者成员指针。
reinterpret_cast运算符是用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位。例如:int n= new int ; double d=reinterpret_cast
IBM的C++指南里倒是明确告诉了我们reinterpret_cast可以,或者说应该在什么地方用来作为转换运算符:
- 从指针类型到一个足够大的整数类型
- 从整数类型或者枚举类型到指针类型
- 从一个指向函数的指针到另一个不同类型的指向函数的指针
- 从一个指向对象的指针到另一个不同类型的指向对象的指针
- 从一个指向类函数成员的指针到另一个指向不同类型的函数成员的指针
- 从一个指向类数据成员的指针到另一个指向不同类型的数据成员的指针
事实上reinterpret_cast的使用并不局限在上边所说的几项的,任何类型的指针之间都可以互相转换,都不会得到编译错误。上述列出的几项,可能 是Linux下reinterpret_cast使用的限制,也可能是IBM推荐我们使用reinterpret_cast的方式。
原文链接: https://www.cnblogs.com/SATinnovation/p/8639675.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/271014
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!