提交 a3c4c541 编写于 作者: W wusongqing

Changed some file names and updated links

Signed-off-by: Nwusongqing <wusongqing@huawei.com>
上级 46ecceec
...@@ -374,7 +374,7 @@ For details about how to obtain the source code of OpenHarmony, see [Source Cod ...@@ -374,7 +374,7 @@ For details about how to obtain the source code of OpenHarmony, see [Source Cod
For details about how to join in the OpenHarmony community, see [OpenHarmony Community](https://gitee.com/openharmony/community/blob/master/README.md). For details about how to join in the OpenHarmony community, see [OpenHarmony Community](https://gitee.com/openharmony/community/blob/master/README.md).
For details about how to contribute, see [Contribution](https://gitee.com/openharmony/docs/blob/master/en/contribute/contribution.md). For details about how to contribute, see [How to Contribute](https://gitee.com/openharmony/docs/blob/master/en/contribute/how-to-contribute.md).
## License Agreement<a name="section1245517472115"></a> ## License Agreement<a name="section1245517472115"></a>
......
# Internationalization # Internationalization
- [Overview](international-overview.md) - [Internationalization Overview](international-overview.md)
- [Internationalization Development (intl)](intl-guidelines.md) - [Internationalization Development (intl)](intl-guidelines.md)
- [Internationalization Development (i18n)](i18n-guidelines.md) - [Internationalization Development (i18n)](i18n-guidelines.md)
# Overview # Internationalization Overview
If an application is targeted for users and markets in different regions with different languages and time zones, it is necessary for you to provide localized versions to ensure good experience for your users. If an application is targeted for users and markets in different regions with different languages and time zones, it is necessary for you to provide localized versions to ensure good experience for your users.
......
...@@ -3,13 +3,9 @@ ...@@ -3,13 +3,9 @@
- Audio - Audio
- [Audio Overview](audio-overview.md) - [Audio Overview](audio-overview.md)
- [Audio Playback Development](audio-playback.md)
- [Audio Playback Development](audio-playback.md)
- [Audio Rendering Development](audio-renderer.md)
- [Audio Recording Development](audio-recorder.md) - [Audio Recording Development](audio-recorder.md)
- [Audio Rendering Development](audio-renderer.md)
- [Audio Capture Development](audio-capturer) - [Audio Capture Development](audio-capturer)
- Video - Video
......
# Security # Security
- Access Control
- [Access Control Overview](accesstoken-overview.md)
- [Access Control Development](accesstoken-guidelines.md)
- User Authentication - User Authentication
- [User Authentication Overview](userauth-overview.md) - [User Authentication Overview](userauth-overview.md)
- [User Authentication Development](userauth-guidelines.md) - [User Authentication Development](userauth-guidelines.md)
- Key Management - Key Management
- [HUKS Overview](huks-overview.md) - [HUKS Overview](huks-overview.md)
- [HUKS Development](huks-guidelines.md) - [HUKS Development](huks-guidelines.md)
- hapsigntool - hapsigntool
- [hapsigntool Guide](hapsigntool-guidelines.md) - [hapsigntool Guide](hapsigntool-guidelines.md)
- Access Control
- [Access Control Overview](accesstoken-overview.md)
- [Access Control Development](accesstoken-guidelines.md)
\ No newline at end of file
# Contributing Documents # Contribution Guide
- [Contribution](contribution.md) - [How to Contribute](how-to-contribute.md)
- [Code of Conduct](code-of-conduct.md) - [Code of Conduct](code-of-conduct.md)
- [Code Contribution](code-contribution.md) - [Code Contribution](code-contribution.md)
- [Contribution Process](contribution-process.md) - [Contribution Process](contribution-process.md)
- [Auto-Test](../readme/test_subsystem.md) - [Auto-Test](../readme/test.md)
- [Documentation Contribution](documentation-contribution.md) - [Documentation Contribution](documentation-contribution.md)
- [Writing Instructions](writing-instructions.md) - [Writing Instructions](writing-instructions.md)
- [Communication in Community](communication-in-community.md) - [Communication in Community](communication-in-community.md)
......
# Contribution Guide<a name="EN-US_TOPIC_0000001053389134"></a>
- **[How to Contribute](how-to-contribute.md)**
- **[Code of Conduct](code-of-conduct.md)**
- **[Code Contribution](code-contribution.md)**
- **[Contribution Process](contribution-process.md)**
- **[FAQs](FAQ.md)**
- **[Documentation Contribution](documentation-contribution.md)**
- **[Writing Instructions](writing-instructions.md)**
- **[Communication in Community](communication-in-community.md)**
# Contribution<a name="EN-US_TOPIC_0000001055208082"></a> # How to Contribute<a name="EN-US_TOPIC_0000001055208082"></a>
## Contributing Code<a name="en-us_topic_0000001053868136_section10170447161315"></a> ## Contributing Code<a name="en-us_topic_0000001053868136_section10170447161315"></a>
......
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
- [Sensor](subsystems/subsys-sensor.md) - [Sensor](subsystems/subsys-sensor.md)
- [USB](subsystems/subsys-usbservice.md) - [USB](subsystems/subsys-usbservice.md)
- [Application Framework](subsystems/subsys-application-framework.md) - [Application Framework](subsystems/subsys-application-framework.md)
- [OTA Upgrade](subsystems/subsys-ota-guide.md) - [OTA Update](subsystems/subsys-ota-guide.md)
- [Telephony Service](subsystems/subsys-tel.md) - [Telephony](subsystems/subsys-tel.md)
- [Security](subsystems/subsys-security.md) - [Security](subsystems/subsys-security.md)
- [Startup](subsystems/subsys-boot.md) - [Startup](subsystems/subsys-boot.md)
- [DFX](subsystems/subsys-dfx.md) - [DFX](subsystems/subsys-dfx.md)
...@@ -55,4 +55,4 @@ ...@@ -55,4 +55,4 @@
- References - References
- [FAQs](faqs/Readme-EN.md) - [FAQs](faqs/Readme-EN.md)
- Contribution - Contribution
- [How to Contribute](../contribute/contribution.md) - [How to Contribute](../contribute/how-to-contribute.md)
\ No newline at end of file \ No newline at end of file
# FAQs # FAQs
- [Overview of FAQs](faqs-overview.md) - [Overview of FAQs](faqs-overview.md)
- [Environment Setup](faqs-environment-building.md) - [Environment Setup](faqs-environment-setup.md)
- [Compilation and Building Subsystem](faqs-building.md) - [Compilation and Building Subsystem](faqs-building.md)
- [Burning](faqs-burning.md) - [Burning](faqs-burning.md)
- [Kernel](faqs-kernel.md) - [Kernel](faqs-kernel.md)
- [Porting](faqs-transplant.md) - [Porting](faqs-porting.md)
- [Startup](faqs-init.md) - [Startup](faqs-startup.md)
- [System Applications](faqs-system-using.md) - [System Applications](faqs-system-applications.md)
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
- [Burning](quickstart-ide-lite-steps-hi3861-burn.md) - [Burning](quickstart-ide-lite-steps-hi3861-burn.md)
- [Networking](quickstart-ide-lite-steps-hi3861-netconfig.md) - [Networking](quickstart-ide-lite-steps-hi3861-netconfig.md)
- [Debugging and Verification](quickstart-ide-lite-steps-hi3861-debug.md) - [Debugging and Verification](quickstart-ide-lite-steps-hi3861-debug.md)
- [Running](quickstart-ide-lite-steps-hi3816-running.md) - [Running](quickstart-ide-lite-steps-hi3861-running.md)
- Hi3516 Development Board - Hi3516 Development Board
- [Writing a Hello World Program](quickstart-ide-lite-steps-hi3516-application-framework.md) - [Writing a Hello World Program](quickstart-ide-lite-steps-hi3516-application-framework.md)
- [Building](quickstart-ide-lite-steps-hi3516-building.md) - [Building](quickstart-ide-lite-steps-hi3516-building.md)
......
# Telephony Development<a name="EN-US_TOPIC_0000001167051994"></a>
## Initializing a Modem Vendor Library<a name="section211mcpsimp"></a>
### When to Use<a name="section213mcpsimp"></a>
Initializing a modem vendor library means to implement **const HRilOps \*RilInitOps\(const struct HRilReport \*reportOps\)** function in the vendor library. This function is mainly used to:
- Receive function pointers to event callbacks of RIL Adapter. When a service event needs to be reported, the target pointer will be called to report the event to RIL Adapter.
- Create a thread for reading modem nodes. In this thread, the data reported by the modem is read cyclically and parsed as a specific service event for reporting.
- Return the function pointer of the service request API to RIL Adapter.
### Available APIs<a name="section811343241215"></a>
The following table describes the API for initializing a modem vendor library.
**Table 1** API for initializing a modem vendor library
<a name="table223mcpsimp"></a>
<table><thead align="left"><tr id="row229mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p231mcpsimp"><a name="p231mcpsimp"></a><a name="p231mcpsimp"></a>API</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p233mcpsimp"><a name="p233mcpsimp"></a><a name="p233mcpsimp"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row235mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p237mcpsimp"><a name="p237mcpsimp"></a><a name="p237mcpsimp"></a>const HRilOps *RilInitOps(const struct HRilReport * reportOps)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p239mcpsimp"><a name="p239mcpsimp"></a><a name="p239mcpsimp"></a>Function: Provides an entry for running a modem vendor library.</p>
<p id="p56281836194610"><a name="p56281836194610"></a><a name="p56281836194610"></a>Input parameter:</p>
<p id="p240mcpsimp"><a name="p240mcpsimp"></a><a name="p240mcpsimp"></a><strong id="b164737479278"><a name="b164737479278"></a><a name="b164737479278"></a>reportOps</strong>: Specifies the pointer to the event callback function, which is passed by RIL Adapter.</p>
<p id="p241mcpsimp"><a name="p241mcpsimp"></a><a name="p241mcpsimp"></a>Return result: function pointer of the service request API.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section51031144122"></a>
1. Set the event callback function pointers passed by RIL Adapter through **RilInitOps**.
```
// Define the callback function pointers of the modem vendor library.
static struct HRilReport g_reportOps = {
OnCallReport, // Callback function for call services
OnDataReport, // Callback function for cellular data services
OnModemReport, // Callback function for modem services
OnNetworkReport, // Callback function for network search services
OnSimReport, // Callback function for SIM card services
OnSmsReport // Callback function for SMS services
};
```
1. Create the **g\_reader** main thread to enable message looping.
```
pthread_attr_t t;
pthread_attr_init(&t);
pthread_attr_setdetachstate(&t, PTHREAD_CREATE_DETACHED);
ret = pthread_create(&g_reader, &t, ReaderLoop, &t); // Create the g_reader thread.
```
1. In the **g\_eventListeners** thread, use **open\(\)** to open a modem node and then create the **g\_reader** thread to read and process messages reported by the modem.
```
g_fd = open(g_devicePath, O_RDWR); // Open the device node specified by g_devicePath.
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
ret = pthread_create(&g_eventListeners, &attr, EventListeners, NULL);
```
1. Return the function pointer of the service request API.
```
// Structure for the service request API of the call module
typedef struct {
// Obtain the call list.
void (*GetCallList)(ReqDataInfo *requestInfo, const void *data, size_t dataLen);
// Make a call.
void (*Dial)(ReqDataInfo *requestInfo, const void *data, size_t dataLen);
// Disconnect a call.
void (*Hangup)(ReqDataInfo *requestInfo, const void *data, size_t dataLen);
// Reject a call.
void (*Reject)(ReqDataInfo *requestInfo, const void *data, size_t dataLen);
// Answer a call.
void (*Answer)(ReqDataInfo *requestInfo, const void *data, size_t dataLen);
} HRilCallReq;
// Callback function pointers of the call module
static const HRilCallReq g_callReqOps = {
.GetCallList = ReqGetCallList, // Obtain the call list.
.Dial = ReqDial, // Make a call.
.Hangup = ReqHangup, // Disconnect a call.
.Reject = ReqReject, // Reject a call.
.Answer = ReqAnswer, // Answer a call.
};
// Service request structure
typedef struct {
const HRilCallReq *callOps; // Pointer to the structure of call service requests
const HRilSimReq *simOps; // Pointer to the structure of SIM card service requests
const HRilSmsReq *smsOps; // Pointer to the structure of SMS and MMS service requests
const HRilDataReq *dataOps; // Pointer to the structure of cellular data service requests
const HRilNetworkReq *networkOps; // Pointer to the structure of network search service requests
const HRilModemReq *modemOps; // Pointer to the structure of modem service requests
} HRilOps;
// Service request APIs
HRilOps g_hrilOps = {
.callOps = &g_callReqOps, // API for call service requests
.simOps = &g_simReqOps, // API for SIM card service requests
.smsOps = &g_smsReqOps, // API for SMS and MMS service requests
.networkOps = &g_networkReqOps, // API for cellular data service requests
.dataOps = &g_dataReqOps, // API for network search service requests
.modemOps = &g_modemReqOps, // API for modem service requests
};
```
### Debugging and Verification<a name="section5351151517132"></a>
1. Use the [hdc\_std](https://gitee.com/openharmony/docs/blob/master/en/device-dev/subsystems/subsys-toolchain-hdc-guide.md#preparations) tool to connect to a debugging device. Then, run the following command to send the generated **libril\_vendor.z.so** library file to the **/system/lib/** directory of the device. For details about how to integrate a library file, see [Integrating Modem Vendor Libraries](#section590mcpsimp).
```
hdc_std file send libril_vendor.z.so /system/lib/
```
2. Reboot the debugging device.
```
hdc_std shell sync
hdc_std shell reboot
```
3. Run the **hdc\_std shell hilog** command to view the debug log, and check whether the **RilInitOps\(\)** function is successfully executed. The following debug log is for reference:
```
01-01 05:13:23.071 136 2319 D 00000/RilAdapterInit: [RilAdapterDispatch-(hril_hdf.c:55)] sbuf IPC obtain test success!
01-01 05:13:23.071 136 2319 D 00000/RilAdapterInit: [LoadVendor-(hril_hdf.c:33)] RilInit rilInit start
01-01 05:13:23.071 136 2319 D 00000/RilAdapterInit: [LoadVendor -(hril_hdf.c:45)] RilInit rilInit completed
```
## Responding to Modem Service Requests<a name="section295mcpsimp"></a>
### When to Use<a name="section297mcpsimp"></a>
After receiving a specific telephony service request, RIL Adapter calls the target function pointer obtained in modem vendor library initialization to send a specific service request to the vendor library. Then, the vendor library processes the request based on the request ID.
### Available APIs<a name="section9503155219134"></a>
The following table describes the APIs for responding to modem service requests, with the dial module as an example.
**Table 2** APIs for responding to modem service requests
<a name="table303mcpsimp"></a>
<table><thead align="left"><tr id="row309mcpsimp"><th class="cellrowborder" valign="top" width="49.84%" id="mcps1.2.3.1.1"><p id="p311mcpsimp"><a name="p311mcpsimp"></a><a name="p311mcpsimp"></a>API</p>
</th>
<th class="cellrowborder" valign="top" width="50.160000000000004%" id="mcps1.2.3.1.2"><p id="p313mcpsimp"><a name="p313mcpsimp"></a><a name="p313mcpsimp"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row315mcpsimp"><td class="cellrowborder" valign="top" width="49.84%" headers="mcps1.2.3.1.1 "><p id="p317mcpsimp"><a name="p317mcpsimp"></a><a name="p317mcpsimp"></a>void ReqDial(ReqDataInfo *requestInfo, const void *data, size_t dataLen);</p>
</td>
<td class="cellrowborder" valign="top" width="50.160000000000004%" headers="mcps1.2.3.1.2 "><p id="p319mcpsimp"><a name="p319mcpsimp"></a><a name="p319mcpsimp"></a>Function: Processes number dial requests.</p>
<p id="p12610151394115"><a name="p12610151394115"></a><a name="p12610151394115"></a>Input parameters:</p>
<a name="ul105511416204116"></a><a name="ul105511416204116"></a><ul id="ul105511416204116"><li><strong id="b85517162414"><a name="b85517162414"></a><a name="b85517162414"></a>requestInfo</strong>: request type</li></ul>
<a name="ul1676502416411"></a><a name="ul1676502416411"></a><ul id="ul1676502416411"><li><strong id="b1576510240416"><a name="b1576510240416"></a><a name="b1576510240416"></a>data</strong>: called number</li></ul>
<a name="ul842034134114"></a><a name="ul842034134114"></a><ul id="ul842034134114"><li><strong id="b1542193411415"><a name="b1542193411415"></a><a name="b1542193411415"></a>dataLen</strong>: data length</li></ul>
<p id="p323mcpsimp"><a name="p323mcpsimp"></a><a name="p323mcpsimp"></a>Return value: none</p>
</td>
</tr>
<tr id="row324mcpsimp"><td class="cellrowborder" valign="top" width="49.84%" headers="mcps1.2.3.1.1 "><p id="p326mcpsimp"><a name="p326mcpsimp"></a><a name="p326mcpsimp"></a>void (*OnCallReport)(struct ReportInfo reportInfo, const void *data, size_t dataLen);</p>
</td>
<td class="cellrowborder" valign="top" width="50.160000000000004%" headers="mcps1.2.3.1.2 "><p id="p328mcpsimp"><a name="p328mcpsimp"></a><a name="p328mcpsimp"></a>Function: Reports the execution result of a service request to RIL Adapter.</p>
<p id="p489264432"><a name="p489264432"></a><a name="p489264432"></a>Input parameters:</p>
<a name="ul44156301444"></a><a name="ul44156301444"></a><ul id="ul44156301444"><li><strong id="b15415930154418"><a name="b15415930154418"></a><a name="b15415930154418"></a>reportInfo</strong>: request type</li></ul>
<a name="ul18380115494513"></a><a name="ul18380115494513"></a><ul id="ul18380115494513"><li><strong id="b83808549457"><a name="b83808549457"></a><a name="b83808549457"></a>data</strong>: called number</li></ul>
<a name="ul118421156184517"></a><a name="ul118421156184517"></a><ul id="ul118421156184517"><li><strong id="b48421056144519"><a name="b48421056144519"></a><a name="b48421056144519"></a>dataLen</strong>: data length</li></ul>
<p id="p332mcpsimp"><a name="p332mcpsimp"></a><a name="p332mcpsimp"></a>Return value: none</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section17190412101414"></a>
1. Implement processing of dial requests in the **ReqDial\(\)** API.
```
// Implement the API for processing dial requests.
void ReqDial(ReqDataInfo *requestInfo, const void *data, size_t dataLen)
{
HRilDial *pDial = NULL;
char cmd[MAX_BUFF_SIZE] = {0};
const char *clir = NULL;
int ret;
int err = HRIL_ERR_SUCCESS;
struct ReportInfo reportInfo = {};
ResponseInfo *pResponse = NULL;
if (data == NULL) {
TELEPHONY_LOGE("data is null!!!");
err = HRIL_ERR_INVALID_PARAMETER;
reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
OnCallReport(reportInfo, NULL, 0);
return;
}
pDial = (HRilDial *)data;
switch (pDial->clir) {
case CALL_CLIR_INVOCATION:
clir = "I";
break; /* invocation */
case CALL_CLIR_SUPPRESSION:
clir = "i";
break; /* suppression */
case CALL_CLIR_SUBSCRIPTION_DEFUALT:
default:
clir = "";
break; /* subscription default */
}
(void)sprintf_s(cmd, MAX_BUFF_SIZE, "ATD%s%s;", pDial->address, clir);
ret = SendCommandLock(cmd, NULL, 0, &pResponse); // Send the AT command.
......
}
```
2. After the modem executes the dial command, report the execution result to RIL Adapter via **OnCallReport\(\)**.
```
ret = SendCommandLock(cmd, NULL, 0, &pResponse);
if (ret != 0 || (pResponse != NULL && pResponse->success == 0)) {
TELEPHONY_LOGE("ATD send failed");
err = HRIL_ERR_GENERIC_FAILURE;
}
reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
OnCallReport(reportInfo, NULL, 0); // Invoke the callback function of the call service.
```
### Debugging and Verification<a name="section10207938171413"></a>
1. Use the [hdc\_std](en-us_topic_0000001080478129.md#section05992022154916) tool to connect to a debugging device. Then, run the following command to send the generated **libril\_vendor.z.so** library file to the **/system/lib/** directory of the device.
```
hdc_std file send libril_vendor.z.so /system/lib/
```
2. Reboot the debugging device.
```
hdc_std shell sync
hdc_std shell reboot
```
3. Run the **hdc\_std shell** command. Then, run the **./system/bin/ril\_adapter\_test** command, type **1**, and enter the phone number as prompted to test the call function.
```
hdc_std shell
# ./system/bin/ril_adapter_test
----> Test Enter --------->Call---------------------
1----> RilUnitTest::OnRequestCallDialTest
2----> RilUnitTest:: OnRequestCallHangupTest
3----> RilUnitTest:: OnRequestCallAnswerTest
4----> RilUnitTest::OnRequestCallGetCurrentCallsStatusTest
5----> RilUnitTest::OnRequestRefusedCallTest
1
```
4. Open another terminal window, and run the **hdc\_std shell hilog** command. Then, view the log to check whether **ReqDial\(\)** is successfully executed. The following debug log is for reference:
```
01-01 05:27:27.419 136 408 D 02b01/Rilvendor: [SendCommandLock-(at_support.c:210)] SendCommandLock enter, cmd: ATD17620373527
01-01 05:27:27.419 136 408 D 02b01/Rilvendor: [SendCommandLock-(at_support.c:231)] SendCommandLock() command ATD17620373527
01-01 05:27:27.419 136 408 D 02b01/Rilvendor: [WriteATCommand-(channel.c:115)] WriteATCommand enter, cmd:ATD17620373527
01-01 05:27:27.421 136 187 D 02b01/Rilvendor: [ReadResponse-(channel.c:94)] g_bufferCur :
01-01 05:27:27.421 136 187 D 02b01/Rilvendor: OK
01-01 05:27:27.422 136 187 D 02b01/Rilvendor: [ProcessResponse-(at_support.c:144)] processLine line = OK
01-01 05:27:27.422 136 187 D 02b01/Rilvendor: [ReadResponse-(channel.c:81)] ReadResponse enter
01-01 05:27:27.422 136 187 D 02b01/Rilvendor: [ProcessLastResponse-(channel.c:37)] last data more than one line , FindEndOfLine g_bufferCur:
01-01 05:27:27.422 136 187 E 02b01/Rilvendor: [ProcessLastResponse-(channel.c:39)] g_bufferCur endLine is null
01-01 05:27:27.422 136 187 E 02b01/Rilvendor:^ORIG:1,0
01-01 05:27:27.422 136 408 E 02b01/Rilvendor: [SendCommandLock-(at_support.c:234)] processLine line = ^ORIG:1,0
01-01 05:27:27.422 136 408 E 02b01/Rilvendor: [SendCommandLock-(vendor_report.c:234)] enter to [^ORIG:1,0]: (null)
01-01 05:27:27.422 136 408 E 02b01/Rilvendor: [SendCommandLock-(at_support.c:264)] err = 0, cmd:ADT17620373527
```
## Reporting Modem Events<a name="section390mcpsimp"></a>
### When to Use<a name="section401mcpsimp"></a>
A modem node thread reads the messages reported by the modem cyclically, parses the messages into specific events, and then reports the events to RIL Adapter.
### Available APIs<a name="section191193791518"></a>
The following table describes the API for reporting modem events.
**Table 3** API for reporting modem events
<a name="table407mcpsimp"></a>
<table><thead align="left"><tr id="row413mcpsimp"><th class="cellrowborder" valign="top" width="52%" id="mcps1.2.3.1.1"><p id="p415mcpsimp"><a name="p415mcpsimp"></a><a name="p415mcpsimp"></a>API</p>
</th>
<th class="cellrowborder" valign="top" width="48%" id="mcps1.2.3.1.2"><p id="p417mcpsimp"><a name="p417mcpsimp"></a><a name="p417mcpsimp"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row419mcpsimp"><td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.3.1.1 "><p id="p421mcpsimp"><a name="p421mcpsimp"></a><a name="p421mcpsimp"></a>void OnNotifyOps(const char *s, const char *smsPdu)</p>
</td>
<td class="cellrowborder" valign="top" width="48%" headers="mcps1.2.3.1.2 "><p id="p423mcpsimp"><a name="p423mcpsimp"></a><a name="p423mcpsimp"></a>Function: Distributes the events reported by the modem.</p>
<p id="p17924530141912"><a name="p17924530141912"></a><a name="p17924530141912"></a>Input parameters:</p>
<a name="ul678053915191"></a><a name="ul678053915191"></a><ul id="ul678053915191"><li><strong id="b14780173912196"><a name="b14780173912196"></a><a name="b14780173912196"></a>s</strong>: AT command prefix</li></ul>
<a name="ul206343434192"></a><a name="ul206343434192"></a><ul id="ul206343434192"><li><strong id="b65891958173518"><a name="b65891958173518"></a><a name="b65891958173518"></a>smsPdu</strong>: PDU of the SMS message</li></ul>
<p id="p426mcpsimp"><a name="p426mcpsimp"></a><a name="p426mcpsimp"></a>Return value: none</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section16394112401512"></a>
1. Call **OnNotifyOps\(\)** in the g\_reader thread of the modem device node to parse reported modem events. On determining the command type, call **OnXxxReport\(\)** to report the parsed module events to the hril layer.
```
// Parse the data reported by the modem as events proactively reported by the corresponding module.
void OnNotifyOps(const char *s, const char *smsPdu)
{
int ret = 0;
struct ReportInfo reportInfo = {0};
reportInfo.error = HRIL_ERR_SUCCESS;
reportInfo.type = HRIL_NOTIFICATION;
if (GetRadioState() == HRIL_RADIO_POWER_STATE_UNAVAILABLE) {
return;
}
TELEPHONY_LOGD("enter to [%{public}s]:%{public}s", s, smsPdu);
// Determine the type of the proactively reported events based on the AT command.
if (ReportStrWith(s, "+CRING:") || ReportStrWith(s, "RING") || ReportStrWith(s, "IRING") ||
ReportStrWith(s, "NO CARRIER") || ReportStrWith(s, "+CCWA") || ReportStrWith(s, "^CCALLSTATE") ||
ReportStrWith(s, "^CEND") || ReportStrWith(s, "^CCWA")) {
reportInfo.notifyId = HNOTI_CALL_STATE_UPDATED;
OnCallReport(reportInfo, NULL, 0);
} else if (ReportStrWith(s, "+CMT:")) {
reportInfo.notifyId = HNOTI_SMS_NEW_SMS;
OnSmsReport(reportInfo, (void *)smsPdu, strlen(smsPdu));
}
// Report the events of each module to the hril layer.
...
}
```
1. Distribute the reported events from the **hril** layer to the Telephony Service layer.
```
// Report the call status proactively.
int32_t HRilCall::CallStateUpdated(
int32_t slotId, int32_t notifyType, const HRilErrno e, const void *response, size_t responseLen)
{
struct HdfSBuf *dataSbuf = HdfSBufTypedObtain(SBUF_IPC);
if (serviceCallbackNotify_ == nullptr) {
TELEPHONY_LOGE("RilAdapter serviceCallbackNotify_ is null");
HdfSBufRecycle(dataSbuf);
return HDF_FAILURE;
}
// Distribute events.
int32_t ret = serviceCallbackNotify_->dispatcher->Dispatch(
serviceCallbackNotify_, HNOTI_CALL_STATE_UPDATED, dataSbuf, nullptr);
if (ret != HDF_SUCCESS) {
HdfSBufRecycle(dataSbuf);
return HDF_FAILURE;
}
HdfSBufRecycle(dataSbuf);
return HDF_SUCCESS;
}
```
### Debugging and Verification<a name="section16999174401516"></a>
1. Use the [hdc\_std](en-us_topic_0000001080478129.md#section05992022154916) tool to connect to a debugging device. Then, run the following command to send the generated **libril\_vendor.z.so** library file to the **/system/lib/** directory of the device.
```
hdc_std file send libril_vendor.z.so /system/lib/
```
2. Reboot the debugging device.
```
hdc_std shell sync
hdc_std shell reboot
```
3. Run the **hdc\_std shell** command. Then, run the **./system/bin/ril\_adapter\_test** command, type **1**, and enter the phone number as prompted to test the call function.
```
hdc_std shell
# ./system/bin/ril_adapter_test
----> Test Enter --------->Call---------------------
1----> RilUnitTest::OnRequestCallDialTest
2----> RilUnitTest:: OnRequestCallHangupTest
3----> RilUnitTest:: OnRequestCallAnswerTest
4----> RilUnitTest::OnRequestCallGetCurrentCallsStatusTest
5----> RilUnitTest::OnRequestRefusedCallTest
1
```
4. Open another terminal window, and run the **hdc\_std shell hilog** command. Then, view the log to check whether **OnNotifyOps\(\)** is successfully executed. The following debug log is for reference:
```
01-01 00:08:01.334 546 551 D 02b01/TelRilTest: [DialResponse-(tel_ril_call.cpp:280)] DialResponse --> radioResponseInfo->serial:2, radioResponseInfo->error:0
01-01 00:08:01.334 546 557 D 02b01/TelRilTest: [ProcessEvent-(tel_ril_test.cpp:1262)] TelRilTest::DemoHandler::ProcessEvent --> eventId:101
01-01 00:08:01.334 143 512 D 02b01/Rilvendor: [ReadResponse-(channel.c:93)] g_bufferCur :
01-01 00:08:01.334 143 512 D 02b01/Rilvendor: ^ORIG:1,0
01-01 00:08:01.334 143 512 D 02b01/Rilvendor: [ReadResponse-(channel.c:108)] AT< ^ORIG:1,0
01-01 00:08:01.334 143 512 D 02b01/Rilvendor: [ProcessResponse-(at_support.c:137)] processLine line = ^ORIG:1,0
01-01 00:08:01.334 143 512 D 02b01/Rilvendor: [OnNotifyOps-(vendor_report.c:126)] enter to [^ORIG:1,0]:(null)
01-01 00:08:01.335 143 512 W 02b01/Rilvendor: [OnNotifyOps-(vendor_report.c:167)] enter to is unrecognized command: ^ORIG:1,0
01-01 00:08:01.335 143 512 D 02b01/Rilvendor: [ProcessLastResponse-(channel.c:37)] last data more than one line , FindEndOfLine g_bufferCur:
01-01 00:08:01.335 143 512 E 02b01/Rilvendor: [ProcessLastResponse-(channel.c:39)] g_bufferCur endLine is null
01-01 00:08:01.336 143 512 D 02b01/Rilvendor: [ReadResponse-(channel.c:93)] g_bufferCur :
01-01 00:08:01.336 143 512 D 02b01/Rilvendor: ^CCALLSTATE: 1,0,1
01-01 00:08:01.336 143 512 D 02b01/Rilvendor: [ReadResponse-(channel.c:108)] AT< ^CCALLSTATE: 1,0,1
01-01 00:08:01.336 143 512 D 02b01/Rilvendor: [ProcessResponse-(at_support.c:137)] processLine line = ^CCALLSTATE: 1,0,1
01-01 00:08:01.336 143 512 D 02b01/Rilvendor: [OnNotifyOps-(vendor_report.c:126)] enter to [^CCALLSTATE: 1,0,1]:(null)
01-01 00:08:01.336 546 551 D 02b01/CoreService: [OnRemoteRequest-(tel_ril_manager.cpp:80)] RilManager OnRemoteRequest code:1001
01-01 00:08:01.336 546 551 D 02b01/CoreService: [NotifyObserver-(observer_handler.cpp:76)] handler->SendEvent:8
```
### Development Examples<a name="section33444350167"></a>
- **Outgoing Call**
The following figure shows the API calling for an outgoing call.
**Figure 1** Time sequence of API calling for an outgoing call<a name="fig494mcpsimp"></a>
![](figure/en-us_image_0000001171507146.png)
When an application initiates an outgoing call, RIL Adapter receives a call request, and the **hril** layer invokes the **ReqDial\(\)** function. In **ReqDial\(\)**, the data passed by the Telephony Service is encapsulated as an AT command and sent to the modem. After executing the dial command, the modem reports the execution result to RIL Adapter through **OnCallReport\(\)**.
```
// Callback function pointer of the call module
static const HRilCallReq g_callReqOps = {
.GetCallList = ReqGetCallList, // Obtain the call list.
.Dial = ReqDial, // Make a call.
.Hangup = ReqHangup, // Disconnect a call.
.Reject = ReqReject, // Reject a call.
.Answer = ReqAnswer, // Answer a call.
};
// Service request APIs
HRilOps g_hrilOps = {
.callOps = &g_callReqOps, // API for call service requests
.simOps = &g_simReqOps, // API for SIM card service requests
.smsOps = &g_smsReqOps, // API for SMS and MMS service requests
.networkOps = &g_networkReqOps, // API for cellular data service requests
.dataOps = &g_dataReqOps, // API for network search service requests
.modemOps = &g_modemReqOps, // API for modem service requests
};
// Implement the API for processing dial requests.
void ReqDial(ReqDataInfo *requestInfo, const void *data, size_t dataLen)
{
HRilDial *pDial = NULL;
char cmd[MAX_BUFF_SIZE] = {0};
const char *clir = NULL;
int ret;
int err = HRIL_ERR_SUCCESS;
struct ReportInfo reportInfo = {};
ResponseInfo *pResponse = NULL;
if (data == NULL) {
TELEPHONY_LOGE("data is null!!!");
err = HRIL_ERR_INVALID_PARAMETER;
reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
OnCallReport(reportInfo, NULL, 0);
return;
}
pDial = (HRilDial *)data;
switch (pDial->clir) {
case CALL_CLIR_INVOCATION:
clir = "I";
break; /* invocation */
case CALL_CLIR_SUPPRESSION:
clir = "i";
break; /* suppression */
case CALL_CLIR_SUBSCRIPTION_DEFUALT:
default:
clir = "";
break; /* subscription default */
}
(void)sprintf_s(cmd, MAX_BUFF_SIZE, "ATD%s%s;", pDial->address, clir);
ret = SendCommandLock(cmd, NULL, 0, &pResponse); // Send the AT command.
if (ret != 0) {
err = HRIL_ERR_CMD_SEND_FAILURE;
TELEPHONY_LOGE("ATD send failed");
} else {
if (pResponse != NULL && pResponse->success == 0) {
TELEPHONY_LOGE("ReqDial return ERROR");
err = HRIL_ERR_CMD_NO_CARRIER;
}
}
reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
OnCallReport(reportInfo, NULL, 0); // Invoke the callback function of the call service.
FreeResponseInfo(pResponse);
}
```
- **Incoming Call**
The following figure shows the API calling of an incoming call.
**Figure 2** Time sequence of API calling for an incoming call<a name="fig556mcpsimp"></a>
![](figure/en-us_image_0000001214727595.png)
The **g\_reader** thread cyclically reads the messages reported by the modem. When the modem receives an incoming call event, it actively reports the information about the incoming call.
The **g\_reader** thread calls **OnNotifyOps\(\)** to parse the reported information. If the parsed data reported by the modem starts with characters such as **+CRING** or **RING**, it indicates that an incoming call event exists. In this case, the event is reported to RIL Adapter through **OnCallReport\(reportInfo, NULL, 0\)**.
```
// Parse the data reported by the modem as events proactively reported by the corresponding module.
void OnNotifyOps(const char *s, const char *smsPdu)
{
int ret = 0;
struct ReportInfo reportInfo = {0};
reportInfo.error = HRIL_ERR_SUCCESS;
reportInfo.type = HRIL_NOTIFICATION;
if (GetRadioState() == HRIL_RADIO_POWER_STATE_UNAVAILABLE) {
return;
}
TELEPHONY_LOGD("enter to [%{public}s]:%{public}s", s, smsPdu);
// Determine the type of the proactively reported events based on the AT command.
if (ReportStrWith(s, "+CRING:") || ReportStrWith(s, "RING") || ReportStrWith(s, "IRING") ||
ReportStrWith(s, "NO CARRIER") || ReportStrWith(s, "+CCWA") || ReportStrWith(s, "^CCALLSTATE") ||
ReportStrWith(s, "^CEND") || ReportStrWith(s, "^CCWA")) {
reportInfo.notifyId = HNOTI_CALL_STATE_UPDATED;
OnCallReport(reportInfo, NULL, 0); // Invoke the callback function of the call service.
} else if (ReportStrWith(s, "+CMT:")) {
reportInfo.notifyId = HNOTI_SMS_NEW_SMS;
OnSmsReport(reportInfo, (void *)smsPdu, strlen(smsPdu));
}
// add your codes
......
}
```
## Integrating Modem Vendor Libraries<a name="section590mcpsimp"></a>
### Configuring Compilation Information<a name="section592mcpsimp"></a>
Compile the modem vendor library into a dynamic library by using **BUILD.gn**. Upon startup, RIL Adapter loads the dynamic library to the system in dlopen mode and then initializes the library. For details about how to implement vendor library initialization, see [Initializing a Modem Vendor Library](#section211mcpsimp). The following is an example of **BUILD.gn**:
```
import("//build/ohos.gni")
RIL_ADAPTER = "//base/telephony"
ohos_shared_library("ril_vendor") { // Modem vendor library
sources = [ // Source files to compile
"at_call.c",
"at_data.c",
"xxx.c",
]
include_dirs = [ // Header files
"$RIL_ADAPTER/ril_adapter/vendor/include",
"$RIL_ADAPTER/ril_adapter/interfaces/innerkits",
"include",
]
deps = [ // Internal dependencies
"//drivers/adapter/uhdf2/osal:libhdf_utils",
"//base/telephony/core_service/utils:libtelephony_common",
]
external_deps = [ "hilog:libhilog" ] // External dependencies
part_name = "ril_adapter" // Part name
subsystem_name = "telephony" // Subsystem name
}
```
### Debugging and Verification<a name="section620mcpsimp"></a>
1. Compile the code.
2. Check whether **libril\_vendor.z.so** exists in the **/out/{device_name}/telephony/ril\_adapter** directory. If yes, the integration is successful. Otherwise, correct the error and perform debugging and verification again.
# Telephony Overview<a name="EN-US_TOPIC_0000001164469232"></a>
## Introduction<a name="section184mcpsimp"></a>
This document provides development guidelines related to the telephony subsystem, including modem vendor library integration, initialization, service request responding, and modem event reporting. It is intended as a reference for developers of different modem chips, helping them efficiently develop telephony service-related functions.
## Basic Concepts<a name="section187mcpsimp"></a>
- Telephony Service: core service layer of the telephony subsystem. Its main functions are as follows:
- Initializes the RIL Manager module, SIM card module, and network search modules.
- Provides access to the RIL Adapter service, and implements communication with RIL Adapter by registering the callback service.
- Implements communication between modules, such as the call module and SMS module, by subscribing to callbacks.
- RIL Adapter: RIL adaptation layer of the Telephony subsystem. This layer provides functions such as vendor library loading and service API implementation. It shields the differences of modems supplied by different vendors to provide a unified API for the telephony service layer. It communicates with the telephony service layer by registering the Hardware Driver Foundation \(HDF\) service.
- HDF: Hardware Driver Foundation, which allows for unified access from peripheral devices and provides a framework for driver development and management.
- hdc\_std: OpenHarmony Device Connector, a command line tool provided by OpenHarmony for developers to debug device connectivity.
## Working Principles<a name="section194mcpsimp"></a>
**Figure 1** RIL Adapter architecture<a name="fig196mcpsimp"></a>
![](figure/en-us_image_0000001210683929.png)
As shown in the preceding figure, RIL Adapter is logically divided into three layers: **hril\_hdf**, **hril**, and **vendorlib**.
- **hril\_hdf**: unique entry of RIL Adapter. The main function of this layer is to load modem vendor library files. Wherein, **modem\_adapter** enables a single firmware to adapt to different modems.
Specifically, **hril\_hdf** obtains the modem type from the kernel and then loads the target modem vendor library based on the modem type.
- **hril**: OpenHarmony Radio Interface Layer, which provides APIs for communication between the **vendorlib** and various Telephony Service modules, including the SIM card, network search, cellular call, cellular data, and SMS/MMS modules.
- **vendorlib**: Modem vendor library file. Different modem vendor libraries are developed based on standard APIs or service request IDs provided by RIL Adapter. \(**vendorlib** is provided by modem vendors.\)
After **hril\_hdf** is executed, **vendorlib** is dynamically loaded so that it can obtain the pointers to the response processing and event reporting functions from **hril\_hdf**. After this process is complete, **hril\_hdf** can communicate with a modem through **vendorlib**.
## Constraints<a name="section205mcpsimp"></a>
**Specifications**
At least one modem must be supported by a device vendor. If no modem is supported, **vendorlib** APIs do not need to be implemented.
# Subsystems # Telephony
- [Telephony Service](telephony-service.md) - **[Telephony Overview](subsys-tel-overview.md)**
- [Telephony Service](telephony-service.md) - **[Telephony Development](subsys-tel-guide.md)**
- [Development Guidelines](development-guidelines.md)
...@@ -358,10 +358,10 @@ ...@@ -358,10 +358,10 @@
- [Setting Up a Development Environment](subsystems/subsys-application-framework-envbuild.md) - [Setting Up a Development Environment](subsystems/subsys-application-framework-envbuild.md)
- [Development Guidelines](subsystems/subsys-application-framework-guide.md) - [Development Guidelines](subsystems/subsys-application-framework-guide.md)
- [Development Example](subsystems/subsys-application-framework-demo.md) - [Development Example](subsystems/subsys-application-framework-demo.md)
- [OTA Upgrade](subsystems/subsys-ota-guide.md) - [OTA Update](subsystems/subsys-ota-guide.md)
- Telephony Service - Telephony
- [Telephony Service](subsystems/telephony-service.md) - [Telephony Overview](subsystems/subsys-tel-overview.md)
- [Development Guidelines](subsystems/development-guidelines.md) - [Telephony Development](subsystems/subsys-tel-guide.md)
- Security - Security
- [Overview](subsystems/subsys-security-overview.md) - [Overview](subsystems/subsys-security-overview.md)
- [Development Guidelines on Application Signature Verification](subsystems/subsys-security-sigverify.md) - [Development Guidelines on Application Signature Verification](subsystems/subsys-security-sigverify.md)
......
...@@ -8,5 +8,6 @@ This repository stores a complete range of OpenHarmony documentation. The conten ...@@ -8,5 +8,6 @@ This repository stores a complete range of OpenHarmony documentation. The conten
- [Release Notes](release-notes/Readme.md) - [Release Notes](release-notes/Readme.md)
- [Subsystems](./readme) - [Subsystems](./readme)
- OpenHarmony Contribution - OpenHarmony Contribution
- [How to Contribute](contribute/contribution.md) - [How to Contribute](contribute/how-to-contribute.md)
- [OpenHarmony Part and API Design Reference](./design) - [OpenHarmony Part and API Design Reference](./design)
...@@ -21,11 +21,11 @@ ...@@ -21,11 +21,11 @@
- [OpenHarmony 1.1.0 LTS (2021-04-01)](release-notes/OpenHarmony-1-1-0-LTS.md) - [OpenHarmony 1.1.0 LTS (2021-04-01)](release-notes/OpenHarmony-1-1-0-LTS.md)
- [OpenHarmony 1.0 (2020-09-10)](release-notes/OpenHarmony-1-0.md) - [OpenHarmony 1.0 (2020-09-10)](release-notes/OpenHarmony-1-0.md)
- Contribution - Contribution
- [Contribution](contribute/contribution.md) - [How to Contribute](contribute/how-to-contribute.md)
- [Code of Conduct](contribute/code-of-conduct.md) - [Code of Conduct](contribute/code-of-conduct.md)
- [Code Contribution](contribute/code-contribution.md) - [Code Contribution](contribute/code-contribution.md)
- [Contribution Process](contribute/contribution-process.md) - [Contribution Process](contribute/contribution-process.md)
- [Auto-Test](readme/test_subsystem.md) - [Auto-Test](readme/test.md)
- [Documentation Contribution](contribute/documentation-contribution.md) - [Documentation Contribution](contribute/documentation-contribution.md)
- [Writing Instructions](contribute/writing-instructions.md) - [Writing Instructions](contribute/writing-instructions.md)
- [Communication in Community](contribute/communication-in-community.md) - [Communication in Community](contribute/communication-in-community.md)
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
- [编译构建子系统常见问题](faqs-building.md) - [编译构建子系统常见问题](faqs-building.md)
- [烧录常见问题](faqs-burning.md) - [烧录常见问题](faqs-burning.md)
- [内核常见问题](faqs-kernel.md) - [内核常见问题](faqs-kernel.md)
- [移植常见问题](faqs-transplant.md) - [移植常见问题](faqs-porting.md)
- [启动恢复常见问题](faqs-init.md) - [启动恢复常见问题](faqs-startup.md)
- [系统应用常见问题](faqs-system-using.md) - [系统应用常见问题](faqs-system-applications.md)
# 环境搭建常见问题
## 轻量和小型系统
### hb安装过程中出现乱码、段错误
- **现象描述**
执行“python3 -m pip install --user ohos-build”出现乱码、段错误(segmentation fault)。
- **可能原因**
pip版本过低。
- **解决办法**
执行如下命令升级pip。
```
python3 -m pip install -U pip
```
### hb安装过程中提示"cannot import 'sysconfig' from 'distutils'"
- **现象描述**
执行“python3 -m pip install --user ohos-build”提示"cannot import 'sysconfig' from 'distutils'"
- **可能原因**
缺少distutils模块。
- **解决办法**
执行如下命令安装。
```
sudo apt-get install python3.8-distutils
```
### hb安装过程中提示"module 'platform' has no attribute 'linux_distribution'"
- **现象描述**
执行“python3 -m pip install --user ohos-build”提示"module 'platform' has no attribute 'linux_distribution'"
- **可能原因**
python3 pip安装兼容性问题。
- **解决办法**
执行如下命令重新安装pip。
```
sudo apt remove python3-pip
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
```
### hb安装过程中提示"Could not find a version that satisfies the requirement ohos-build"
- **现象描述**
执行“python3 -m pip install --user ohos-build”提示"Could not find a version that satisfies the requirement ohos-build"
- **可能原因**
可能是网络环境较差导致的安装失败。
- **解决办法**
1. 请检查网络连接是否正常。如果网络有问题,请修复网络问题后重新安装。
2. 若网络正常,请尝试指定临时pypi源的方式安装:
```
python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ohos-build
```
### 安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH”
- **现象描述**
安装python3过程中出现以下错误:
```
configure: error: no acceptable C compiler found in $PATH. See 'config.log' for more details
```
- **可能原因**
环境中未安装“gcc”。
- **解决办法**
1. 通过命令“apt-get install gcc”在线安装。
2. 完成后,重新安装python3。
### 安装python3过程中,提示“-bash: make: command not found”
- **现象描述**
安装python3过程中出现以下错误:
```
-bash: make: command not found
```
- **可能原因**
环境中未安装“make”。
- **解决办法**
1. 通过命令“apt-get install make”在线安装。
2. 完成后,重新安装python3。
### 安装python3过程中,提示“zlib not available”
- **现象描述**
安装python3过程中出现以下错误:
```
zipimport.ZipImportError: can't decompress data; zlib not available
```
- **可能原因**
环境中未安装“zlib”。
- **解决办法**
方法1:通过命令“apt-get install zlib”在线安装。
方法2:如果软件源中没有该软件,请从“www.zlib.net”下载版本代码,并离线安装。
![zh-cn_image_0000001198001086](figures/zh-cn_image_0000001198001086.png)
完成下载后,通过以下命令安装:
```
# tar xvf zlib-1.2.11.tar.gz
# cd zlib-1.2.11
# ./configure
# make && make install
```
完成后,重新安装python3。
### 编译构建过程中,提示“No module named 'Crypto'”
- **现象描述**
编译构建过程中出现以下错误:
```
ModuleNotFoundError: No module named 'Crypto'
```
- **可能原因**
环境中未安装“Crypto”。
- **解决办法**
方法1:通过命令“pip3 install Crypto”,在线安装。
方法2:离线安装。
通过网页[https://pypi.org/project/pycrypto/#files](https://pypi.org/project/pycrypto/#files),下载源码。
![zh-cn_image_0000001251196005](figures/zh-cn_image_0000001251196005.png)
将源码放置在Linux服务器中,解压,并安装“python3 setup.py install”。
完成上述安装后,重新构建。
### 安装kconfiglib时,遇到lsb_release错误
- **现象描述**
安装kconfiglib过程中遇到如下错误打印:
```
subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1.
```
- **可能原因**
lsb_release模块基于的python版本与现有python版本不一致。
- **解决办法**
执行"find / -name lsb_release",找到lsb_release位置并删除,如:"sudo rm -rf /usr/bin/lsb_release"。
### Linux编译服务器终端输入不识别的命令时提示“ImportError: No module named apt_pkg”
- **现象描述**
Linux编译服务器终端输入不识别的命令时,提示"ImportError: No module named apt_pkg"
- **可能原因**
python3 apt安装兼容性问题。
- **解决办法**
执行如下命令重新安装python3-apt。
```
sudo apt-get remove python3-apt
sudo apt-get install python3-apt
```
# 环境搭建常见问题<a name="ZH-CN_TOPIC_0000001215650793"></a> # 环境搭建常见问题
## 轻量和小型系统<a name="section1742119306399"></a> ## 轻量和小型系统
### 安装hb过程中,出现乱码、段错误<a name="section36351051193919"></a>
- **现象描述** ### hb安装过程中出现乱码、段错误
- **现象描述**
执行“python3 -m pip install --user ohos-build”出现乱码、段错误(segmentation fault)。 执行“python3 -m pip install --user ohos-build”出现乱码、段错误(segmentation fault)。
- **可能原因** - **可能原因**
pip版本过低。 pip版本过低。
- **解决办法** - **解决办法**
执行如下命令升级pip。 执行如下命令升级pip。
``` ```
python3 -m pip install -U pip python3 -m pip install -U pip
``` ```
### 安装hb过程中,提示"cannot import 'sysconfig' from 'distutils'"<a name="section48221013144011"></a> ### hb安装过程中提示"cannot import 'sysconfig' from 'distutils'"
- **现象描述** - **现象描述**
执行“python3 -m pip install --user ohos-build”提示"cannot import 'sysconfig' from 'distutils'"
执行“python3 -m pip install --user ohos-build”提示"cannot import 'sysconfig' from 'distutils'"。
- **可能原因** - **可能原因**
缺少distutils模块。 缺少distutils模块。
- **解决办法** - **解决办法**
执行如下命令安装。 执行如下命令安装。
``` ```
sudo apt-get install python3.8-distutils sudo apt-get install python3.8-distutils
``` ```
### 安装hb过程中,提示"module 'platform' has no attribute 'linux\_distribution'"<a name="section10307193044111"></a> ### hb安装过程中提示"module 'platform' has no attribute 'linux_distribution'"
- **现象描述** - **现象描述**
执行“python3 -m pip install --user ohos-build”提示"module 'platform' has no attribute 'linux_distribution'"
执行“python3 -m pip install --user ohos-build”提示"module 'platform' has no attribute 'linux\_distribution'"。
- **可能原因** - **可能原因**
python3 pip安装兼容性问题。 python3 pip安装兼容性问题。
- **解决办法** - **解决办法**
执行如下命令重新安装pip。 执行如下命令重新安装pip。
``` ```
sudo apt remove python3-pip sudo apt remove python3-pip
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
...@@ -65,15 +57,12 @@ ...@@ -65,15 +57,12 @@
``` ```
### 安装hb过程中,提示"Could not find a version that satisfies the requirement ohos-build"<a name="section8692735427"></a> ### hb安装过程中提示"Could not find a version that satisfies the requirement ohos-build"
- **现象描述** - **现象描述**
执行“python3 -m pip install --user ohos-build”提示"Could not find a version that satisfies the requirement ohos-build" 执行“python3 -m pip install --user ohos-build”提示"Could not find a version that satisfies the requirement ohos-build"
- **可能原因** - **可能原因**
可能是网络环境较差导致的安装失败。 可能是网络环境较差导致的安装失败。
- **解决办法** - **解决办法**
...@@ -85,73 +74,65 @@ ...@@ -85,73 +74,65 @@
``` ```
### 安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH”
### 安装python3过程中,提示“configure: error: no acceptable C compiler found in $PATH”<a name="section870082884217"></a>
- **现象描述** - **现象描述**
安装python3过程中出现以下错误: 安装python3过程中出现以下错误:
``` ```
configure: error: no acceptable C compiler found in $PATH. See 'config.log' for more details configure: error: no acceptable C compiler found in $PATH. See 'config.log' for more details
``` ```
- **可能原因** - **可能原因**
环境中未安装“gcc”。 环境中未安装“gcc”。
- **解决办法** - **解决办法**
1. 通过命令“apt-get install gcc”在线安装。
2. 完成后,重新安装python3。
1、通过命令“apt-get install gcc”在线安装。
2、完成后,重新安装python3。 ### 安装python3过程中,提示“-bash: make: command not found”
### 安装python3过程中,提示“-bash: make: command not found”<a name="section198707170455"></a>
- **现象描述** - **现象描述**
安装python3过程中出现以下错误: 安装python3过程中出现以下错误:
``` ```
-bash: make: command not found -bash: make: command not found
``` ```
- **可能原因** - **可能原因**
环境中未安装“make”。 环境中未安装“make”。
- **解决办法** - **解决办法**
1. 通过命令“apt-get install make”在线安装。
1、通过命令“apt-get install make”在线安装。 2. 完成后,重新安装python3。
2、完成后,重新安装python3。
### 安装python3过程中,提示“zlib not available”<a name="section85401445204518"></a> ### 安装python3过程中,提示“zlib not available”
- **现象描述** - **现象描述**
安装python3过程中出现以下错误: 安装python3过程中出现以下错误:
``` ```
zipimport.ZipImportError: can't decompress data; zlib not available zipimport.ZipImportError: can't decompress data; zlib not available
``` ```
- **可能原因** - **可能原因**
环境中未安装“zlib”。 环境中未安装“zlib”。
- **解决办法** - **解决办法**
方法1:通过命令“apt-get install zlib”在线安装。 方法1:通过命令“apt-get install zlib”在线安装。
方法2:如果软件源中没有该软件,请从“www.zlib.net”下载版本代码,并离线安装。 方法2:如果软件源中没有该软件,请从“www.zlib.net”下载版本代码,并离线安装。
![](figures/download-zlib.png) ![zh-cn_image_0000001198001086](figures/zh-cn_image_0000001198001086.png)
完成下载后,通过以下命令安装: 完成下载后,通过以下命令安装:
``` ```
# tar xvf zlib-1.2.11.tar.gz # tar xvf zlib-1.2.11.tar.gz
# cd zlib-1.2.11 # cd zlib-1.2.11
...@@ -162,66 +143,63 @@ ...@@ -162,66 +143,63 @@
完成后,重新安装python3。 完成后,重新安装python3。
### 安装python3过程中,提示“No module named '\_ctypes'”<a name="section12202694460"></a> ### 编译构建过程中,提示“No module named 'Crypto'”
- **现象描述** - **现象描述**
编译构建过程中出现以下错误:
安装python3过程中出现以下错误:
``` ```
ModuleNotFoundError:No module named ‘_ctypes’ ModuleNotFoundError: No module named 'Crypto'
``` ```
- **可能原因** - **可能原因**
环境中未安装“Crypto”。
环境中未安装“libffi”和“libffi-devel”。 - **解决办法**
方法1:通过命令“pip3 install Crypto”,在线安装。
方法2:离线安装。
- **解决办法** 通过网页[https://pypi.org/project/pycrypto/#files](https://pypi.org/project/pycrypto/#files),下载源码。
1、通过命令“apt-get install libffi\* -y”,在线安装。 ![zh-cn_image_0000001251196005](figures/zh-cn_image_0000001251196005.png)
2、完成后,重新安装python3 将源码放置在Linux服务器中,解压,并安装“python3 setup.py install”
完成上述安装后,重新构建。
### 安装 kconfiglib时,遇到lsb\_release错误<a name="section5803174135115"></a>
- **现象描述** ### 安装kconfiglib时,遇到lsb_release错误
- **现象描述**
安装kconfiglib过程中遇到如下错误打印: 安装kconfiglib过程中遇到如下错误打印:
``` ```
subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1. subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1.
``` ```
- **可能原因** - **可能原因**
lsb_release模块基于的python版本与现有python版本不一致。
lsb\_release模块基于的python版本与现有python版本不一致
- **解决办法** - **解决办法**
执行"find / -name lsb_release",找到lsb_release位置并删除,如:"sudo rm -rf /usr/bin/lsb_release"。
执行"find / -name lsb\_release",找到lsb\_release位置并删除,如:"sudo rm -rf /usr/bin/lsb\_release"
### Linux编译服务器终端输入不识别的命令时提示“ImportError: No module named apt\_pkg”<a name="section510820516515"></a> ### Linux编译服务器终端输入不识别的命令时提示“ImportError: No module named apt_pkg”
- **现象描述** - **现象描述**
Linux编译服务器终端输入不识别的命令时,提示"ImportError: No module named apt_pkg"
Linux编译服务器终端输入不识别的命令时,提示"ImportError: No module named apt\_pkg"
- **可能原因** - **可能原因**
python3 apt安装兼容性问题。 python3 apt安装兼容性问题。
- **解决办法** - **解决办法**
执行如下命令重新安装python3-apt。 执行如下命令重新安装python3-apt。
``` ```
sudo apt-get remove python3-apt sudo apt-get remove python3-apt
sudo apt-get install python3-apt sudo apt-get install python3-apt
``` ```
# 启动恢复常见问题
## 系统启动过程中打印“parse failed!”错误后停止启动
**现象描述**
系统启动过程中,打印“[Init] InitReadCfg, parse failed! please check file /etc/init.cfg format.”错误,启动过程停止,如下图所示:
**图1** 运行报错图
![zh-cn_image_0000001200053087](figures/zh-cn_image_0000001200053087.png)
**可能原因**
修改init.cfg文件时,漏掉或多加了逗号或括号等,导致init.cfg文件的json格式被破坏。
**解决办法**
仔细检查init.cfg文件,确保其格式符合json格式要求。
## 系统启动过程未结束就自动重启,如此反复持续
**现象描述**
镜像烧写完成后系统启动,启动过程未完成即自动重新启动,如此反复持续。
**可能原因**
被init启动的服务都有一个叫做“importance”的属性(详见[第2章表3](../subsystems/subsys-boot-init.md)描述)。
- 当该属性为0时,表示若当前服务进程退出,init不需要重启单板。
- 当该属性为1时,表示若当前服务进程退出,init需要重启单板。
因此出现上述现象的可能原因:有“importance”属性为1的服务在每次启动的过程中都会退出(可能是进程崩溃或出错自动退出),导致init进程自动重启单板。
**解决办法**
1. 需要通过日志确认崩溃或报错退出的服务,并解决其崩溃/报错的问题,然后重新烧写镜像即可。
2. 也可以将崩溃/报错退出的服务的“importance”属性改为0,然后重新烧写镜像,这样即使其退出,init也不会重启单板。
## 参数正确的情况下调用SetParameter/GetParameter返回失败
**现象描述**
在各参数正确的情况下调用SetParameter/GetParameter返回失败。
**可能原因**
程序对SetParameter/GetParameter这两个接口做了权限校验,在各参数正确的情况下调用SetParameter/GetParameter返回操作失败,很有可能是调用者的uid大于1000,没有调用权限。
**解决办法**
无需处理
# 移植常见问题<a name="ZH-CN_TOPIC_0000001215769367"></a> # 移植常见问题
- [如何将用户的堆内存挂载进内核](#section21471536184914)
## 如何将用户的堆内存挂载进内核<a name="section21471536184914"></a> ## 如何将用户的堆内存挂载进内核
- 内核堆内存配置的相关宏如下,用户可根据实际情况,在target\_config.h中配置: - 内核堆内存配置的相关宏如下,用户可根据实际情况,在target_config.h中配置:
**表 1** 内核堆内存配置相关宏 **表1** 内核堆内存配置相关宏
<a name="zh-cn_topic_0000001153683024_table04172020563"></a> | 宏名称 | 描述 |
<table><thead align="left"><tr id="zh-cn_topic_0000001153683024_row5462035616"><th class="cellrowborder" valign="top" width="39.12%" id="mcps1.2.3.1.1"><p id="zh-cn_topic_0000001153683024_p1456204569"><a name="zh-cn_topic_0000001153683024_p1456204569"></a><a name="zh-cn_topic_0000001153683024_p1456204569"></a>宏名称</p> | -------- | -------- |
</th> | LOSCFG_SYS_EXTERNAL_HEAP | 这个宏决定系统是使用内核的内部堆内存还是用户的堆内存,默认为0(即使用内部的堆内存),大小为0x10000;如果用户需要基于外部的堆内存,那么可以将该宏设置为1。 |
<th class="cellrowborder" valign="top" width="60.88%" id="mcps1.2.3.1.2"><p id="zh-cn_topic_0000001153683024_p19502005618"><a name="zh-cn_topic_0000001153683024_p19502005618"></a><a name="zh-cn_topic_0000001153683024_p19502005618"></a>描述</p> | LOSCFG_SYS_HEAP_ADDR | 内核堆内存的起始地址。 |
</th> | LOSCFG_SYS_HEAP_SIZE | 内核堆内存的大小,即LOSCFG_SYS_HEAP_ADDR指定的内存块大小。 |
</tr>
</thead>
<tbody><tr id="zh-cn_topic_0000001153683024_row14522018560"><td class="cellrowborder" valign="top" width="39.12%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001153683024_p35112025620"><a name="zh-cn_topic_0000001153683024_p35112025620"></a><a name="zh-cn_topic_0000001153683024_p35112025620"></a>LOSCFG_SYS_EXTERNAL_HEAP</p>
</td>
<td class="cellrowborder" valign="top" width="60.88%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001153683024_p5127138175710"><a name="zh-cn_topic_0000001153683024_p5127138175710"></a><a name="zh-cn_topic_0000001153683024_p5127138175710"></a>这个宏决定系统是使用内核的内部堆内存还是用户的堆内存,默认为0(即使用内部的堆内存),大小为0x10000;如果用户需要基于外部的堆内存,那么可以将该宏设置为1。</p>
</td>
</tr>
<tr id="zh-cn_topic_0000001153683024_row20514209567"><td class="cellrowborder" valign="top" width="39.12%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001153683024_p5532017563"><a name="zh-cn_topic_0000001153683024_p5532017563"></a><a name="zh-cn_topic_0000001153683024_p5532017563"></a>LOSCFG_SYS_HEAP_ADDR</p>
</td>
<td class="cellrowborder" valign="top" width="60.88%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001153683024_p65520125619"><a name="zh-cn_topic_0000001153683024_p65520125619"></a><a name="zh-cn_topic_0000001153683024_p65520125619"></a>内核堆内存的起始地址。</p>
</td>
</tr>
<tr id="zh-cn_topic_0000001153683024_row15302929115615"><td class="cellrowborder" valign="top" width="39.12%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001153683024_p113021529145612"><a name="zh-cn_topic_0000001153683024_p113021529145612"></a><a name="zh-cn_topic_0000001153683024_p113021529145612"></a>LOSCFG_SYS_HEAP_SIZE</p>
</td>
<td class="cellrowborder" valign="top" width="60.88%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001153683024_p1030252965619"><a name="zh-cn_topic_0000001153683024_p1030252965619"></a><a name="zh-cn_topic_0000001153683024_p1030252965619"></a>内核堆内存的大小,即LOSCFG_SYS_HEAP_ADDR指定的内存块大小。</p>
</td>
</tr>
</tbody>
</table>
- 注意事项: - 注意事项:
指定的堆内存范围务必保证没有其他模块使用,避免踩内存,破坏堆内存功能。 指定的堆内存范围务必保证没有其他模块使用,避免踩内存,破坏堆内存功能。
# 启动恢复常见问题<a name="ZH-CN_TOPIC_0000001215449321"></a> # 启动恢复常见问题
- [系统启动过程中打印“parse failed!”错误后停止启动](#section835662214302)
- [系统启动过程未结束就自动重启,如此反复持续](#section3857921143117)
- [参数正确的情况下调用SetParameter/GetParameter返回失败](#section548818116328)
## 系统启动过程中打印“parse failed!”错误后停止启动<a name="section835662214302"></a> ## 系统启动过程中打印“parse failed!”错误后停止启动
**现象描述** **现象描述**
系统启动过程中,打印“\[Init\] InitReadCfg, parse failed! please check file /etc/init.cfg format.”错误,启动过程停止,如下图所示: 系统启动过程中,打印“[Init] InitReadCfg, parse failed! please check file /etc/init.cfg format.”错误,启动过程停止,如下图所示:
**图 1** 运行报错图<a name="zh-cn_topic_0000001063231870_fig15217111545118"></a> **图1** 运行报错图
![](figures/运行报错图.png "运行报错图")
![zh-cn_image_0000001200053087](figures/zh-cn_image_0000001200053087.png)
**可能原因** **可能原因**
...@@ -21,7 +19,8 @@ ...@@ -21,7 +19,8 @@
仔细检查init.cfg文件,确保其格式符合json格式要求。 仔细检查init.cfg文件,确保其格式符合json格式要求。
## 系统启动过程未结束就自动重启,如此反复持续<a name="section3857921143117"></a>
## 系统启动过程未结束就自动重启,如此反复持续
**现象描述** **现象描述**
...@@ -32,6 +31,7 @@ ...@@ -32,6 +31,7 @@
被init启动的服务都有一个叫做“importance”的属性(详见[第2章表3](../subsystems/subsys-boot-init.md)描述)。 被init启动的服务都有一个叫做“importance”的属性(详见[第2章表3](../subsystems/subsys-boot-init.md)描述)。
- 当该属性为0时,表示若当前服务进程退出,init不需要重启单板。 - 当该属性为0时,表示若当前服务进程退出,init不需要重启单板。
- 当该属性为1时,表示若当前服务进程退出,init需要重启单板。 - 当该属性为1时,表示若当前服务进程退出,init需要重启单板。
因此出现上述现象的可能原因:有“importance”属性为1的服务在每次启动的过程中都会退出(可能是进程崩溃或出错自动退出),导致init进程自动重启单板。 因此出现上述现象的可能原因:有“importance”属性为1的服务在每次启动的过程中都会退出(可能是进程崩溃或出错自动退出),导致init进程自动重启单板。
...@@ -39,9 +39,11 @@ ...@@ -39,9 +39,11 @@
**解决办法** **解决办法**
1. 需要通过日志确认崩溃或报错退出的服务,并解决其崩溃/报错的问题,然后重新烧写镜像即可。 1. 需要通过日志确认崩溃或报错退出的服务,并解决其崩溃/报错的问题,然后重新烧写镜像即可。
2. 也可以将崩溃/报错退出的服务的“importance”属性改为0,然后重新烧写镜像,这样即使其退出,init也不会重启单板。 2. 也可以将崩溃/报错退出的服务的“importance”属性改为0,然后重新烧写镜像,这样即使其退出,init也不会重启单板。
## 参数正确的情况下调用SetParameter/GetParameter返回失败<a name="section548818116328"></a>
## 参数正确的情况下调用SetParameter/GetParameter返回失败
**现象描述** **现象描述**
...@@ -54,4 +56,3 @@ ...@@ -54,4 +56,3 @@
**解决办法** **解决办法**
无需处理 无需处理
# 系统应用常见问题<a name="ZH-CN_TOPIC_0000001169690992"></a>
- [公共基础库常见问题](#section639433461512)
- [1.LiteOS-A内核\(Hi3516、Hi3518平台\)KV存储路径设置错误,导致KV存储运行失败](#section16520347131511)
- [视觉应用常见问题](#section787718474161)
- [是否存在一个全局变量,所有的页面都可以访问?](#section187297991718)
- [如何获取dom中的元素](#section1833493719175)
- [如何在页面间传值?](#section184283812183)
- [list如何滚动到某个item?](#section11897734131811)
- [text支持多行吗?](#section5872656121814)
- [为什么控件不显示?](#section7397125317107)
- [如何实现页面滑动?](#section338794422010)
- [Left、Top为什么不生效?](#section2597193611217)
- [动态绑定为什么不生效?](#section6939050172115)
- [如何实现相对定位和绝对定位?](#section5547311192215)
- [如何控制控件的显示与隐藏?](#section16107113352213)
- [使用Margin时,有什么注意事项?](#section1524910142314)
- [使用事件订阅时,有什么注意事项?](#section1537132012231)
- [使用动态绑定时,有什么注意事项?](#section96561452236)
- [swiper loop属性如何生效?](#section690166112414)
- [使用数组时,有什么注意事项?](#section1554552822414)
- [hdc类问题](#section412357182518)
- [hdc\_std连接不到设备](#section1965012223257)
- [hdc\_std运行不了](#section1157575212515)
## 公共基础库常见问题<a name="section639433461512"></a>
### 1.LiteOS-A内核\(Hi3516、Hi3518平台\)KV存储路径设置错误,导致KV存储运行失败<a name="section16520347131511"></a>
**现象描述**
LiteOS-A内核\(Hi3516、Hi3518平台\)直接调用KV存储提供的接口,各参数正常的情况下,编译可执行程序运行失败。
**可能原因**
直接运行编译出的可执行文件,没有将程序基于AbilityKit转换成应用,不能由BMS在应用安装时正确设置应用数据存储路径,导致KV存储运行失败。
**解决办法**
显示调用KV存储的UtilsSetEnv接口,设置数据存储路径。
```
UtilsSetEnv("/storage/com.example.kv");
```
## 视觉应用常见问题<a name="section787718474161"></a>
### 是否存在一个全局变量,所有的页面都可以访问?<a name="section187297991718"></a>
当前框架中不存在所有Page都可以访问的全局变量。
### 如何获取dom中的元素<a name="section1833493719175"></a>
如何获取dom中的元素?
通过ref属性获取dom中的元素,详细示例如下图所示;获取的元素只能使用它的方法,不能改变属性。
```
<!--index.hml-->
<div class="container">
<!--指定组件的ref属性为animator-->
<image-animator class="image-player" ref="ainmator" images="{{images}}" duration="1s" onclick="handleClick"></image-animator>
</div>
/* index.js */
export default {
data: {
images:[
{src:"common/frame1.png"},
{src:"common/frame2.png"},
{src:"common/frame3.png"}
]
},
handleClick(){
//通过$refs属性获取对应的组件,在hml中,组件的ref属性要设置为animator
const animator = this.$refs.animator;
const state = animator.getState();
if(state == "paused"){
animator.resume();
}else if(state == "stopped"){
animator.start();
}else{
animator.pause();
}
}
}
```
### 如何在页面间传值?<a name="section184283812183"></a>
通过router.replace方法中的params参数来传递,参考代码如下:
第一个页面传递数据:
```
router.replace({
uri:'pages/detail/detail', //要跳转的页面uri
params:{transferData:this.data} //传递的数据,数据个数和名称开发者自己定义,
});
```
第二个界面接受数据:
```
onInit(){
const data = this.transferData; //在onInit函数中接受传递的数据
}
```
### list如何滚动到某个item?<a name="section11897734131811"></a>
通过list的scrollTo方法滚动到指定的item,参数是目标item的index。Index参数可以通过scrollend事件获取或者开发者指定。
### text支持多行吗?<a name="section5872656121814"></a>
text支持多行。通过回车键换行或者是不设置text的高度属性,由控件自动根据内容换行。
### 为什么控件不显示?<a name="section7397125317107"></a>
**现象描述**
开发者在hml文件中添加的控件无法显示
**可能原因**
- 未设置width和height值;
- 样式设置错误。
**处理步骤**
\(1\)检查是否设置width和height值,组件必须显式设置width和height值;
\(2\)检查组件的样式设置是否正确。
### 如何实现页面滑动?<a name="section338794422010"></a>
实现页面滑动目前有三种方式:scroll(根组件大小超过屏幕的大小即自动实现scroll效果)、list、swiper。开发者可以参考开发文档查看三者的区别,并加以使用。
### Left、Top为什么不生效?<a name="section2597193611217"></a>
除根节点外,Left、Top配合Stack组件使用才有效果。
### 动态绑定为什么不生效?<a name="section6939050172115"></a>
在进行绑定时,必须先将要绑定的对象或者对象的属性进行定义,不能先绑定后定义
### 如何实现相对定位和绝对定位?<a name="section5547311192215"></a>
使用div、stack(top left属性)来实现相对和绝对定位。
### 如何控制控件的显示与隐藏?<a name="section16107113352213"></a>
通过display、show和if来控制控件的显示与隐藏。区别在于:if为false时,组件会从VDOM中移除,而show仅是渲染时不可见,组件依然存在于VDOM中。
### 使用Margin时,有什么注意事项?<a name="section1524910142314"></a>
Stack组件不支持其子组件设置margin属性。
### 使用事件订阅时,有什么注意事项?<a name="section1537132012231"></a>
在应用运行期间只存在一个page,所以router.replace跳转是先销毁前一个页面,然后在新创建一个界面。因此,如果涉及到事件订阅的页面,每次页面创建时要进行事件订阅,跳转离开界面前取消事件订阅。
### 使用动态绑定时,有什么注意事项?<a name="section96561452236"></a>
过多的动态绑定会消耗较多的内存,若非业务需要,尽量不要使用太多的动态绑定。
### swiper loop属性如何生效?<a name="section690166112414"></a>
去掉第一个组件或者去掉最后一个组件,剩余的长度大于swiper长度,loop生效。
### 使用数组时,有什么注意事项?<a name="section1554552822414"></a>
数组元素不宜过多,尽量避免对大数组进行频繁操作。
## hdc类问题<a name="section412357182518"></a>
### hdc\_std连接不到设备<a name="section1965012223257"></a>
- **现象描述**
执行 "hdc\_std list targets"命令后结果为:\[Empty\]
- **解决方法**
1. 设备没有被识别:
在设备管理器中查看是否有hdc设备,在通用串行总线设备中会有“HDC Device”信息。如果没有,hdc无法连接。此时需要插拔设备,或者烧写最新的镜像。
2. hdc\_std工作异常:
可以执行"hdc kill"或者"hdc start -r"杀掉hdc服务或者重启hdc服务,然后再执行hdc list targets查看是否已经可以获取设备信息。
3. hdc\_std与设备不匹配:
如果设备烧写的是最新镜像,hdc\_std也需要使用最新版本。由于hdc\_std会持续更新,请从开源仓developtools\_hdc\_standard中获取,具体位置在该开源仓的prebuilt目录。
### hdc\_std运行不了<a name="section1157575212515"></a>
- **现象描述**
点击hdc\_std.exe文件无法运行。
- **解决方法**
hdc\_std.exe不需要安装,直接放到磁盘上就能使用,也可以添加到环境变量中。通过打开cmd执行hdc\_std命令直接使用。
# 移植常见问题
## 如何将用户的堆内存挂载进内核
- 内核堆内存配置的相关宏如下,用户可根据实际情况,在target_config.h中配置:
**表1** 内核堆内存配置相关宏
| 宏名称 | 描述 |
| -------- | -------- |
| LOSCFG_SYS_EXTERNAL_HEAP | 这个宏决定系统是使用内核的内部堆内存还是用户的堆内存,默认为0(即使用内部的堆内存),大小为0x10000;如果用户需要基于外部的堆内存,那么可以将该宏设置为1。 |
| LOSCFG_SYS_HEAP_ADDR | 内核堆内存的起始地址。 |
| LOSCFG_SYS_HEAP_SIZE | 内核堆内存的大小,即LOSCFG_SYS_HEAP_ADDR指定的内存块大小。 |
- 注意事项:
指定的堆内存范围务必保证没有其他模块使用,避免踩内存,破坏堆内存功能。
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
- [烧录](quickstart-ide-lite-steps-hi3861-burn.md) - [烧录](quickstart-ide-lite-steps-hi3861-burn.md)
- [联网](quickstart-ide-lite-steps-hi3861-netconfig.md) - [联网](quickstart-ide-lite-steps-hi3861-netconfig.md)
- [调试验证](quickstart-ide-lite-steps-hi3861-debug.md) - [调试验证](quickstart-ide-lite-steps-hi3861-debug.md)
- [运行](quickstart-ide-lite-steps-hi3816-running.md) - [运行](quickstart-ide-lite-steps-hi3861-running.md)
- Hi3516开发板 - Hi3516开发板
- [编写“Hello World”程序](quickstart-ide-lite-steps-hi3516-application-framework.md) - [编写“Hello World”程序](quickstart-ide-lite-steps-hi3516-application-framework.md)
- [编译](quickstart-ide-lite-steps-hi3516-building.md) - [编译](quickstart-ide-lite-steps-hi3516-building.md)
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
- [烧录](quick-start/quickstart-ide-lite-steps-hi3861-burn.md) - [烧录](quick-start/quickstart-ide-lite-steps-hi3861-burn.md)
- [联网](quick-start/quickstart-ide-lite-steps-hi3861-netconfig.md) - [联网](quick-start/quickstart-ide-lite-steps-hi3861-netconfig.md)
- [调试验证](quick-start/quickstart-ide-lite-steps-hi3861-debug.md) - [调试验证](quick-start/quickstart-ide-lite-steps-hi3861-debug.md)
- [运行](quick-start/quickstart-ide-lite-steps-hi3816-running.md) - [运行](quick-start/quickstart-ide-lite-steps-hi3861-running.md)
- Hi3516开发板 - Hi3516开发板
- [编写“Hello World”程序](quick-start/quickstart-ide-lite-steps-hi3516-application-framework.md) - [编写“Hello World”程序](quick-start/quickstart-ide-lite-steps-hi3516-application-framework.md)
- [编译](quick-start/quickstart-ide-lite-steps-hi3516-building.md) - [编译](quick-start/quickstart-ide-lite-steps-hi3516-building.md)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册