OpenHarmony liteOS 串口通信
一、代码程序说明由于 liteOS 资源较低,为了有更好的性能,并跨越框架层直接对系统层进行操作,故上层应用的代码应全部用 c++语言编写,整合为系统组件,在系统编译时编译成 hap 包即可。
二、代码开发
[*] ||
| -- ||| https://forums.openharmony.cn/file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image003.gif |
代码结构
cert :放 hap 签名证书文件 p7b include : 头文件
resources : 应用资源文件src : cpp 代码文件BUILD.gn : 编译构建config.json : 应用配置文件
[*] config.json 示例
{
"app": {
"bundleName": "com.example.mytest",
"vendor": "ohos",
"version": {
"code": 1,
"name": "1.0"
},
"apiVersion": {
"compatible": 3,
"target": 4
}
},
"deviceConfig": {
"default": {
"keepAlive": false
}
},
"module": {
"package": "com.example.mytest",
"name": ".MainAbility",
"deviceType": [
"phone",
"tv",
"tablet",
"pc",
"car",
"smartWatch",
"sportsWatch",
"smartVision"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "mytest",
"moduleType": "entry"
},
"abilities": [
{
"name": "MainAbility",
"icon": "assets/mytest/resources/drawable/icon.png",
"label": "串口 Demo",
"launchType": "standard",
"type": "page",
"visible": true,
"srcLanguage":"c++"
}
![文本框: ]
}
}](file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image005.gif)
3. BUILD.gn 构建配置示例
import("//build/lite/config/hap_pack.gni") shared_library("mytest") { #生成 so 库文件
sources = [ "src/main_ability.cpp", "src/main_ability_slice.cpp",
]
include_dirs = [#头文件路径"include",
"\${aafwk_lite_path}/interfaces/kits/ability_lite", "\${appexecfwk_lite_path}/interfaces/kits/bundle_lite", "\${aafwk_lite_path}/interfaces/kits/want_lite", "//base/startup/syspara_lite/interfaces/kits",
]
deps = [#依赖关系"\${aafwk_lite_path}/frameworks/ability_lite:aafwk_abilitykit_lite", "\${appexecfwk_lite_path}/frameworks/bundle_lite:bundle", "//foundation/distributedschedule/samgr_lite/samgr:samgr", "//foundation/graphic/surface",
"//foundation/graphic/ui:lite_ui", "//foundation/graphic/utils:lite_graphic_utils", "//utils/native/lite/kv_store:kv_store",
]
clang 编译项
ldflags = [ "-shared" ] ldflags += [ "-lstdc++" ] ldflags += [ "-lpthread" ]
ldflags += [ "-L\$ohos_root_path/sysroot/usr/lib" ]
ldflags += [ "-Wl,-rpath-link=\$ohos_root_path/sysroot/usr/lib" ] ldflags += [
"-lui",
"-lsurface",
"-lability",
]
defines = [ "ENABLE_WINDOW=1", "ABILITY_WINDOW_SUPPORT",
]
}
编译为 hap 包
hap_pack("mytest_hap") { deps = [ ":mytest" ] mode = "hap"
json_path = "config.json"
ability_so_path = "\$root_out_dir/libmytest.so" force = "true"
cert_profile = "cert/mytest.p7b" resources_path = "resources" hap_name = "mytest"
privatekey = "HOS Application Provision Release"
}
[*] src/main\_ability.cpp 代码示例
namespace OHOS { REGISTER_AA(MainAbility)
void MainAbility::OnStart(const Want& want)
{
SetMainRoute("MainAbilitySlice"); Ability::OnStart(want);}
void MainAbility::OnInactive()
{
Ability::OnInactive();
}
void MainAbility::OnActive(const Want& want)
{
Ability::OnActive(want);
}
void MainAbility::OnBackground()
{
Ability::OnBackground();
}
void MainAbility::OnStop()
{
Ability::OnStop();
}
} // namespace OHOS](file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image006.gif) |
[*] src/main\_ability\_slice.cpp 示例
include
](file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image007.gif) |
https://forums.openharmony.cn/file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image008.gif#include
include
include "main_ability_slice.h"
include "ability_loader.h"
include "event_listener.h"
//#include "btn_onclick_listener.h"
include
include
include
include
include
include
include
include
include
namespace OHOS {
REGISTER_AS(MainAbilitySlice)
//全局配置 uart 设备参数
define BUFF_LEN 256
define DEVICE "/dev/ttyS0" //串口号,如:ttyS1,ttyS3,ttyS4 ... #define BAUDRATE "9600" //波特率
define COMMAND "43 61 6C 63 54 0D 0A" //向串口发的指令,该指令为 ASCII 指令,如要发送 hex byte 指令,则需要进行转换处理
class BtnOnclickListener : public UIView::OnClickListener {
protected:
/*
//设置操作的 uart 设备
void setDevice(const char *device_name){
deviceName = device_name;
}*/
//返回 2 进制 bundrate
speed_t getBaudRate(int baudrate){
switch(baudrate) {
case 0: return B0;
case 50: return B50;
case 75: return B75;
case 110: return B110;
case 134: return B134;
case 150: return B150;
case 200: return B200;
case 300: return B300;
case 600: return B600;
case 1200: return B1200;
https://forums.openharmony.cn/file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image010.gifcase 1800: return B1800;
case 2400: return B2400;
case 4800: return B4800;
case 9600: return B9600;
case 19200: return B19200;
case 38400: return B38400;
case 57600: return B57600;
case 115200: return B115200;
case 230400: return B230400;
case 460800: return B460800;
case 500000: return B500000;
case 576000: return B576000;
case 921600: return B921600;
case 1000000: return B1000000;
case 1152000: return B1152000;
case 1500000: return B1500000;
case 2000000: return B2000000;
case 2500000: return B2500000;
case 3000000: return B3000000;
case 3500000: return B3500000;
case 4000000: return B4000000;
default: return B9600;
}
}
//初始化串口
int uartInit(const char *baudRate_d){
speed_t baudRate_t = getBaudRate(atoi(baudRate_d));
int fd;
fd = open(DEVICE, O_RDWR | O_NOCTTY);
if(fd == -1) {
printf("\n Error! in Opening device : %s " , DEVICE);
return -1;
}
struct termios SerialPortSettings;
if (tcgetattr(fd, &SerialPortSettings) != 0)
{
printf("\n tcgetattr ERROR !");
return -1;
}else{
printf("\n tcgetattr Successfully !");
}
if(cfsetispeed(&SerialPortSettings, baudRate_t) != 0){
https://forums.openharmony.cn/file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image011.gifprintf("\n cfsetispeed ERROR !");
return -1;
}else{
printf("\n cfsetispeed Successfully !");
}
if (cfsetospeed(&SerialPortSettings, baudRate_t) != 0)
{
printf("\n cfsetospeed ERROR !");
return -1;
}else{
printf("\n cfsetospeed Successfully !");
}
SerialPortSettings.c_cflag &= ~PARENB;
SerialPortSettings.c_cflag &= ~CSTOPB;
//SerialPortSettings.c_cflag &= ~CSIZE;
SerialPortSettings.c_cflag |= CS8;
SerialPortSettings.c_cflag &= ~CRTSCTS;
SerialPortSettings.c_cflag |= CREAD | CLOCAL;
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);
SerialPortSettings.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | ECHONL);
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
SerialPortSettings.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received
bytes
SerialPortSettings.c_oflag &= ~OPOST;
SerialPortSettings.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
SerialPortSettings.c_cc = 1;
SerialPortSettings.c_cc = 3;
if(tcsetattr(fd, TCSANOW, &SerialPortSettings) != 0) {
printf("\n ERROR ! in Setting attributes");
return -1;
}else{
printf("\nBaudRate = %d \nStopBits = 1 \n Parity = none",baudRate_d);
}
if (tcflush(fd, TCIFLUSH) != 0)
{
printf("\n tcflush ERROR!");
return -1;
}else{
printf("\n tcflush Successfully!");
close(fd);
}
return 0;
}
https://forums.openharmony.cn/file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image012.gif//hex 转为 byte 指令
int hexstringtobyte(char *in, unsigned char *out) {
int len = (int)strlen(in);
char *str = (char *)malloc(len);
memset(str, 0, len);
memcpy(str, in, len);
for (int i = 0; i < len; i+=2) {
//小写转大写
if(str >= 'a' && str = 'a' && str = 'A' && str Add(headView_);
headView_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), 70);
headView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
headView_->SetStyle(STYLE_BACKGROUND_OPA, 255);
headView_->SetTouchable(true);
https://forums.openharmony.cn/file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image020.gifauto onClick = (UIView& view, const Event& event) -> bool {
Terminate();
return true;
};
headView_->SetOnClickListener(new EventListener(onClick, nullptr));
headImageView_ = new UIImageView();
headView_->Add(headImageView_);
headImageView_->SetPosition(39, 16, 30, 30);
headImageView_->SetSrc(DE_IMAGE_BACK);
headLablelFont_ = new UILabel();
headLablelFont_->SetPosition(100, 15, 180, 60);
headLablelFont_->SetText("back");
headLablelFont_->SetFont(FOND_PATH, FOND_SIZE);
headLablelFont_->SetStyle(STYLE_TEXT_COLOR, Color::ColorTo32(Color::White()));
headView_->Add(headLablelFont_);
}
void MainAbilitySlice::setInput(){
inputView_ = new UIViewGroup();
inputView_->SetPosition(36, 108, 700, 500);
inputView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
inputView_->SetStyle(STYLE_BACKGROUND_OPA, 0);
//inputView_->SetStyle(STYLE_BORDER_RADIUS, 16);
rootview_->Add(inputView_);
lableDevTag_ = new UILabel();
lableDevTag_->SetPosition(36, 10,100,50);
lableDevTag_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full);
lableDevTag_->SetFont(FOND_PATH, FOND_SIZE); lableDevTag_->SetText("设备");
inputView_->Add(lableDevTag_);
lableTail_ = new UILabel();
lableTail_->SetPosition(120, 2, 220, 70);
lableTail_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
lableTail_->SetStyle(STYLE_BACKGROUND_OPA, 255);
lableTail_->SetStyle(STYLE_BORDER_RADIUS, 16);
lableTail_->SetStyle(STYLE_PADDING_LEFT, 5);
lableTail_->SetAlign(TEXT_ALIGNMENT_LEFT,TEXT_ALIGNMENT_CENTER);
lableTail_->SetFont(FOND_PATH, FOND_SIZE);
lableTail_->SetText(DEVICE);
inputView_->Add(lableTail_);
lableBundTag_ = new UILabel();
lableBundTag_->SetPosition(36, 110,100,50);
https://forums.openharmony.cn/file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image021.giflableBundTag_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full);
lableBundTag_->SetFont(FOND_PATH, FOND_SIZE); lableBundTag_->SetText("波特");
inputView_->Add(lableBundTag_);
lableBundRate_ = new UILabel();
lableBundRate_->SetPosition(120, 100, 220, 70);
lableBundRate_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
lableBundRate_->SetStyle(STYLE_BACKGROUND_OPA, 255);
lableBundRate_->SetStyle(STYLE_BORDER_RADIUS, 16);
lableBundRate_->SetStyle(STYLE_PADDING_LEFT, 5);
lableBundRate_->SetAlign(TEXT_ALIGNMENT_LEFT,TEXT_ALIGNMENT_CENTER);
lableBundRate_->SetFont(FOND_PATH, FOND_SIZE);
lableBundRate_->SetText(BAUDRATE);
inputView_->Add(lableBundRate_);
lableCmdTag_ = new UILabel();
lableCmdTag_->SetPosition(36, 210,100,50);
lableCmdTag_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full);
lableCmdTag_->SetFont(FOND_PATH, FOND_SIZE); lableCmdTag_->SetText("指令");
inputView_->Add(lableCmdTag_);
lableCmd_ = new UILabel();
lableCmd_->SetPosition(120, 200, 400, 70);
lableCmd_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
lableCmd_->SetStyle(STYLE_BACKGROUND_OPA, 255);
lableCmd_->SetStyle(STYLE_BORDER_RADIUS, 16);
lableCmd_->SetStyle(STYLE_PADDING_LEFT, 5);
lableCmd_->SetAlign(TEXT_ALIGNMENT_LEFT,TEXT_ALIGNMENT_CENTER);
lableCmd_->SetFont(FOND_PATH, FOND_SIZE);
lableCmd_->SetText(COMMAND);
inputView_->Add(lableCmd_);
lableRecTag_ = new UILabel();
lableRecTag_->SetPosition(36, 310,100,50);
lableRecTag_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full);
lableRecTag_->SetFont(FOND_PATH, FOND_SIZE); lableRecTag_->SetText("接收");
inputView_->Add(lableRecTag_);
lableRecData_ = new UILabel();
lableRecData_->SetPosition(120, 300, 400, 70);
lableRecData_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
lableRecData_->SetStyle(STYLE_BACKGROUND_OPA, 255);
lableRecData_->SetStyle(STYLE_BORDER_RADIUS, 16);
lableRecData_->SetStyle(STYLE_PADDING_LEFT, 5);
lableRecData_->SetAlign(TEXT_ALIGNMENT_LEFT,TEXT_ALIGNMENT_CENTER);
lableRecData_->SetFont(FOND_PATH, FOND_SIZE);
inputView_->Add(lableRecData_);
https://forums.openharmony.cn/file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image022.gif//光标输入状态
/*
UILabel *lablelCursorText_ = new UILabel();
lablelCursorText_->SetPosition(24, 3, 2, 70);
lablelCursorText_->SetStyle(STYLE_BACKGROUND_COLOR, Color::ColorTo32(Color::GetColorFromRGB(0x0D, 0x9F, 0xF8)));
lablelCursorText_->SetStyle(STYLE_BACKGROUND_OPA, 255);
inputView_->Add(lablelCursorText_);
*/
BtnOnclickListener *clickListener = new BtnOnclickListener(lableRecData_);
enterView_ = new UIViewGroup();
enterView_->SetPosition(120, 400, 150, 70);
enterView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::ColorTo32(Color::GetColorFromRGB(0x0D, 0x9F, 0xF8)));
enterView_->SetStyle(STYLE_BACKGROUND_OPA, 255);
enterView_->SetStyle(STYLE_BORDER_RADIUS, 16);
enterView_->SetTouchable(true);
enterView_->SetOnClickListener(clickListener);
inputView_->Add(enterView_);
btnImageView_ = new UIImageView();
btnImageView_->SetPosition(10, 20);
btnImageView_->SetSrc(DE_IMAGE_ENTER);
enterView_->Add(btnImageView_);
btnImageView_->SetTouchable(true);
btnImageView_->SetOnClickListener(clickListener);
}
void MainAbilitySlice::OnStart(const Want& want)
{
AbilitySlice::OnStart(want);
rootview_ = RootView::GetWindowRootView();
rootview_->SetPosition(0, 0);
rootview_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
rootview_->SetStyle(STYLE_BACKGROUND_OPA, UN_OPACITY);
rootview_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full);//Color::Blue().full
SetHead();
setInput();
SetUIContent(rootview_);
rootview_->Invalidate();
}
void MainAbilitySlice::OnInactive()
{
AbilitySlice::OnInactive();
}

6. include/event_listener.h 示例
include#include
include "components/ui_view.h"
namespace OHOS {
using OnEventFunc = std::function;
class EventListener : public UIView::OnClickListener, public UIView::OnLongPressListener { public:EventListener() = delete;
~EventListener() override = default;
EventListener(OnEventFunc onClick, OnEventFunc onLongPress)
{
onClick = std::move(onClick); onLongPress = std::move(onLongPress);}
bool OnClick(UIView& view, const ClickEvent &event) override
{
if (!onClick_) { return false;}
UIView *currentView = &view;](file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image024.gif) |

[*] include/ui\_config.h 示例

其它头文件不做示例,可从 cpp 中推荐创建
三、集成说明
[*] 将上述应用代码放置于 applications/sample/camera 路径下
[*] 修改 build/lite/components/applications.json,在其中添加组件配置
若要修要 app 应用的 bundleName 与 package 名,请修改
applications/sample/camera/mytest/config.json (修改 bundleName 与 package 名需要替换 cert 下
p7b 签 名文件)
https://forums.openharmony.cn/file:///C:/Users/zhang/AppData/Local/Temp/msohtmlclip1/01/clip_image031.jpg
执行编译命 令 : hb build
若编译失败,试着执行重新编译
rm -rf out hb build -f
[*]编译成功后在 out 目录下查找 mytest.hap ,如果找到则说明集成成功,最后重烧开发板,重新启动即可看到“串口 DEMO”应用已被安装
四、串口配置
用 c++语言编辑器打开上述 src/main_ability_slice.cpp,将开头的常量替换为开发板实际参数即可
串口初始化后,自动在子线程中进行来数据监听,当收到数据后,会通过 UIView 的 Label 控件展示在应用界面上,如下图:
|
页:
[1]